/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Display/DisplayModeRequest.h" #include "DisplayHardware/DisplayMode.h" #include "DisplayHardware/Hal.h" #include "DisplayHardware/PowerAdvisor.h" #include "FrontEnd/DisplayInfo.h" #include "Scheduler/RefreshRateSelector.h" #include "ThreadContext.h" #include "TracedOrdinal.h" #include "Utils/Dumper.h" namespace android { class Fence; class HWComposer; class IGraphicBufferProducer; class Layer; class RefreshRateOverlay; class SurfaceFlinger; struct CompositionInfo; struct DisplayDeviceCreationArgs; namespace compositionengine { class Display; class DisplaySurface; } // namespace compositionengine namespace display { class DisplaySnapshot; } // namespace display class DisplayDevice : public RefBase { public: constexpr static float sDefaultMinLumiance = 0.0; constexpr static float sDefaultMaxLumiance = 500.0; enum { eReceivesInput = 0x01 }; explicit DisplayDevice(DisplayDeviceCreationArgs& args); // Must be destroyed on the main thread because it may call into HWComposer. virtual ~DisplayDevice(); std::shared_ptr getCompositionDisplay() const { return mCompositionDisplay; } bool isVirtual() const { return VirtualDisplayId::tryCast(getId()).has_value(); } bool isPrimary() const { return mIsPrimary; } // isSecure indicates whether this display can be trusted to display // secure surfaces. bool isSecure() const; int getWidth() const; int getHeight() const; ui::Size getSize() const { return {getWidth(), getHeight()}; } void setLayerFilter(ui::LayerFilter); void setDisplaySize(int width, int height); void setProjection(ui::Rotation orientation, Rect viewport, Rect frame); void stageBrightness(float brightness) REQUIRES(kMainThreadContext); void persistBrightness(bool needsComposite) REQUIRES(kMainThreadContext); bool isBrightnessStale() const REQUIRES(kMainThreadContext); void setFlags(uint32_t flags); ui::Rotation getPhysicalOrientation() const { return mPhysicalOrientation; } ui::Rotation getOrientation() const { return mOrientation; } std::optional getStagedBrightness() const REQUIRES(kMainThreadContext); ui::Transform::RotationFlags getTransformHint() const; const ui::Transform& getTransform() const; const Rect& getLayerStackSpaceRect() const; const Rect& getOrientedDisplaySpaceRect() const; ui::LayerStack getLayerStack() const; bool receivesInput() const { return mFlags & eReceivesInput; } DisplayId getId() const; // Shorthand to upcast the ID of a display whose type is known as a precondition. PhysicalDisplayId getPhysicalId() const { const auto id = PhysicalDisplayId::tryCast(getId()); LOG_FATAL_IF(!id); return *id; } VirtualDisplayId getVirtualId() const { const auto id = VirtualDisplayId::tryCast(getId()); LOG_FATAL_IF(!id); return *id; } const wp& getDisplayToken() const { return mDisplayToken; } int32_t getSequenceId() const { return mSequenceId; } const Region& getUndefinedRegion() const; int32_t getSupportedPerFrameMetadata() const; bool hasWideColorGamut() const; // Whether h/w composer has native support for specific HDR type. bool hasHDR10PlusSupport() const; bool hasHDR10Support() const; bool hasHLGSupport() const; bool hasDolbyVisionSupport() const; void overrideHdrTypes(const std::vector& hdrTypes); // The returned HdrCapabilities is the combination of HDR capabilities from // hardware composer and RenderEngine. When the DisplayDevice supports wide // color gamut, RenderEngine is able to simulate HDR support in Display P3 // color space for both PQ and HLG HDR contents. The minimum and maximum // luminance will be set to sDefaultMinLumiance and sDefaultMaxLumiance // respectively if hardware composer doesn't return meaningful values. HdrCapabilities getHdrCapabilities() const; // Return true if intent is supported by the display. bool hasRenderIntent(ui::RenderIntent intent) const; const Rect getBounds() const; const Rect bounds() const { return getBounds(); } void setDisplayName(const std::string& displayName); const std::string& getDisplayName() const { return mDisplayName; } surfaceflinger::frontend::DisplayInfo getFrontEndInfo() const; /* ------------------------------------------------------------------------ * Display power mode management. */ std::optional getPowerMode() const; void setPowerMode(hardware::graphics::composer::hal::PowerMode mode); bool isPoweredOn() const; void tracePowerMode(); // Enables layer caching on this DisplayDevice void enableLayerCaching(bool enable); ui::Dataspace getCompositionDataSpace() const; /* ------------------------------------------------------------------------ * Display mode management. */ // TODO(b/241285876): Replace ActiveModeInfo and DisplayModeEvent with DisplayModeRequest. struct ActiveModeInfo { using Event = scheduler::DisplayModeEvent; ActiveModeInfo() = default; ActiveModeInfo(scheduler::FrameRateMode mode, Event event) : modeOpt(std::move(mode)), event(event) {} explicit ActiveModeInfo(display::DisplayModeRequest&& request) : ActiveModeInfo(std::move(request.mode), request.emitEvent ? Event::Changed : Event::None) {} ftl::Optional modeOpt; Event event = Event::None; bool operator!=(const ActiveModeInfo& other) const { return modeOpt != other.modeOpt || event != other.event; } }; enum class DesiredActiveModeAction { None, InitiateDisplayModeSwitch, InitiateRenderRateSwitch }; DesiredActiveModeAction setDesiredActiveMode(const ActiveModeInfo&, bool force = false) EXCLUDES(mActiveModeLock); std::optional getDesiredActiveMode() const EXCLUDES(mActiveModeLock); void clearDesiredActiveModeState() EXCLUDES(mActiveModeLock); ActiveModeInfo getUpcomingActiveMode() const REQUIRES(kMainThreadContext) { return mUpcomingActiveMode; } scheduler::FrameRateMode getActiveMode() const REQUIRES(kMainThreadContext) { return mRefreshRateSelector->getActiveMode(); } void setActiveMode(DisplayModeId, Fps displayFps, Fps renderFps); status_t initiateModeChange(const ActiveModeInfo&, const hal::VsyncPeriodChangeConstraints& constraints, hal::VsyncPeriodChangeTimeline* outTimeline) REQUIRES(kMainThreadContext); scheduler::RefreshRateSelector& refreshRateSelector() const { return *mRefreshRateSelector; } // Extends the lifetime of the RefreshRateSelector, so it can outlive this DisplayDevice. std::shared_ptr holdRefreshRateSelector() const { return mRefreshRateSelector; } // Enables an overlay to be displayed with the current refresh rate void enableRefreshRateOverlay(bool enable, bool setByHwc, bool showSpinner, bool showRenderRate, bool showInMiddle) REQUIRES(kMainThreadContext); void updateRefreshRateOverlayRate(Fps displayFps, Fps renderFps, bool setByHwc = false); bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; } bool onKernelTimerChanged(std::optional, bool timerExpired); void animateRefreshRateOverlay(); nsecs_t getVsyncPeriodFromHWC() const; Fps getAdjustedRefreshRate() const { return mAdjustedRefreshRate; } // Round the requested refresh rate to match a divisor of the pacesetter // display's refresh rate. Only supported for virtual displays. void adjustRefreshRate(Fps pacesetterDisplayRefreshRate); // release HWC resources (if any) for removable displays void disconnect(); void dump(utils::Dumper&) const; #ifdef MTK_SF_HINT_LOW_POWER public: void changeRefreshRate(bool enabled); #endif private: const sp mFlinger; HWComposer& mHwComposer; const wp mDisplayToken; const int32_t mSequenceId; const std::shared_ptr mCompositionDisplay; std::string mDisplayName; std::string mActiveModeFPSTrace; std::string mActiveModeFPSHwcTrace; std::string mRenderFrameRateFPSTrace; const ui::Rotation mPhysicalOrientation; ui::Rotation mOrientation = ui::ROTATION_0; // Allow nullopt as initial power mode. using TracedPowerMode = TracedOrdinal; std::optional mPowerMode; std::optional mStagedBrightness; std::optional mBrightness; // TODO(b/182939859): Remove special cases for primary display. const bool mIsPrimary; uint32_t mFlags = 0; // Requested refresh rate in fps, supported only for virtual displays. // when this value is non zero, SurfaceFlinger will try to drop frames // for virtual displays to match this requested refresh rate. const Fps mRequestedRefreshRate; // Adjusted refresh rate, rounded to match a divisor of the pacesetter // display's refresh rate. Only supported for virtual displays. Fps mAdjustedRefreshRate = 0_Hz; std::vector mOverrideHdrTypes; std::shared_ptr mRefreshRateSelector; std::unique_ptr mRefreshRateOverlay; mutable std::mutex mActiveModeLock; ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); TracedOrdinal mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock) = {ftl::Concat("DesiredActiveModeChanged-", getId().value).c_str(), false}; ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext); }; struct DisplayDeviceState { struct Physical { PhysicalDisplayId id; hardware::graphics::composer::hal::HWDisplayId hwcDisplayId; DisplayModePtr activeMode; bool operator==(const Physical& other) const { return id == other.id && hwcDisplayId == other.hwcDisplayId; } }; bool isVirtual() const { return !physical; } int32_t sequenceId = sNextSequenceId++; std::optional physical; sp surface; ui::LayerStack layerStack; uint32_t flags = 0; Rect layerStackSpaceRect; Rect orientedDisplaySpaceRect; ui::Rotation orientation = ui::ROTATION_0; uint32_t width = 0; uint32_t height = 0; std::string displayName; bool isSecure = false; // Refer to DisplayDevice::mRequestedRefreshRate, for virtual display only Fps requestedRefreshRate; private: static std::atomic sNextSequenceId; }; struct DisplayDeviceCreationArgs { // We use a constructor to ensure some of the values are set, without // assuming a default value. DisplayDeviceCreationArgs(const sp&, HWComposer& hwComposer, const wp& displayToken, std::shared_ptr); const sp flinger; HWComposer& hwComposer; const wp displayToken; const std::shared_ptr compositionDisplay; std::shared_ptr refreshRateSelector; int32_t sequenceId{0}; bool isSecure{false}; sp nativeWindow; sp displaySurface; ui::Rotation physicalOrientation{ui::ROTATION_0}; bool hasWideColorGamut{false}; HdrCapabilities hdrCapabilities; int32_t supportedPerFrameMetadata{0}; std::unordered_map> hwcColorModes; std::optional initialPowerMode; bool isPrimary{false}; DisplayModeId activeModeId; // Refer to DisplayDevice::mRequestedRefreshRate, for virtual display only Fps requestedRefreshRate; }; } // namespace android