1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_SF_HWCOMPOSER_H 18 #define ANDROID_SF_HWCOMPOSER_H 19 20 #include <cstdint> 21 #include <future> 22 #include <memory> 23 #include <mutex> 24 #include <optional> 25 #include <unordered_map> 26 #include <unordered_set> 27 #include <vector> 28 29 #include <android-base/thread_annotations.h> 30 #include <ui/FenceTime.h> 31 32 // TODO(b/129481165): remove the #pragma below and fix conversion issues 33 #pragma clang diagnostic push 34 #pragma clang diagnostic ignored "-Wconversion" 35 #pragma clang diagnostic ignored "-Wextra" 36 #include <ui/GraphicTypes.h> 37 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra" 38 39 #include <utils/StrongPointer.h> 40 #include <utils/Timers.h> 41 42 #include "DisplayIdentification.h" 43 #include "DisplayMode.h" 44 #include "HWC2.h" 45 #include "Hal.h" 46 47 namespace android { 48 49 namespace hal = hardware::graphics::composer::hal; 50 51 struct DisplayedFrameStats; 52 class GraphicBuffer; 53 class TestableSurfaceFlinger; 54 struct CompositionInfo; 55 56 namespace Hwc2 { 57 class Composer; 58 } // namespace Hwc2 59 60 namespace compositionengine { 61 class Output; 62 } // namespace compositionengine 63 64 struct KnownHWCGenericLayerMetadata { 65 const char* name; 66 const uint32_t id; 67 }; 68 69 // See the comment for SurfaceFlinger::getHwComposer for the thread safety rules for accessing 70 // this class. 71 class HWComposer { 72 public: 73 struct DeviceRequestedChanges { 74 using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>; 75 using ClientTargetProperty = hal::ClientTargetProperty; 76 using DisplayRequests = hal::DisplayRequest; 77 using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>; 78 79 ChangedTypes changedTypes; 80 DisplayRequests displayRequests; 81 LayerRequests layerRequests; 82 ClientTargetProperty clientTargetProperty; 83 }; 84 85 struct HWCDisplayMode { 86 hal::HWConfigId hwcId; 87 int32_t width = -1; 88 int32_t height = -1; 89 nsecs_t vsyncPeriod = -1; 90 int32_t dpiX = -1; 91 int32_t dpiY = -1; 92 int32_t configGroup = -1; 93 94 friend std::ostream& operator<<(std::ostream& os, const HWCDisplayMode& mode) { 95 return os << "id=" << mode.hwcId << " res=" << mode.width << "x" << mode.height 96 << " vsyncPeriod=" << mode.vsyncPeriod << " dpi=" << mode.dpiX << "x" 97 << mode.dpiY << " group=" << mode.configGroup; 98 } 99 }; 100 101 virtual ~HWComposer(); 102 103 virtual void setCallback(HWC2::ComposerCallback*) = 0; 104 105 virtual bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort, 106 DisplayIdentificationData* outData) const = 0; 107 108 virtual bool hasCapability(hal::Capability) const = 0; 109 virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0; 110 111 virtual size_t getMaxVirtualDisplayCount() const = 0; 112 virtual size_t getMaxVirtualDisplayDimension() const = 0; 113 114 // Attempts to allocate a virtual display on the HWC. The maximum number of virtual displays 115 // supported by the HWC can be queried in advance, but allocation may fail for other reasons. 116 // For virtualized compositors, the PhysicalDisplayId is a hint that this virtual display is 117 // a mirror of a physical display, and that the screen should be captured by the host rather 118 // than guest compositor. 119 virtual bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*, 120 std::optional<PhysicalDisplayId> mirror) = 0; 121 122 virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0; 123 124 // Attempts to create a new layer on this display 125 virtual std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) = 0; 126 127 // Gets any required composition change requests from the HWC device. 128 // 129 // Note that frameUsesClientComposition must be set correctly based on 130 // whether the current frame appears to use client composition. If it is 131 // false some internal optimizations are allowed to present the display 132 // with fewer handshakes, but this does not work if client composition is 133 // expected. 134 virtual status_t getDeviceCompositionChanges( 135 HalDisplayId, bool frameUsesClientComposition, 136 std::chrono::steady_clock::time_point earliestPresentTime, 137 const std::shared_ptr<FenceTime>& previousPresentFence, 138 std::optional<DeviceRequestedChanges>* outChanges) = 0; 139 140 virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, 141 const sp<GraphicBuffer>& target, ui::Dataspace) = 0; 142 143 // Present layers to the display and read releaseFences. 144 virtual status_t presentAndGetReleaseFences( 145 HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime, 146 const std::shared_ptr<FenceTime>& previousPresentFence) = 0; 147 148 // set power mode 149 virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0; 150 151 // Sets a color transform to be applied to the result of composition 152 virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0; 153 154 // reset state when a display is disconnected 155 virtual void disconnectDisplay(HalDisplayId) = 0; 156 157 // get the present fence received from the last call to present. 158 virtual sp<Fence> getPresentFence(HalDisplayId) const = 0; 159 160 // Get last release fence for the given layer 161 virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0; 162 163 // Set the output buffer and acquire fence for a virtual display. 164 virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence, 165 const sp<GraphicBuffer>& buffer) = 0; 166 167 // After SurfaceFlinger has retrieved the release fences for all the frames, 168 // it can call this to clear the shared pointers in the release fence map 169 virtual void clearReleaseFences(HalDisplayId) = 0; 170 171 // Fetches the HDR capabilities of the given display 172 virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0; 173 174 virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0; 175 176 // Returns the available RenderIntent of the given display. 177 virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0; 178 179 virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0; 180 181 // Returns the attributes of the color sampling engine. 182 virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat, 183 ui::Dataspace* outDataspace, 184 uint8_t* outComponentMask) = 0; 185 virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, 186 uint8_t componentMask, 187 uint64_t maxFrames) = 0; 188 virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp, 189 DisplayedFrameStats* outStats) = 0; 190 191 // Sets the brightness of a display. 192 virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0; 193 194 // Events handling --------------------------------------------------------- 195 196 // Returns stable display ID (and display name on connection of new or previously disconnected 197 // display), or std::nullopt if hotplug event was ignored. 198 // This function is called from SurfaceFlinger. 199 virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, 200 hal::Connection) = 0; 201 202 // If true we'll update the DeviceProductInfo on subsequent hotplug connected events. 203 // TODO(b/157555476): Remove when the framework has proper support for headless mode 204 virtual bool updatesDeviceProductInfoOnHotplugReconnect() const = 0; 205 206 virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0; 207 virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0; 208 209 virtual bool isConnected(PhysicalDisplayId) const = 0; 210 211 virtual std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const = 0; 212 213 virtual std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const = 0; 214 215 virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0; 216 217 virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode, 218 ui::RenderIntent) = 0; 219 220 // Composer 2.4 221 virtual ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0; 222 virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0; 223 virtual status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId, 224 nsecs_t* outVsyncPeriod) const = 0; 225 virtual status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId, 226 const hal::VsyncPeriodChangeConstraints&, 227 hal::VsyncPeriodChangeTimeline* outTimeline) = 0; 228 virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0; 229 virtual status_t getSupportedContentTypes( 230 PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0; 231 virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0; 232 virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() 233 const = 0; 234 235 // for debugging ---------------------------------------------------------- 236 virtual void dump(std::string& out) const = 0; 237 238 virtual Hwc2::Composer* getComposer() const = 0; 239 240 // TODO(b/74619554): Remove special cases for internal/external display. 241 virtual std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const = 0; 242 virtual std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const = 0; 243 244 virtual std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const = 0; 245 virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const = 0; 246 }; 247 248 namespace impl { 249 250 class HWComposer final : public android::HWComposer { 251 public: 252 explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer); 253 explicit HWComposer(const std::string& composerServiceName); 254 255 ~HWComposer() override; 256 257 void setCallback(HWC2::ComposerCallback*) override; 258 259 bool getDisplayIdentificationData(hal::HWDisplayId, uint8_t* outPort, 260 DisplayIdentificationData* outData) const override; 261 262 bool hasCapability(hal::Capability) const override; 263 bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override; 264 265 size_t getMaxVirtualDisplayCount() const override; 266 size_t getMaxVirtualDisplayDimension() const override; 267 268 bool allocateVirtualDisplay(HalVirtualDisplayId, ui::Size, ui::PixelFormat*, 269 std::optional<PhysicalDisplayId>) override; 270 271 // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated. 272 void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override; 273 274 // Attempts to create a new layer on this display 275 std::shared_ptr<HWC2::Layer> createLayer(HalDisplayId) override; 276 277 status_t getDeviceCompositionChanges( 278 HalDisplayId, bool frameUsesClientComposition, 279 std::chrono::steady_clock::time_point earliestPresentTime, 280 const std::shared_ptr<FenceTime>& previousPresentFence, 281 std::optional<DeviceRequestedChanges>* outChanges) override; 282 283 status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence, 284 const sp<GraphicBuffer>& target, ui::Dataspace) override; 285 286 // Present layers to the display and read releaseFences. 287 status_t presentAndGetReleaseFences( 288 HalDisplayId, std::chrono::steady_clock::time_point earliestPresentTime, 289 const std::shared_ptr<FenceTime>& previousPresentFence) override; 290 291 // set power mode 292 status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override; 293 294 // Sets a color transform to be applied to the result of composition 295 status_t setColorTransform(HalDisplayId, const mat4& transform) override; 296 297 // reset state when a display is disconnected 298 void disconnectDisplay(HalDisplayId) override; 299 300 // get the present fence received from the last call to present. 301 sp<Fence> getPresentFence(HalDisplayId) const override; 302 303 // Get last release fence for the given layer 304 sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override; 305 306 // Set the output buffer and acquire fence for a virtual display. 307 status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence, 308 const sp<GraphicBuffer>& buffer) override; 309 310 // After SurfaceFlinger has retrieved the release fences for all the frames, 311 // it can call this to clear the shared pointers in the release fence map 312 void clearReleaseFences(HalDisplayId) override; 313 314 // Fetches the HDR capabilities of the given display 315 status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override; 316 317 int32_t getSupportedPerFrameMetadata(HalDisplayId) const override; 318 319 // Returns the available RenderIntent of the given display. 320 std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override; 321 322 mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override; 323 324 // Returns the attributes of the color sampling engine. 325 status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat, 326 ui::Dataspace* outDataspace, 327 uint8_t* outComponentMask) override; 328 status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask, 329 uint64_t maxFrames) override; 330 status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp, 331 DisplayedFrameStats* outStats) override; 332 std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override; 333 334 // Events handling --------------------------------------------------------- 335 336 // Returns PhysicalDisplayId (and display name on connection of new or previously disconnected 337 // display), or std::nullopt if hotplug event was ignored. 338 std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override; 339 340 bool updatesDeviceProductInfoOnHotplugReconnect() const override; 341 342 bool onVsync(hal::HWDisplayId, int64_t timestamp) override; 343 void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override; 344 345 bool isConnected(PhysicalDisplayId) const override; 346 347 std::vector<HWCDisplayMode> getModes(PhysicalDisplayId) const override; 348 349 std::optional<hal::HWConfigId> getActiveMode(PhysicalDisplayId) const override; 350 351 std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override; 352 353 status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override; 354 355 // Composer 2.4 356 ui::DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override; 357 bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override; 358 status_t getDisplayVsyncPeriod(PhysicalDisplayId displayId, 359 nsecs_t* outVsyncPeriod) const override; 360 status_t setActiveModeWithConstraints(PhysicalDisplayId, hal::HWConfigId, 361 const hal::VsyncPeriodChangeConstraints&, 362 hal::VsyncPeriodChangeTimeline* outTimeline) override; 363 status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override; 364 status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override; 365 status_t setContentType(PhysicalDisplayId, hal::ContentType) override; 366 367 const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override; 368 369 // for debugging ---------------------------------------------------------- 370 void dump(std::string& out) const override; 371 getComposer()372 Hwc2::Composer* getComposer() const override { return mComposer.get(); } 373 374 // TODO(b/74619554): Remove special cases for internal/external display. getInternalHwcDisplayId()375 std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const override { 376 return mInternalHwcDisplayId; 377 } getExternalHwcDisplayId()378 std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const override { 379 return mExternalHwcDisplayId; 380 } 381 382 std::optional<PhysicalDisplayId> toPhysicalDisplayId(hal::HWDisplayId) const override; 383 std::optional<hal::HWDisplayId> fromPhysicalDisplayId(PhysicalDisplayId) const override; 384 385 private: 386 // For unit tests 387 friend TestableSurfaceFlinger; 388 389 struct DisplayData { 390 bool isVirtual = false; 391 std::unique_ptr<HWC2::Display> hwcDisplay; 392 sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires 393 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 394 buffer_handle_t outbufHandle = nullptr; 395 sp<Fence> outbufAcquireFence = Fence::NO_FENCE; 396 397 bool validateWasSkipped; 398 hal::Error presentError; 399 400 bool vsyncTraceToggle = false; 401 402 std::mutex vsyncEnabledLock; 403 hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE; 404 405 nsecs_t lastHwVsync = 0; 406 }; 407 408 std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId); 409 std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId); 410 bool shouldIgnoreHotplugConnect(hal::HWDisplayId, bool hasDisplayIdentificationData) const; 411 412 int32_t getAttribute(hal::HWDisplayId hwcDisplayId, hal::HWConfigId configId, 413 hal::Attribute attribute) const; 414 415 void loadCapabilities(); 416 void loadLayerMetadataSupport(); 417 418 std::unordered_map<HalDisplayId, DisplayData> mDisplayData; 419 420 std::unique_ptr<android::Hwc2::Composer> mComposer; 421 std::unordered_set<hal::Capability> mCapabilities; 422 std::unordered_map<std::string, bool> mSupportedLayerGenericMetadata; 423 bool mRegisteredCallback = false; 424 425 std::unordered_map<hal::HWDisplayId, PhysicalDisplayId> mPhysicalDisplayIdMap; 426 std::optional<hal::HWDisplayId> mInternalHwcDisplayId; 427 std::optional<hal::HWDisplayId> mExternalHwcDisplayId; 428 bool mHasMultiDisplaySupport = false; 429 430 const size_t mMaxVirtualDisplayDimension; 431 const bool mUpdateDeviceProductInfoOnHotplugReconnect; 432 }; 433 434 } // namespace impl 435 } // namespace android 436 437 #endif // ANDROID_SF_HWCOMPOSER_H 438