/* * 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 * * 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 /* * NOTE: Make sure this file doesn't include anything from or */ #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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ActivePictureUpdater.h" #include "BackgroundExecutor.h" #include "Display/DisplayModeController.h" #include "Display/PhysicalDisplay.h" #include "Display/VirtualDisplaySnapshot.h" #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayIdGenerator.h" #include "Effects/Daltonizer.h" #include "FrontEnd/DisplayInfo.h" #include "FrontEnd/LayerCreationArgs.h" #include "FrontEnd/LayerLifecycleManager.h" #include "FrontEnd/LayerSnapshot.h" #include "FrontEnd/LayerSnapshotBuilder.h" #include "FrontEnd/TransactionHandler.h" #include "LayerVector.h" #include "MutexUtils.h" #include "PowerAdvisor/PowerAdvisor.h" #include "Scheduler/ISchedulerCallback.h" #include "Scheduler/RefreshRateSelector.h" #include "Scheduler/Scheduler.h" #include "SurfaceFlingerFactory.h" #include "ThreadContext.h" #include "Tracing/LayerTracing.h" #include "Tracing/TransactionTracing.h" #include "TransactionCallbackInvoker.h" #include "TransactionState.h" #include "Utils/OnceFuture.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Client.h" using namespace android::surfaceflinger; namespace android { class EventThread; class FlagManager; class FpsReporter; class TunnelModeEnabledReporter; class HdrLayerInfoReporter; class HWComposer; class IGraphicBufferProducer; class Layer; class MessageBase; class RefreshRateOverlay; class RegionSamplingThread; class RenderArea; class TimeStats; class FrameTracer; class ScreenCapturer; class WindowInfosListenerInvoker; using ::aidl::android::hardware::drm::HdcpLevels; using ::aidl::android::hardware::graphics::common::DisplayHotplugEvent; using ::aidl::android::hardware::graphics::composer3::RefreshRateChangedDebugData; using frontend::TransactionHandler; using gui::CaptureArgs; using gui::DisplayCaptureArgs; using gui::IRegionSamplingListener; using gui::LayerCaptureArgs; using gui::ScreenCaptureResults; namespace frametimeline { class FrameTimeline; } namespace os { class IInputFlinger; } namespace compositionengine { class DisplaySurface; class OutputLayer; struct CompositionRefreshArgs; } // namespace compositionengine namespace renderengine { class RenderEngine; } // namespace renderengine enum { eTransactionNeeded = 0x01, eTraversalNeeded = 0x02, eDisplayTransactionNeeded = 0x04, eTransformHintUpdateNeeded = 0x08, eTransactionFlushNeeded = 0x10, eInputInfoUpdateNeeded = 0x20, eTransactionMask = 0x3f, }; // Latch Unsignaled buffer behaviours enum class LatchUnsignaledConfig { // All buffers are latched signaled. Disabled, // Latch unsignaled is permitted when a single layer is updated in a frame, // and the update includes just a buffer update (i.e. no sync transactions // or geometry changes). // Latch unsignaled is also only permitted when a single transaction is ready // to be applied. If we pass an unsignaled fence to HWC, HWC might miss presenting // the frame if the fence does not fire in time. If we apply another transaction, // we may penalize the other transaction unfairly. AutoSingleLayer, // All buffers are latched unsignaled. This behaviour is discouraged as it // can break sync transactions, stall the display and cause undesired side effects. // This is equivalent to ignoring the acquire fence when applying transactions. Always, }; struct DisplayRenderAreaBuilder; struct LayerRenderAreaBuilder; using DisplayColorSetting = compositionengine::OutputColorSetting; class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ICompositor, private scheduler::ISchedulerCallback, private compositionengine::ICEPowerCallback { public: struct SkipInitializationTag {}; SurfaceFlinger(surfaceflinger::Factory&, SkipInitializationTag) ANDROID_API; explicit SurfaceFlinger(surfaceflinger::Factory&) ANDROID_API; // set main thread scheduling policy static status_t setSchedFifo(bool enabled) ANDROID_API; // set main thread scheduling attributes static status_t setSchedAttr(bool enabled); static char const* getServiceName() ANDROID_API { return "SurfaceFlinger"; } // If fences from sync Framework are supported. static bool hasSyncFramework; // The offset in nanoseconds to use when VsyncController timestamps present fence // signaling time. static int64_t dispSyncPresentTimeOffset; // Some hardware can do RGB->YUV conversion more efficiently in hardware // controlled by HWC than in hardware controlled by the video encoder. // This instruct VirtualDisplaySurface to use HWC for such conversion on // GL composition. static bool useHwcForRgbToYuv; // Controls the number of buffers SurfaceFlinger will allocate for use in // FramebufferSurface static int64_t maxFrameBufferAcquiredBuffers; // Controls the minimum acquired buffers SurfaceFlinger will suggest via // ISurfaceComposer.getMaxAcquiredBufferCount(). static int64_t minAcquiredBuffers; // Controls the maximum width and height in pixels that the graphics pipeline can support for // GPU fallback composition. For example, 8k devices with 4k GPUs, or 4k devices with 2k GPUs. static uint32_t maxGraphicsWidth; static uint32_t maxGraphicsHeight; static bool useContextPriority; // The data space and pixel format that SurfaceFlinger expects hardware composer // to composite efficiently. Meaning under most scenarios, hardware composer // will accept layers with the data space and pixel format. static ui::Dataspace defaultCompositionDataspace; static ui::PixelFormat defaultCompositionPixelFormat; // The data space and pixel format that SurfaceFlinger expects hardware composer // to composite efficiently for wide color gamut surfaces. Meaning under most scenarios, // hardware composer will accept layers with the data space and pixel format. static ui::Dataspace wideColorGamutCompositionDataspace; static ui::PixelFormat wideColorGamutCompositionPixelFormat; static constexpr SkipInitializationTag SkipInitialization; static LatchUnsignaledConfig enableLatchUnsignaledConfig; // must be called before clients can connect void init() ANDROID_API; // starts SurfaceFlinger main loop in the current thread void run() ANDROID_API; // Indicates frame activity, i.e. whether commit and/or composite is taking place. enum class FrameHint { kNone, kActive }; // Schedule commit of transactions on the main thread ahead of the next VSYNC. void scheduleCommit(FrameHint, Duration workDurationSlack = Duration::fromNs(0)); // As above, but also force composite regardless if transactions were committed. void scheduleComposite(FrameHint); // As above, but also force dirty geometry to repaint. void scheduleRepaint(); // Schedule sampling independently from commit or composite. void scheduleSample(); surfaceflinger::Factory& getFactory() { return mFactory; } // The CompositionEngine encapsulates all composition related interfaces and actions. compositionengine::CompositionEngine& getCompositionEngine() const; renderengine::RenderEngine& getRenderEngine() const; void onLayerFirstRef(Layer*); void onLayerDestroyed(Layer*); void onLayerUpdate(); // Called when all clients have released all their references to // this layer. The layer may still be kept alive by its parents but // the client can no longer modify this layer directly. void onHandleDestroyed(sp& layer, uint32_t layerId); TransactionCallbackInvoker& getTransactionCallbackInvoker() { return mTransactionCallbackInvoker; } // If set, disables reusing client composition buffers. This can be set by // debug.sf.disable_client_composition_cache bool mDisableClientCompositionCache = false; // Disables expensive rendering for all displays // This is scheduled on the main thread void disableExpensiveRendering(); // If set, composition engine tries to predict the composition strategy provided by HWC // based on the previous frame. If the strategy can be predicted, gpu composition will // run parallel to the hwc validateDisplay call and re-run if the predition is incorrect. bool mPredictCompositionStrategy = false; // If true, then any layer with a SMPTE 170M transfer function is decoded using the sRGB // transfer instead. This is mainly to preserve legacy behavior, where implementations treated // SMPTE 170M as sRGB prior to color management being implemented, and now implementations rely // on this behavior to increase contrast for some media sources. bool mTreat170mAsSrgb = false; // If true, then screenshots with an enhanced render intent will dim in gamma space. // The purpose is to ensure that screenshots appear correct during system animations for devices // that require that dimming must occur in gamma space. bool mDimInGammaSpaceForEnhancedScreenshots = false; // Allows to ignore physical orientation provided through hwc API in favour of // 'ro.surface_flinger.primary_display_orientation'. // TODO(b/246793311): Clean up a temporary property bool mIgnoreHwcPhysicalDisplayOrientation = false; void forceFutureUpdate(int delayInMs); const DisplayDevice* getDisplayFromLayerStack(ui::LayerStack) REQUIRES(mStateLock, kMainThreadContext); // TODO (b/259407931): Remove. // TODO (b/281857977): This should be annotated with REQUIRES(kMainThreadContext), but this // would require thread safety annotations throughout the frontend (in particular Layer and // LayerFE). static ui::Transform::RotationFlags getActiveDisplayRotationFlags() { return sActiveDisplayRotationFlags; } protected: // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); virtual void processDisplayAdded(const wp& displayToken, const DisplayDeviceState&) REQUIRES(mStateLock); virtual std::shared_ptr getExternalTextureFromBufferData( BufferData& bufferData, const char* layerName, uint64_t transactionId); // Returns true if any display matches a `bool(const DisplayDevice&)` predicate. template bool hasDisplay(Predicate p) const REQUIRES(mStateLock) { return static_cast(findDisplay(p)); } bool exceedsMaxRenderTargetSize(uint32_t width, uint32_t height) const { return width > mMaxRenderTargetSize || height > mMaxRenderTargetSize; } private: friend class BufferLayer; friend class Client; friend class FpsReporter; friend class TunnelModeEnabledReporter; friend class Layer; friend class RefreshRateOverlay; friend class RegionSamplingThread; friend class LayerRenderArea; friend class SurfaceComposerAIDL; friend class DisplayRenderArea; // For unit tests friend class TestableSurfaceFlinger; friend class TransactionApplicationTest; friend class TunnelModeEnabledReporterTest; using TransactionSchedule = scheduler::TransactionSchedule; using GetLayerSnapshotsFunction = std::function>>()>; using RenderAreaBuilderVariant = std::variant; using DumpArgs = Vector; using Dumper = std::function; class State { public: explicit State(LayerVector::StateSet set) : stateSet(set) {} State& operator=(const State& other) { // We explicitly don't copy stateSet so that, e.g., mDrawingState // always uses the Drawing StateSet. displays = other.displays; colorMatrixChanged = other.colorMatrixChanged; if (colorMatrixChanged) { colorMatrix = other.colorMatrix; } globalShadowSettings = other.globalShadowSettings; return *this; } const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid; // TODO(b/241285876): Replace deprecated DefaultKeyedVector with ftl::SmallMap. DefaultKeyedVector, DisplayDeviceState> displays; std::optional getDisplayIndex(PhysicalDisplayId displayId) const { for (size_t i = 0; i < displays.size(); i++) { const auto& state = displays.valueAt(i); if (state.physical && state.physical->id == displayId) { return i; } } return {}; } bool colorMatrixChanged = true; mat4 colorMatrix; ShadowSettings globalShadowSettings; }; // Keeps track of pending buffers per layer handle in the transaction queue or current/drawing // state before the buffers are latched. The layer owns the atomic counters and decrements the // count in the main thread when dropping or latching a buffer. // // The binder threads increment the same counter when a new transaction containing a buffer is // added to the transaction queue. The map is updated with the layer handle lifecycle updates. // This is done to avoid lock contention with the main thread. class BufferCountTracker { public: void increment(uint32_t layerId) { std::lock_guard lock(mLock); auto it = mCounterByLayerId.find(layerId); if (it != mCounterByLayerId.end()) { auto [name, pendingBuffers] = it->second; int32_t count = ++(*pendingBuffers); SFTRACE_INT(name.c_str(), count); } else { ALOGW("Layer ID not found! %d", layerId); } } void add(uint32_t layerId, const std::string& name, std::atomic* counter) { std::lock_guard lock(mLock); mCounterByLayerId[layerId] = std::make_pair(name, counter); } void remove(uint32_t layerId) { std::lock_guard lock(mLock); mCounterByLayerId.erase(layerId); } private: std::mutex mLock; std::unordered_map*>> mCounterByLayerId GUARDED_BY(mLock); }; enum class BootStage { BOOTLOADER, BOOTANIMATION, FINISHED, }; template >* = nullptr> static Dumper dumper(F&& dump) { using namespace std::placeholders; return std::bind(std::forward(dump), _3); } Dumper lockedDumper(Dumper dump) { return [this, dump](const DumpArgs& args, bool asProto, std::string& result) -> void { TimedLock lock(mStateLock, s2ns(1), __func__); if (!lock.locked()) { base::StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n", strerror(-lock.status), lock.status); } dump(args, asProto, result); }; } template >* = nullptr> Dumper dumper(F dump) { using namespace std::placeholders; return lockedDumper(std::bind(dump, this, _3)); } template Dumper argsDumper(F dump) { using namespace std::placeholders; return lockedDumper(std::bind(dump, this, _1, _3)); } template Dumper protoDumper(F dump) { using namespace std::placeholders; return lockedDumper(std::bind(dump, this, _1, _2, _3)); } Dumper mainThreadDumperImpl(Dumper dumper) { return [this, dumper](const DumpArgs& args, bool asProto, std::string& result) -> void { mScheduler ->schedule( [&args, asProto, &result, dumper]() FTL_FAKE_GUARD(kMainThreadContext) FTL_FAKE_GUARD(mStateLock) { dumper(args, asProto, result); }) .get(); }; } template >* = nullptr> Dumper mainThreadDumper(F dump) { using namespace std::placeholders; return mainThreadDumperImpl(std::bind(dump, this, _3)); } template >* = nullptr> Dumper argsMainThreadDumper(F dump) { using namespace std::placeholders; return mainThreadDumperImpl(std::bind(dump, this, _1, _3)); } // Maximum allowed number of display frames that can be set through backdoor static const int MAX_ALLOWED_DISPLAY_FRAMES = 2048; static const size_t MAX_LAYERS = 4096; static bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true) EXCLUDES(mStateLock); // IBinder overrides: status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override; status_t dump(int fd, const Vector& args) override { return priorityDump(fd, args); } // ISurfaceComposer implementation: sp createVirtualDisplay(const std::string& displayName, bool isSecure, const std::string& uniqueId, float requestedRefreshRate = 0.0f); status_t destroyVirtualDisplay(const sp& displayToken); std::vector getPhysicalDisplayIds() const EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return getPhysicalDisplayIdsLocked(); } sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const; status_t setTransactionState( const FrameTimelineInfo& frameTimelineInfo, Vector& state, Vector& displays, uint32_t flags, const sp& applyToken, InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector& uncacheBuffers, bool hasListenerCallbacks, const std::vector& listenerCallbacks, uint64_t transactionId, const std::vector& mergedTransactionIds) override; void bootFinished(); status_t getSupportedFrameTimestamps(std::vector* outSupported) const; sp createDisplayEventConnection( gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, EventRegistrationFlags eventRegistration = {}, const sp& layerHandle = nullptr); void captureDisplay(const DisplayCaptureArgs&, const sp&); void captureDisplay(DisplayId, const CaptureArgs&, const sp&); ScreenCaptureResults captureLayersSync(const LayerCaptureArgs&); void captureLayers(const LayerCaptureArgs&, const sp&); status_t getDisplayStats(const sp& displayToken, DisplayStatInfo* stats); status_t getDisplayState(const sp& displayToken, ui::DisplayState*) EXCLUDES(mStateLock); status_t getStaticDisplayInfo(int64_t displayId, ui::StaticDisplayInfo*) EXCLUDES(mStateLock); status_t getDynamicDisplayInfoFromId(int64_t displayId, ui::DynamicDisplayInfo*) EXCLUDES(mStateLock); status_t getDynamicDisplayInfoFromToken(const sp& displayToken, ui::DynamicDisplayInfo*) EXCLUDES(mStateLock); void getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*&, const sp&, const display::DisplaySnapshot&); status_t getDisplayNativePrimaries(const sp& displayToken, ui::DisplayPrimaries&); status_t setActiveColorMode(const sp& displayToken, ui::ColorMode colorMode); status_t getBootDisplayModeSupport(bool* outSupport) const; status_t setBootDisplayMode(const sp&, DisplayModeId); status_t getOverlaySupport(gui::OverlayProperties* outProperties) const; status_t clearBootDisplayMode(const sp& displayToken); status_t getHdrConversionCapabilities( std::vector* hdrConversionCapaabilities) const; status_t setHdrConversionStrategy(const gui::HdrConversionStrategy& hdrConversionStrategy, int32_t*); status_t getHdrOutputConversionSupport(bool* outSupport) const; void setAutoLowLatencyMode(const sp& displayToken, bool on); void setGameContentType(const sp& displayToken, bool on); status_t getMaxLayerPictureProfiles(const sp& displayToken, int32_t* outMaxProfiles); void setPowerMode(const sp& displayToken, int mode); status_t overrideHdrTypes(const sp& displayToken, const std::vector& hdrTypes); status_t onPullAtom(const int32_t atomId, std::vector* pulledData, bool* success); status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat, ui::Dataspace* outWideColorGamutDataspace, ui::PixelFormat* outWideColorGamutPixelFormat) const; status_t getDisplayedContentSamplingAttributes(const sp& displayToken, ui::PixelFormat* outFormat, ui::Dataspace* outDataspace, uint8_t* outComponentMask) const; status_t setDisplayContentSamplingEnabled(const sp& displayToken, bool enable, uint8_t componentMask, uint64_t maxFrames); status_t getDisplayedContentSample(const sp& displayToken, uint64_t maxFrames, uint64_t timestamp, DisplayedFrameStats* outStats) const; status_t getProtectedContentSupport(bool* outSupported) const; status_t isWideColorDisplay(const sp& displayToken, bool* outIsWideColorDisplay) const; status_t addRegionSamplingListener(const Rect& samplingArea, const sp& stopLayerHandle, const sp& listener); status_t removeRegionSamplingListener(const sp& listener); status_t addFpsListener(int32_t taskId, const sp& listener); status_t removeFpsListener(const sp& listener); status_t addTunnelModeEnabledListener(const sp& listener); status_t removeTunnelModeEnabledListener(const sp& listener); status_t setDesiredDisplayModeSpecs(const sp& displayToken, const gui::DisplayModeSpecs&); status_t getDesiredDisplayModeSpecs(const sp& displayToken, gui::DisplayModeSpecs*); status_t getDisplayBrightnessSupport(const sp& displayToken, bool* outSupport) const; status_t setDisplayBrightness(const sp& displayToken, const gui::DisplayBrightness& brightness); status_t addHdrLayerInfoListener(const sp& displayToken, const sp& listener); status_t removeHdrLayerInfoListener(const sp& displayToken, const sp& listener); status_t notifyPowerBoost(int32_t boostId); status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius); status_t getDisplayDecorationSupport( const sp& displayToken, std::optional* outSupport) const; status_t setFrameRate(const sp& surface, float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy); status_t setFrameTimelineInfo(const sp& surface, const gui::FrameTimelineInfo& frameTimelineInfo); status_t setGameModeFrameRateOverride(uid_t uid, float frameRate); status_t setGameDefaultFrameRateOverride(uid_t uid, float frameRate); status_t updateSmallAreaDetection(std::vector>& uidThresholdMappings); status_t setSmallAreaDetectionThreshold(int32_t appId, float threshold); int getGpuContextPriority(); status_t getMaxAcquiredBufferCount(int* buffers) const; status_t addWindowInfosListener(const sp& windowInfosListener, gui::WindowInfosListenerInfo* outResult); status_t removeWindowInfosListener( const sp& windowInfosListener) const; status_t getStalledTransactionInfo( int pid, std::optional& result); void updateHdcpLevels(hal::HWDisplayId hwcDisplayId, int32_t connectedLevel, int32_t maxLevel); void setActivePictureListener(const sp& listener); // IBinder::DeathRecipient overrides: void binderDied(const wp& who) override; // HWC2::ComposerCallback overrides: void onComposerHalVsync(hal::HWDisplayId, nsecs_t timestamp, std::optional) override; void onComposerHalHotplugEvent(hal::HWDisplayId, DisplayHotplugEvent) override; void onComposerHalRefresh(hal::HWDisplayId) override; void onComposerHalVsyncPeriodTimingChanged(hal::HWDisplayId, const hal::VsyncPeriodChangeTimeline&) override; void onComposerHalSeamlessPossible(hal::HWDisplayId) override; void onComposerHalVsyncIdle(hal::HWDisplayId) override; void onRefreshRateChangedDebug(const RefreshRateChangedDebugData&) override; void onComposerHalHdcpLevelsChanged(hal::HWDisplayId, const HdcpLevels& levels) override; // ICompositor overrides: void configure() override REQUIRES(kMainThreadContext); bool commit(PhysicalDisplayId pacesetterId, const scheduler::FrameTargets&) override REQUIRES(kMainThreadContext); CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters&) override REQUIRES(kMainThreadContext); void sample() override; // ISchedulerCallback overrides: void requestHardwareVsync(PhysicalDisplayId, bool) override; void requestDisplayModes(std::vector) override; void kernelTimerChanged(bool expired) override; void onChoreographerAttached() override; void onExpectedPresentTimePosted(TimePoint expectedPresentTime, ftl::NonNull, Fps renderRate) override; void onCommitNotComposited() override REQUIRES(kMainThreadContext); void vrrDisplayIdle(bool idle) override; // ICEPowerCallback overrides: void notifyCpuLoadUp() override; using KernelIdleTimerController = scheduler::RefreshRateSelector::KernelIdleTimerController; // Get the controller and timeout that will help decide how the kernel idle timer will be // configured and what value to use as the timeout. std::pair, std::chrono::milliseconds> getKernelIdleTimerProperties(PhysicalDisplayId) REQUIRES(mStateLock); // Show spinner with refresh rate overlay bool mRefreshRateOverlaySpinner = false; // Show render rate with refresh rate overlay bool mRefreshRateOverlayRenderRate = false; // Show render rate overlay offseted to the middle of the screen (e.g. for circular displays) bool mRefreshRateOverlayShowInMiddle = false; // Show hdr sdr ratio overlay bool mHdrSdrRatioOverlay = false; void setDesiredMode(display::DisplayModeRequest&&) REQUIRES(mStateLock); status_t setActiveModeFromBackdoor(const sp&, DisplayModeId, Fps minFps, Fps maxFps); void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) REQUIRES(mStateLock); void finalizeDisplayModeChange(PhysicalDisplayId) REQUIRES(kMainThreadContext) REQUIRES(mStateLock); void dropModeRequest(PhysicalDisplayId) REQUIRES(kMainThreadContext); void applyActiveMode(PhysicalDisplayId) REQUIRES(kMainThreadContext); // Called on the main thread in response to setPowerMode() void setPowerModeInternal(const sp& display, hal::PowerMode mode) REQUIRES(mStateLock, kMainThreadContext); // Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that // display. Falls back to the display's defaultModeId otherwise. ftl::Optional getPreferredDisplayMode( PhysicalDisplayId, DisplayModeId defaultModeId) const REQUIRES(mStateLock); status_t setDesiredDisplayModeSpecsInternal( const sp&, const scheduler::RefreshRateSelector::PolicyVariant&) EXCLUDES(mStateLock) REQUIRES(kMainThreadContext); // TODO(b/241285191): Look up RefreshRateSelector on Scheduler to remove redundant parameter. status_t applyRefreshRateSelectorPolicy(PhysicalDisplayId, const scheduler::RefreshRateSelector&) REQUIRES(mStateLock, kMainThreadContext); void commitTransactions() REQUIRES(kMainThreadContext, mStateLock); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock, kMainThreadContext); void doCommitTransactions() REQUIRES(mStateLock); std::vector> moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) REQUIRES(kMainThreadContext); void moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs& refreshArgs, const std::vector>& layers) REQUIRES(kMainThreadContext); // Return true if we must composite this frame bool updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); void updateLayerHistory(nsecs_t now) REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) REQUIRES(kMainThreadContext); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector& outWindowInfos, std::vector& outDisplayInfos) REQUIRES(kMainThreadContext); void commitInputWindowCommands() REQUIRES(mStateLock); void updateCursorAsync() REQUIRES(kMainThreadContext); void initScheduler(const sp&) REQUIRES(kMainThreadContext, mStateLock); /* * Transactions */ bool applyTransactionState(const FrameTimelineInfo& info, std::vector& state, Vector& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const std::vector& uncacheBufferIds, const int64_t postTime, bool hasListenerCallbacks, const std::vector& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock, kMainThreadContext); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues() REQUIRES(kMainThreadContext); bool applyTransactions(std::vector&) REQUIRES(kMainThreadContext); bool applyAndCommitDisplayTransactionStatesLocked(std::vector& transactions) REQUIRES(kMainThreadContext, mStateLock); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded() REQUIRES(kMainThreadContext); void addTransactionReadyFilters() REQUIRES(kMainThreadContext); TransactionHandler::TransactionReadiness transactionReadyTimelineCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); TransactionHandler::TransactionReadiness transactionReadyBufferCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock, kMainThreadContext); uint32_t getTransactionFlags() const; // Sets the masked bits, and schedules a commit if needed. void setTransactionFlags(uint32_t mask, TransactionSchedule = TransactionSchedule::Late, const sp& applyToken = nullptr, FrameHint = FrameHint::kActive); // Clears and returns the masked bits. uint32_t clearTransactionFlags(uint32_t mask); static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const layer_state_t&, size_t numStates, bool firstTransaction) const; bool applyTransactionsLocked(std::vector& transactions) REQUIRES(mStateLock, kMainThreadContext); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); bool frameIsEarly(TimePoint expectedPresentTime, VsyncId) const; /* * Layer management */ status_t createLayer(LayerCreationArgs& args, gui::CreateSurfaceResult& outResult); status_t createBufferStateLayer(LayerCreationArgs& args, sp* outHandle, sp* outLayer); status_t createEffectLayer(const LayerCreationArgs& args, sp* outHandle, sp* outLayer); status_t mirrorLayer(const LayerCreationArgs& args, const sp& mirrorFromHandle, gui::CreateSurfaceResult& outResult); status_t mirrorDisplay(DisplayId displayId, const LayerCreationArgs& args, gui::CreateSurfaceResult& outResult); // add a layer to SurfaceFlinger status_t addClientLayer(LayerCreationArgs& args, const sp& handle, const sp& layer, const wp& parentLayer, uint32_t* outTransformHint); // Creates a promise for a future release fence for a layer. This allows for // the layer to keep track of when its buffer can be released. void attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE, ui::LayerStack layerStack); // Checks if a protected layer exists in a list of layers. bool layersHasProtectedLayer(const std::vector>>& layers) const; using OutputCompositionState = compositionengine::impl::OutputCompositionState; std::optional getSnapshotsFromMainThread( RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector>>& layers); void captureScreenCommon(RenderAreaBuilderVariant, GetLayerSnapshotsFunction, ui::Size bufferSize, ui::PixelFormat, bool allowProtected, bool grayscale, bool attachGainmap, const sp&); std::optional getDisplayStateFromRenderAreaBuilder( RenderAreaBuilderVariant& renderAreaBuilder) REQUIRES(kMainThreadContext); ftl::SharedFuture captureScreenshot( const RenderAreaBuilderVariant& renderAreaBuilder, const std::shared_ptr& buffer, bool regionSampling, bool grayscale, bool isProtected, bool attachGainmap, const sp& captureListener, std::optional& displayState, std::vector>>& layers); ftl::SharedFuture renderScreenImpl( const RenderArea*, const std::shared_ptr&, bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults&, std::optional& displayState, std::vector>>& layers); void readPersistentProperties(); uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const; /* * Display and layer stack management */ // Called during boot and restart after system_server death, setting the stage for bootanimation // before DisplayManager takes over. void initializeDisplays() REQUIRES(kMainThreadContext); sp getDisplayDeviceLocked(const wp& displayToken) const REQUIRES(mStateLock) { return const_cast(this)->getDisplayDeviceLocked(displayToken); } sp getDisplayDeviceLocked(const wp& displayToken) REQUIRES(mStateLock) { return mDisplays.get(displayToken) .or_else(ftl::static_ref>([] { return nullptr; })) .value(); } sp getDisplayDeviceLocked(PhysicalDisplayId id) const REQUIRES(mStateLock) { return const_cast(this)->getDisplayDeviceLocked(id); } sp getDisplayDeviceLocked(PhysicalDisplayId id) REQUIRES(mStateLock) { if (const auto token = getPhysicalDisplayTokenLocked(id)) { return getDisplayDeviceLocked(token); } return nullptr; } sp getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) { // TODO(b/182939859): Replace tokens with IDs for display lookup. return findDisplay([id](const auto& display) { return display.getId() == id; }); } std::shared_ptr getCompositionDisplayLocked(DisplayId id) const REQUIRES(mStateLock) { if (const auto display = getDisplayDeviceLocked(id)) { return display->getCompositionDisplay(); } return nullptr; } // Returns the primary display or (for foldables) the active display. sp getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) { return const_cast(this)->getDefaultDisplayDeviceLocked(); } sp getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) { return getDisplayDeviceLocked(mActiveDisplayId); } sp getDefaultDisplayDevice() const EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return getDefaultDisplayDeviceLocked(); } using DisplayDeviceAndSnapshot = std::pair, display::DisplaySnapshotRef>; // Combinator for ftl::Optional::and_then. auto getDisplayDeviceAndSnapshot() REQUIRES(mStateLock) { return [this](const display::PhysicalDisplay& display) REQUIRES( mStateLock) -> ftl::Optional { if (auto device = getDisplayDeviceLocked(display.snapshot().displayId())) { return std::make_pair(std::move(device), display.snapshotRef()); } return {}; }; } // Returns the first display that matches a `bool(const DisplayDevice&)` predicate. template sp findDisplay(Predicate p) const REQUIRES(mStateLock) { const auto it = std::find_if(mDisplays.begin(), mDisplays.end(), [&](const auto& pair) REQUIRES(mStateLock) { return p(*pair.second); }); return it == mDisplays.end() ? nullptr : it->second; } std::vector getPhysicalDisplayIdsLocked() const REQUIRES(mStateLock); // mark a region of a layer stack dirty. this updates the dirty // region of all screens presenting this layer stack. void invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty); ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack) REQUIRES(mStateLock) { return {layerStack, PhysicalDisplayId::tryCast(displayId) .and_then(display::getPhysicalDisplay(mPhysicalDisplays)) .transform(&display::PhysicalDisplay::isInternal) .value_or(false)}; } /* * H/W composer */ // The following thread safety rules apply when accessing HWComposer: // 1. When reading display state from HWComposer on the main thread, it's not necessary to // acquire mStateLock. // 2. When accessing HWComposer on a thread other than the main thread, we always // need to acquire mStateLock. This is because the main thread could be // in the process of writing display state, e.g. creating or destroying a display. HWComposer& getHwComposer() const; /* * Compositing */ void onCompositionPresented(PhysicalDisplayId pacesetterId, const scheduler::FrameTargeters&, nsecs_t presentStartTime) REQUIRES(kMainThreadContext); /* * Display management */ std::pair loadDisplayModes(PhysicalDisplayId) const REQUIRES(mStateLock); // TODO(b/241285876): Move to DisplayConfigurator. // // Returns whether displays have been added/changed/removed, i.e. whether ICompositor should // commit display transactions. bool configureLocked() REQUIRES(mStateLock) REQUIRES(kMainThreadContext) EXCLUDES(mHotplugMutex); // Returns the active mode ID, or nullopt on hotplug failure. std::optional processHotplugConnect(PhysicalDisplayId, hal::HWDisplayId, DisplayIdentificationInfo&&, const char* displayString) REQUIRES(mStateLock, kMainThreadContext); void processHotplugDisconnect(PhysicalDisplayId, const char* displayString) REQUIRES(mStateLock, kMainThreadContext); sp setupNewDisplayDeviceInternal( const wp& displayToken, std::shared_ptr compositionDisplay, const DisplayDeviceState& state, const sp& displaySurface, const sp& producer) REQUIRES(mStateLock); void processDisplayChangesLocked() REQUIRES(mStateLock, kMainThreadContext); void processDisplayRemoved(const wp& displayToken) REQUIRES(mStateLock, kMainThreadContext); void processDisplayChanged(const wp& displayToken, const DisplayDeviceState& currentState, const DisplayDeviceState& drawingState) REQUIRES(mStateLock, kMainThreadContext); /* * Display identification */ sp getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { return mPhysicalDisplays.get(displayId) .transform([](const display::PhysicalDisplay& display) { return display.token(); }) .or_else([] { return std::optional>(nullptr); }) .value(); } std::optional getPhysicalDisplayIdLocked( const sp&) const REQUIRES(mStateLock); // Returns the first display connected at boot. // // TODO(b/229851933): SF conflates the primary display with the first display connected at boot, // which typically has DisplayConnectionType::Internal. (Theoretically, it must be an internal // display because SF does not support disconnecting it, though in practice HWC may circumvent // this limitation.) sp getPrimaryDisplayTokenLocked() const REQUIRES(mStateLock) { return getPhysicalDisplayTokenLocked(getPrimaryDisplayIdLocked()); } PhysicalDisplayId getPrimaryDisplayIdLocked() const REQUIRES(mStateLock) { return getHwComposer().getPrimaryDisplayId(); } // Toggles use of HAL/GPU virtual displays. void enableHalVirtualDisplays(bool); // Virtual display lifecycle for ID generation and HAL allocation. VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, const std::string& uniqueId) REQUIRES(mStateLock); template void acquireVirtualDisplaySnapshot(ID displayId, const std::string& uniqueId) { std::lock_guard lock(mVirtualDisplaysMutex); const bool emplace_success = mVirtualDisplays.try_emplace(displayId, displayId, uniqueId).second; if (!emplace_success) { ALOGW("%s: Virtual display snapshot with the same ID already exists", __func__); } } void releaseVirtualDisplay(VirtualDisplayId); void releaseVirtualDisplaySnapshot(VirtualDisplayId displayId); // Returns a display other than `mActiveDisplayId` that can be activated, if any. sp getActivatableDisplay() const REQUIRES(mStateLock, kMainThreadContext); void onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr, const DisplayDevice& activeDisplay) REQUIRES(mStateLock, kMainThreadContext); void onActiveDisplaySizeChanged(const DisplayDevice&); /* * Debugging & dumpsys */ void dumpAll(const DumpArgs& args, const std::string& compositionLayers, std::string& result) const EXCLUDES(mStateLock); void dumpHwcLayersMinidump(std::string& result) const REQUIRES(mStateLock, kMainThreadContext); void appendSfConfigString(std::string& result) const; void listLayers(std::string& result) const REQUIRES(kMainThreadContext); void dumpStats(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock, kMainThreadContext); void clearStats(const DumpArgs& args, std::string& result) REQUIRES(kMainThreadContext); void dumpTimeStats(const DumpArgs& args, bool asProto, std::string& result) const; void dumpFrameTimeline(const DumpArgs& args, std::string& result) const; void logFrameStats(TimePoint now) REQUIRES(kMainThreadContext); void dumpScheduler(std::string& result) const REQUIRES(mStateLock); void dumpEvents(std::string& result) const REQUIRES(mStateLock); void dumpVsync(std::string& result) const REQUIRES(mStateLock); void dumpCompositionDisplays(std::string& result) const REQUIRES(mStateLock); void dumpDisplays(std::string& result) const REQUIRES(mStateLock); void dumpDisplayIdentificationData(std::string& result) const REQUIRES(mStateLock); void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const; void dumpWideColorInfo(std::string& result) const REQUIRES(mStateLock); void dumpHdrInfo(std::string& result) const REQUIRES(mStateLock); void dumpFrontEnd(std::string& result) REQUIRES(kMainThreadContext); void dumpVisibleFrontEnd(std::string& result) REQUIRES(mStateLock, kMainThreadContext); perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const REQUIRES(kMainThreadContext); google::protobuf::RepeatedPtrField dumpDisplayProto() const; void doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty, TimePoint, VsyncId) REQUIRES(kMainThreadContext); perfetto::protos::LayersSnapshotProto takeLayersSnapshotProto(uint32_t flags, TimePoint, VsyncId, bool visibleRegionDirty) REQUIRES(kMainThreadContext); // Dumps state from HW Composer void dumpHwc(std::string& result) const; perfetto::protos::LayersProto dumpProtoFromMainThread( uint32_t traceFlags = LayerTracing::TRACE_ALL) EXCLUDES(mStateLock); void dumpPlannerInfo(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); status_t doDump(int fd, const DumpArgs& args, bool asProto); status_t dumpCritical(int fd, const DumpArgs&, bool asProto); status_t dumpAll(int fd, const DumpArgs& args, bool asProto) override { return doDump(fd, args, asProto); } static mat4 calculateColorMatrix(float saturation); void updateColorMatrixLocked(); // Verify that transaction is being called by an approved process: // either AID_GRAPHICS or AID_SYSTEM. status_t CheckTransactCodeCredentials(uint32_t code); // Add transaction to the Transaction Queue /* * Generic Layer Metadata */ const std::unordered_map& getGenericLayerMetadataKeyMap() const; static int calculateMaxAcquiredBufferCount(Fps refreshRate, std::chrono::nanoseconds presentLatency); int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const; bool isHdrLayer(const frontend::LayerSnapshot& snapshot) const; ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); void traverseLegacyLayers(const LayerVector::Visitor& visitor) const REQUIRES(kMainThreadContext); void initBootProperties(); void initTransactionTraceWriter(); surfaceflinger::Factory& mFactory; pid_t mPid; // TODO: b/328459745 - Encapsulate in a SystemProperties object. utils::OnceFuture mInitBootPropsFuture; utils::OnceFuture mRenderEnginePrimeCacheFuture; // mStateLock has conventions related to the current thread, because only // the main thread should modify variables protected by mStateLock. // - read access from a non-main thread must lock mStateLock, since the main // thread may modify these variables. // - write access from a non-main thread is not permitted. // - read access from the main thread can use an ftl::FakeGuard, since other // threads must not modify these variables. // - write access from the main thread must lock mStateLock, since another // thread may be reading these variables. mutable Mutex mStateLock; State mCurrentState{LayerVector::StateSet::Current}; std::atomic mTransactionFlags = 0; std::atomic mUniqueTransactionId = 1; // Buffers that have been discarded by clients and need to be evicted from per-layer caches so // the graphics memory can be immediately freed. std::vector mBufferIdsToUncache; // global color transform states Daltonizer mDaltonizer; float mGlobalSaturationFactor = 1.0f; mat4 mClientColorMatrix; // protected by mStateLock (but we could use another lock) bool mLayersRemoved = false; bool mLayersAdded = false; std::atomic_bool mMustComposite = false; std::atomic_bool mGeometryDirty = false; // constant members (no synchronization needed for access) const nsecs_t mBootTime = systemTime(); bool mIsUserBuild = true; bool mHasReliablePresentFences = false; // Can only accessed from the main thread, these members // don't need synchronization State mDrawingState{LayerVector::StateSet::Drawing}; bool mVisibleRegionsDirty = false; bool mHdrLayerInfoChanged = false; struct LayerEvent { uid_t uid; int32_t layerId; ui::Dataspace dataspace; std::chrono::milliseconds timeSinceLastEvent; }; std::vector mLayerEvents; // Used to ensure we omit a callback when HDR layer info listener is newly added but the // scene hasn't changed bool mAddingHDRLayerInfoListener = false; bool mIgnoreHdrCameraLayers = false; // Set during transaction application stage to track if the input info or children // for a layer has changed. // TODO: Also move visibleRegions over to a boolean system. bool mUpdateInputInfo = false; bool mSomeChildrenChanged; bool mUpdateAttachedChoreographer = false; struct LayerIntHash { size_t operator()(const std::pair, gui::GameMode>& k) const { return std::hash()(k.first.get()) ^ std::hash()(static_cast(k.second)); } }; // TODO(b/238781169) validate these on composition // Tracks layers that have pending frames which are candidates for being // latched. std::unordered_set, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames; std::unordered_set, SpHash> mLayersWithBuffersRemoved; // Sorted list of layers that were composed during previous frame. This is used to // avoid an expensive traversal of the layer hierarchy when there are no // visible region changes. Because this is a list of strong pointers, this will // extend the life of the layer but this list is only updated in the main thread. std::vector> mPreviouslyComposedLayers; BootStage mBootStage = BootStage::BOOTLOADER; struct HotplugEvent { hal::HWDisplayId hwcDisplayId; hal::Connection connection = hal::Connection::INVALID; }; bool mIsHdcpViaNegVsync = false; std::mutex mHotplugMutex; std::vector mPendingHotplugEvents GUARDED_BY(mHotplugMutex); // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and // never removed, so take precedence over external and virtual displays. // // May be read from any thread, but must only be written from the main thread. ui::DisplayMap, const sp> mDisplays GUARDED_BY(mStateLock); display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock); mutable std::mutex mVirtualDisplaysMutex; ftl::SmallMap mVirtualDisplays GUARDED_BY(mVirtualDisplaysMutex); // The inner or outer display for foldables, while unfolded or folded, respectively. std::atomic mActiveDisplayId; display::DisplayModeController mDisplayModeController; struct { DisplayIdGenerator gpu; std::optional> hal; } mVirtualDisplayIdGenerators; std::atomic_uint mDebugFlashDelay = 0; std::atomic_bool mDebugDisableHWC = false; std::atomic_bool mDebugDisableTransformHint = false; std::atomic mDebugInTransaction = 0; std::atomic_bool mForceFullDamage = false; bool mLayerCachingEnabled = false; bool mBackpressureGpuComposition = false; LayerTracing mLayerTracing; std::optional mTransactionTracing; const std::shared_ptr mTimeStats; const std::unique_ptr mFrameTracer; const std::unique_ptr mFrameTimeline; VsyncId mLastCommittedVsyncId; // If blurs should be enabled on this device. bool mSupportsBlur = false; TransactionCallbackInvoker mTransactionCallbackInvoker; std::atomic mNumLayers = 0; // to linkToDeath sp mWindowManager; // We want to avoid multiple calls to BOOT_FINISHED as they come in on // different threads without a lock and could trigger unsynchronized writes to // to mWindowManager or mInputFlinger std::atomic mBootFinished = false; std::thread::id mMainThreadId = std::this_thread::get_id(); DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::kEnhanced; // Color mode forced by setting persist.sys.sf.color_mode, it must: // 1. not be NATIVE color mode, NATIVE color mode means no forced color mode; // 2. be one of the supported color modes returned by hardware composer, otherwise // it will not be respected. // persist.sys.sf.color_mode will only take effect when persist.sys.sf.native_mode // is not set to 1. // This property can be used to force SurfaceFlinger to always pick a certain color mode. ui::ColorMode mForceColorMode = ui::ColorMode::NATIVE; // Whether to enable wide color gamut (e.g. Display P3) for internal displays that support it. // If false, wide color modes are filtered out for all internal displays. bool mSupportsWideColor = false; ui::Dataspace mDefaultCompositionDataspace; ui::Dataspace mWideColorGamutCompositionDataspace; std::unique_ptr mRenderEngine; std::atomic mNumTrustedPresentationListeners = 0; std::unique_ptr mCompositionEngine; CompositionCoveragePerDisplay mCompositionCoverage; // mMaxRenderTargetSize is only set once in init() so it doesn't need to be protected by // any mutex. size_t mMaxRenderTargetSize{1}; const std::string mHwcServiceName; std::unique_ptr mScheduler; scheduler::PresentLatencyTracker mPresentLatencyTracker GUARDED_BY(kMainThreadContext); bool mLumaSampling = true; sp mRegionSamplingThread; sp mFpsReporter; sp mTunnelModeEnabledReporter; ui::DisplayPrimaries mInternalDisplayPrimaries; const float mEmulatedDisplayDensity; const float mInternalDisplayDensity; // Should only be accessed by the main thread. sp mInputFlinger; InputWindowCommands mInputWindowCommands; std::unique_ptr mPowerAdvisor; void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock, kMainThreadContext); void enableHdrSdrRatioOverlay(bool enable) REQUIRES(mStateLock, kMainThreadContext); // Flag used to set override desired display mode from backdoor bool mDebugDisplayModeSetByBackdoor = false; // Tracks the number of maximum queued buffers by layer owner Uid. using BufferStuffingMap = ftl::SmallMap; BufferCountTracker mBufferCountTracker; std::unordered_map> mHdrLayerInfoListeners GUARDED_BY(mStateLock); sp mActivePictureListener GUARDED_BY(mStateLock); bool mHaveNewActivePictureListener GUARDED_BY(mStateLock); ActivePictureUpdater mActivePictureUpdater GUARDED_BY(kMainThreadContext); std::atomic mActiveDisplayTransformHint; // Must only be accessed on the main thread. // TODO (b/259407931): Remove. static ui::Transform::RotationFlags sActiveDisplayRotationFlags; bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) { return hasDisplay( [](const auto& display) { return display.isRefreshRateOverlayEnabled(); }); } bool isHdrSdrRatioOverlayEnabled() const REQUIRES(mStateLock) { return hasDisplay( [](const auto& display) { return display.isHdrSdrRatioOverlayEnabled(); }); } std::function>>()> getLayerSnapshotsForScreenshots( std::optional layerStack, uint32_t uid, std::function snapshotFilterFn); std::function>>()> getLayerSnapshotsForScreenshots( std::optional layerStack, uint32_t uid, std::unordered_set excludeLayerIds); std::function>>()> getLayerSnapshotsForScreenshots( uint32_t rootLayerId, uint32_t uid, std::unordered_set excludeLayerIds, bool childrenOnly, const std::optional& optionalParentCrop); const sp mWindowInfosListenerInvoker; // returns the framerate of the layer with the given sequence ID float getLayerFramerate(nsecs_t now, int32_t id) const { return mScheduler->getLayerFramerate(now, id); } bool mPowerHintSessionEnabled; // Whether a display should be turned on when initialized bool mSkipPowerOnForQuiescent; // used for omitting vsync callbacks to apps when the display is not updatable int mRefreshableDisplays GUARDED_BY(mStateLock) = 0; void incRefreshableDisplays() REQUIRES(mStateLock); void decRefreshableDisplays() REQUIRES(mStateLock); frontend::LayerLifecycleManager mLayerLifecycleManager GUARDED_BY(kMainThreadContext); frontend::LayerHierarchyBuilder mLayerHierarchyBuilder GUARDED_BY(kMainThreadContext); frontend::LayerSnapshotBuilder mLayerSnapshotBuilder GUARDED_BY(kMainThreadContext); mutable std::mutex mCreatedLayersLock; std::vector> mCreatedLayers GUARDED_BY(mCreatedLayersLock); std::vector> mDestroyedHandles GUARDED_BY(mCreatedLayersLock); std::vector> mNewLayers GUARDED_BY(mCreatedLayersLock); std::vector mNewLayerArgs GUARDED_BY(mCreatedLayersLock); // These classes do not store any client state but help with managing transaction callbacks // and stats. std::unordered_map> mLegacyLayers GUARDED_BY(kMainThreadContext); TransactionHandler mTransactionHandler GUARDED_BY(kMainThreadContext); ui::DisplayMap mFrontEndDisplayInfos GUARDED_BY(kMainThreadContext); bool mFrontEndDisplayInfosChanged GUARDED_BY(kMainThreadContext) = false; // WindowInfo ids visible during the last commit. std::unordered_set mVisibleWindowIds GUARDED_BY(kMainThreadContext); // Mirroring // Map of displayid to mirrorRoot ftl::SmallMap, 3> mMirrorMapForDebug; // NotifyExpectedPresentHint enum class NotifyExpectedPresentHintStatus { // Represents that framework can start sending hint if required. Start, // Represents that the hint is already sent. Sent, // Represents that the hint will be scheduled with a new frame. ScheduleOnPresent, // Represents that a hint will be sent instantly by scheduling on the main thread. ScheduleOnTx }; struct NotifyExpectedPresentData { TimePoint lastExpectedPresentTimestamp{}; Fps lastFrameInterval{}; // hintStatus is read and write from multiple threads such as // main thread, EventThread. And is atomic for that reason. std::atomic hintStatus = NotifyExpectedPresentHintStatus::Start; }; std::unordered_map mNotifyExpectedPresentMap; void sendNotifyExpectedPresentHint(PhysicalDisplayId displayId) override REQUIRES(kMainThreadContext); void scheduleNotifyExpectedPresentHint(PhysicalDisplayId displayId, VsyncId vsyncId = VsyncId{ FrameTimelineInfo::INVALID_VSYNC_ID}); void notifyExpectedPresentIfRequired(PhysicalDisplayId, Period vsyncPeriod, TimePoint expectedPresentTime, Fps frameInterval, std::optional timeoutOpt); void sfdo_enableRefreshRateOverlay(bool active); void sfdo_setDebugFlash(int delay); void sfdo_scheduleComposite(); void sfdo_scheduleCommit(); void sfdo_forceClientComposition(bool enabled); }; class SurfaceComposerAIDL : public gui::BnSurfaceComposer { public: explicit SurfaceComposerAIDL(sp sf) : mFlinger(std::move(sf)) {} binder::Status bootFinished() override; binder::Status createDisplayEventConnection( VsyncSource vsyncSource, EventRegistration eventRegistration, const sp& layerHandle, sp* outConnection) override; binder::Status createConnection(sp* outClient) override; binder::Status createVirtualDisplay(const std::string& displayName, bool isSecure, const std::string& uniqueId, float requestedRefreshRate, sp* outDisplay) override; binder::Status destroyVirtualDisplay(const sp& displayToken) override; binder::Status getPhysicalDisplayIds(std::vector* outDisplayIds) override; binder::Status getPhysicalDisplayToken(int64_t displayId, sp* outDisplay) override; binder::Status setPowerMode(const sp& display, int mode) override; binder::Status getSupportedFrameTimestamps(std::vector* outSupported) override; binder::Status getDisplayStats(const sp& display, gui::DisplayStatInfo* outStatInfo) override; binder::Status getDisplayState(const sp& display, gui::DisplayState* outState) override; binder::Status getStaticDisplayInfo(int64_t displayId, gui::StaticDisplayInfo* outInfo) override; binder::Status getDynamicDisplayInfoFromId(int64_t displayId, gui::DynamicDisplayInfo* outInfo) override; binder::Status getDynamicDisplayInfoFromToken(const sp& display, gui::DynamicDisplayInfo* outInfo) override; binder::Status getDisplayNativePrimaries(const sp& display, gui::DisplayPrimaries* outPrimaries) override; binder::Status setActiveColorMode(const sp& display, int colorMode) override; binder::Status setBootDisplayMode(const sp& display, int displayModeId) override; binder::Status clearBootDisplayMode(const sp& display) override; binder::Status getBootDisplayModeSupport(bool* outMode) override; binder::Status getOverlaySupport(gui::OverlayProperties* outProperties) override; binder::Status getHdrConversionCapabilities( std::vector*) override; binder::Status setHdrConversionStrategy(const gui::HdrConversionStrategy& hdrConversionStrategy, int32_t*) override; binder::Status getHdrOutputConversionSupport(bool* outSupport) override; binder::Status setAutoLowLatencyMode(const sp& display, bool on) override; binder::Status setGameContentType(const sp& display, bool on) override; binder::Status getMaxLayerPictureProfiles(const sp& display, int32_t* outMaxProfiles) override; binder::Status captureDisplay(const DisplayCaptureArgs&, const sp&) override; binder::Status captureDisplayById(int64_t, const CaptureArgs&, const sp&) override; binder::Status captureLayers(const LayerCaptureArgs&, const sp&) override; binder::Status captureLayersSync(const LayerCaptureArgs&, ScreenCaptureResults* results); // TODO(b/239076119): Remove deprecated AIDL. [[deprecated]] binder::Status clearAnimationFrameStats() override { return binder::Status::ok(); } [[deprecated]] binder::Status getAnimationFrameStats(gui::FrameStats*) override { return binder::Status::ok(); } binder::Status overrideHdrTypes(const sp& display, const std::vector& hdrTypes) override; binder::Status onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) override; binder::Status getCompositionPreference(gui::CompositionPreference* outPref) override; binder::Status getDisplayedContentSamplingAttributes( const sp& display, gui::ContentSamplingAttributes* outAttrs) override; binder::Status setDisplayContentSamplingEnabled(const sp& display, bool enable, int8_t componentMask, int64_t maxFrames) override; binder::Status getDisplayedContentSample(const sp& display, int64_t maxFrames, int64_t timestamp, gui::DisplayedFrameStats* outStats) override; binder::Status getProtectedContentSupport(bool* outSupporte) override; binder::Status isWideColorDisplay(const sp& token, bool* outIsWideColorDisplay) override; binder::Status addRegionSamplingListener( const gui::ARect& samplingArea, const sp& stopLayerHandle, const sp& listener) override; binder::Status removeRegionSamplingListener( const sp& listener) override; binder::Status addFpsListener(int32_t taskId, const sp& listener) override; binder::Status removeFpsListener(const sp& listener) override; binder::Status addTunnelModeEnabledListener( const sp& listener) override; binder::Status removeTunnelModeEnabledListener( const sp& listener) override; binder::Status setDesiredDisplayModeSpecs(const sp& displayToken, const gui::DisplayModeSpecs&) override; binder::Status getDesiredDisplayModeSpecs(const sp& displayToken, gui::DisplayModeSpecs* outSpecs) override; binder::Status getDisplayBrightnessSupport(const sp& displayToken, bool* outSupport) override; binder::Status setDisplayBrightness(const sp& displayToken, const gui::DisplayBrightness& brightness) override; binder::Status addHdrLayerInfoListener(const sp& displayToken, const sp& listener) override; binder::Status removeHdrLayerInfoListener( const sp& displayToken, const sp& listener) override; binder::Status notifyPowerBoost(int boostId) override; binder::Status setGlobalShadowSettings(const gui::Color& ambientColor, const gui::Color& spotColor, float lightPosY, float lightPosZ, float lightRadius) override; binder::Status getDisplayDecorationSupport( const sp& displayToken, std::optional* outSupport) override; binder::Status setGameModeFrameRateOverride(int32_t uid, float frameRate) override; binder::Status setGameDefaultFrameRateOverride(int32_t uid, float frameRate) override; binder::Status enableRefreshRateOverlay(bool active) override; binder::Status setDebugFlash(int delay) override; binder::Status scheduleComposite() override; binder::Status scheduleCommit() override; binder::Status forceClientComposition(bool enabled) override; binder::Status updateSmallAreaDetection(const std::vector& appIds, const std::vector& thresholds) override; binder::Status setSmallAreaDetectionThreshold(int32_t appId, float threshold) override; binder::Status getGpuContextPriority(int32_t* outPriority) override; binder::Status getMaxAcquiredBufferCount(int32_t* buffers) override; binder::Status addWindowInfosListener(const sp& windowInfosListener, gui::WindowInfosListenerInfo* outInfo) override; binder::Status removeWindowInfosListener( const sp& windowInfosListener) override; binder::Status getStalledTransactionInfo( int pid, std::optional* outInfo) override; binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override; binder::Status notifyShutdown() override; binder::Status addJankListener(const sp& layer, const sp& listener) override; binder::Status flushJankData(int32_t layerId) override; binder::Status removeJankListener(int32_t layerId, const sp& listener, int64_t afterVsync) override; binder::Status setActivePictureListener(const sp& listener); binder::Status clearActivePictureListener(); private: static const constexpr bool kUsePermissionCache = true; status_t checkAccessPermission(bool usePermissionCache = kUsePermissionCache); status_t checkControlDisplayBrightnessPermission(); status_t checkReadFrameBufferPermission(); status_t checkObservePictureProfilesPermission(); static void getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo& info, gui::DynamicDisplayInfo*& outInfo); private: const sp mFlinger; }; } // namespace android