/* * 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 "Display/DisplayMap.h" #include "Display/PhysicalDisplay.h" #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayHardware/PowerAdvisor.h" #include "DisplayIdGenerator.h" #include "Effects/Daltonizer.h" #include "FlagManager.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 "Scheduler/ISchedulerCallback.h" #include "Scheduler/RefreshRateSelector.h" #include "Scheduler/RefreshRateStats.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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Client.h" #ifdef MTK_SF_GUI_DEBUG_SUPPORT #include "mediatek/LayerDebug.h" #endif using namespace android::surfaceflinger; #ifdef MTK_COMPOSER_EXT namespace ComposerExt { class ClientInterface; } #endif 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; #if ((defined MTK_SF_CPU_POLICY) || (defined MTK_SF_CPU_POLICY_FOR_LEGACY)) class SfCpuPolicyInterface; #endif #ifdef MTK_SF_MSYNC class MSyncSfApi; class MSyncTester; #endif 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, }; using DisplayColorSetting = compositionengine::OutputColorSetting; class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ICompositor, private scheduler::ISchedulerCallback { 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 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; // Indicate if device wants color management on its display. static const constexpr bool useColorManagement = true; 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); // 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; // Obtains a name from the texture pool, or, if the pool is empty, posts a // synchronous message to the main thread to obtain one on the fly uint32_t getNewTexture(); // utility function to delete a texture on the main thread void deleteTextureAsync(uint32_t texture); renderengine::RenderEngine& getRenderEngine() const; void onLayerFirstRef(Layer*); void onLayerDestroyed(Layer*); void onLayerUpdate(); void removeHierarchyFromOffscreenLayers(Layer* layer); void removeFromOffscreenLayers(Layer* layer); // 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(BBinder* handle, sp& layer, uint32_t layerId); std::vector mLayerMirrorRoots; 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(); FloatRect getMaxDisplayBounds(); // 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; // 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 LayerTracing; 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 RenderAreaFuture = ftl::Future>; using DumpArgs = Vector; using Dumper = std::function; class State { public: explicit State(LayerVector::StateSet set) : stateSet(set), layersSortedByZ(set) {} State& operator=(const State& other) { // We explicitly don't copy stateSet so that, e.g., mDrawingState // always uses the Drawing StateSet. layersSortedByZ = other.layersSortedByZ; displays = other.displays; colorMatrixChanged = other.colorMatrixChanged; if (colorMatrixChanged) { colorMatrix = other.colorMatrix; } globalShadowSettings = other.globalShadowSettings; return *this; } const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid; LayerVector layersSortedByZ; // 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; renderengine::ShadowSettings globalShadowSettings; void traverse(const LayerVector::Visitor& visitor) const; void traverseInZOrder(const LayerVector::Visitor& visitor) const; void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const; }; // 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(BBinder* layerHandle) { std::lock_guard lock(mLock); auto it = mCounterByLayerHandle.find(layerHandle); if (it != mCounterByLayerHandle.end()) { auto [name, pendingBuffers] = it->second; int32_t count = ++(*pendingBuffers); ATRACE_INT(name.c_str(), count); } else { ALOGW("Handle not found! %p", layerHandle); } } void add(BBinder* layerHandle, const std::string& name, std::atomic* counter) { std::lock_guard lock(mLock); mCounterByLayerHandle[layerHandle] = std::make_pair(name, counter); } void remove(BBinder* layerHandle) { std::lock_guard lock(mLock); mCounterByLayerHandle.erase(layerHandle); } #ifdef MTK_SF_MSYNC int getBufferCount(BBinder* layerHandle) { std::lock_guard lock(mLock); auto it = mCounterByLayerHandle.find(layerHandle); if (it != mCounterByLayerHandle.end()) { auto [name, pendingBuffers] = it->second; //ATRACE_NAME("Msync2: getBufferCount"); return *pendingBuffers; } else { ALOGW("Handle not found! %p", layerHandle); } return 0; } #endif #ifdef MTK_SF_DEBUG_SUPPORT void track(Layer* layer, const std::string& where) { std::lock_guard lock(mLock); mWhereByLayer[layer] = where; } void unTrack(Layer* layer); size_t getLayerSize() { std::lock_guard lock(mLock); return mWhereByLayer.size(); } size_t getHandleSize() { std::lock_guard lock(mLock); return mCounterByLayerHandle.size(); } void dumpLayers(); void dumpHandles() { std::lock_guard lock(mLock); ALOGE("Dumping mCounterByLayerHandle(%zu):", mCounterByLayerHandle.size()); for (auto it = mCounterByLayerHandle.begin(); it != mCounterByLayerHandle.end(); it++) { auto [name, _] = it->second; ALOGE("HandleTracker: %s", name.c_str()); } } bool find(const std::string& layerName) { std::lock_guard lock(mLock); for (auto it = mCounterByLayerHandle.begin(); it != mCounterByLayerHandle.end(); it++) { auto [name, _] = it->second; if (name.find(layerName) != std::string::npos) { return true; } } return false; } #endif private: std::mutex mLock; std::unordered_map*>> mCounterByLayerHandle GUARDED_BY(mLock); #ifdef MTK_SF_DEBUG_SUPPORT std::unordered_map mWhereByLayer GUARDED_BY(mLock); #endif }; enum class BootStage { BOOTLOADER, BOOTANIMATION, FINISHED, }; template >* = nullptr> static Dumper dumper(F&& dump) { using namespace std::placeholders; return std::bind(std::forward(dump), _3); } template >* = nullptr> Dumper dumper(F dump) { using namespace std::placeholders; return std::bind(dump, this, _3); } template Dumper argsDumper(F dump) { using namespace std::placeholders; return std::bind(dump, this, _1, _3); } template Dumper protoDumper(F dump) { using namespace std::placeholders; return std::bind(dump, this, _1, _2, _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; // Implements IBinder. 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); } bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true) EXCLUDES(mStateLock); // Implements ISurfaceComposer sp createDisplay(const String8& displayName, bool secure, float requestedRefreshRate = 0.0f); void destroyDisplay(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(); virtual status_t getSupportedFrameTimestamps(std::vector* outSupported) const; sp createDisplayEventConnection( gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, EventRegistrationFlags eventRegistration = {}, const sp& layerHandle = nullptr); status_t captureDisplay(const DisplayCaptureArgs&, const sp&); status_t captureDisplay(DisplayId, const sp&); status_t 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); 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 getLayerDebugInfo(std::vector* outLayers); status_t getColorManagement(bool* outGetColorManagement) const; 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 setOverrideFrameRate(uid_t uid, float frameRate); int getGpuContextPriority(); status_t getMaxAcquiredBufferCount(int* buffers) const; status_t addWindowInfosListener(const sp& windowInfosListener, gui::WindowInfosListenerInfo* outResult); status_t removeWindowInfosListener( const sp& windowInfosListener) const; // Implements IBinder::DeathRecipient. void binderDied(const wp& who) override; // HWC2::ComposerCallback overrides: void onComposerHalVsync(hal::HWDisplayId, nsecs_t timestamp, std::optional) override; void onComposerHalHotplug(hal::HWDisplayId, hal::Connection) 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; // ICompositor overrides: void configure() override; bool commit(TimePoint frameTime, VsyncId, TimePoint expectedVsyncTime) override; void composite(TimePoint frameTime, VsyncId) override; void sample() override; // ISchedulerCallback overrides: // Toggles hardware VSYNC by calling into HWC. // TODO(b/241286146): Rename for self-explanatory API. void setVsyncEnabled(PhysicalDisplayId, bool) override; void requestDisplayModes(std::vector) override; void kernelTimerChanged(bool expired) override; void triggerOnFrameRateOverridesChanged() override; // Toggles the kernel idle timer on or off depending the policy decisions around refresh rates. void toggleKernelIdleTimer() REQUIRES(mStateLock); 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(DisplayId) REQUIRES(mStateLock); // Updates the kernel idle timer either through HWC or through sysprop // depending on which controller is provided void updateKernelIdleTimer(std::chrono::milliseconds timeoutMs, KernelIdleTimerController, PhysicalDisplayId) REQUIRES(mStateLock); // Keeps track of whether the kernel idle timer is currently enabled, so we don't have to // make calls to sys prop each time. bool mKernelIdleTimerEnabled = false; // 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; void setDesiredActiveMode(display::DisplayModeRequest&&, bool force = false) REQUIRES(mStateLock); status_t setActiveModeFromBackdoor(const sp&, DisplayModeId); // Sets the active mode and a new refresh rate in SF. void updateInternalStateWithChangedMode() REQUIRES(mStateLock, kMainThreadContext); // Calls to setActiveMode on the main thread if there is a pending mode change // that needs to be applied. void setActiveModeInHwcIfNeeded() REQUIRES(mStateLock, kMainThreadContext); void clearDesiredActiveModeState(const sp&) REQUIRES(mStateLock); // Called when active mode is no longer is progress void desiredActiveModeChangeDone(const sp&) REQUIRES(mStateLock); // 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&, bool force = false) REQUIRES(mStateLock, kMainThreadContext); void commitTransactions() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock, kMainThreadContext); void doCommitTransactions() REQUIRES(mStateLock); // Returns whether a new buffer has been latched. bool latchBuffers(); void updateLayerGeometry(); void updateLayerMetadataSnapshot(); std::vector> moveSnapshotsToCompositionArgs( compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly, int64_t vsyncId); void moveSnapshotsFromCompositionArgs(compositionengine::CompositionRefreshArgs& refreshArgs, std::vector>& layers); bool updateLayerSnapshotsLegacy(VsyncId vsyncId, frontend::Update& update, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); bool updateLayerSnapshots(VsyncId vsyncId, frontend::Update& update, bool transactionsFlushed, bool& out) REQUIRES(kMainThreadContext); void updateLayerHistory(const frontend::LayerSnapshot& snapshot); frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext); void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector& outWindowInfos, std::vector& outDisplayInfos); void commitInputWindowCommands() REQUIRES(mStateLock); void updateCursorAsync(); void initScheduler(const sp&) REQUIRES(kMainThreadContext, mStateLock); void resetPhaseConfiguration(Fps) REQUIRES(mStateLock, kMainThreadContext); void updatePhaseConfiguration(Fps) REQUIRES(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); // Flush pending transactions that were presented after desiredPresentTime. // For test only bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext); bool applyTransactions(std::vector&, VsyncId) REQUIRES(kMainThreadContext); bool applyAndCommitDisplayTransactionStates(std::vector& transactions) REQUIRES(kMainThreadContext); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded(); void addTransactionReadyFilters(); TransactionHandler::TransactionReadiness transactionReadyTimelineCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); TransactionHandler::TransactionReadiness transactionReadyBufferCheck( const TransactionHandler::TransactionFlushState& flushState) REQUIRES(kMainThreadContext); uint32_t setClientStateLocked(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock); 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); void commitOffscreenLayers(); static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const sp& layer, const layer_state_t&, size_t numStates, bool firstTransaction) const; bool applyTransactionsLocked(std::vector& transactions, VsyncId) REQUIRES(mStateLock); 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); void markLayerPendingRemovalLocked(const sp& layer) REQUIRES(mStateLock); // add a layer to SurfaceFlinger status_t addClientLayer(LayerCreationArgs& args, const sp& handle, const sp& layer, const wp& parentLayer, uint32_t* outTransformHint); // Traverse through all the layers and compute and cache its bounds. void computeLayerBounds(); // Boot animation, on/off animations and screen capture void startBootAnim(); ftl::SharedFuture captureScreenCommon(RenderAreaFuture, GetLayerSnapshotsFunction, ui::Size bufferSize, ui::PixelFormat, bool allowProtected, bool grayscale, const sp&); ftl::SharedFuture captureScreenCommon( RenderAreaFuture, GetLayerSnapshotsFunction, const std::shared_ptr&, bool regionSampling, bool grayscale, const sp&); ftl::SharedFuture renderScreenImpl( std::shared_ptr, GetLayerSnapshotsFunction, const std::shared_ptr&, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock) REQUIRES(kMainThreadContext); #ifdef MTK_AOSP_DISPLAY_BUGFIX ftl::SharedFuture captureScreenLayers( RenderAreaFuture renderAreaFuture, GetLayerSnapshotsFunction getLayerSnapshots, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool regionSampling, bool grayscale, bool canCaptureBlackoutContent, const sp& captureListener); ftl::SharedFuture renderScreenLayersImpl( std::shared_ptr renderArea, GetLayerSnapshotsFunction getLayerSnapshots, ui::Size bufferSize, ui::PixelFormat reqPixelFormat, bool allowProtected, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) EXCLUDES(mStateLock) REQUIRES(kMainThreadContext); #endif // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a // matching ownerUid void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid, std::unordered_set excludeLayerIds, const LayerVector::Visitor&); void readPersistentProperties(); uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const; /* * Display and layer stack management */ // Called during boot, and restart after system_server death. 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; }); } // Returns the primary display or (for foldables) the active display, assuming that the inner // and outer displays have mutually exclusive power states. sp getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) { return const_cast(this)->getDefaultDisplayDeviceLocked(); } sp getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) { if (const auto display = getDisplayDeviceLocked(mActiveDisplayId)) { return display; } // The active display is outdated, so fall back to the primary display. mActiveDisplayId = getPrimaryDisplayIdLocked(); return getDisplayDeviceLocked(mActiveDisplayId); } sp getDefaultDisplayDevice() const EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return getDefaultDisplayDeviceLocked(); } using DisplayDeviceAndSnapshot = std::pair, display::PhysicalDisplay::SnapshotRef>; // 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) { 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 postComposition(nsecs_t callTime) 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 a string describing the hotplug, or nullptr if it was rejected. const char* processHotplug(PhysicalDisplayId, hal::HWDisplayId, bool connected, DisplayIdentificationInfo&&) REQUIRES(mStateLock) REQUIRES(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); void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); /* * VSYNC */ nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock); void setHWCVsyncEnabled(PhysicalDisplayId id, bool enabled) { hal::Vsync halState = enabled ? hal::Vsync::ENABLE : hal::Vsync::DISABLE; getHwComposer().setVsyncEnabled(id, halState); } using FenceTimePtr = std::shared_ptr; bool wouldPresentEarly(TimePoint frameTime, Period) const REQUIRES(kMainThreadContext); const FenceTimePtr& getPreviousPresentFence(TimePoint frameTime, Period) const REQUIRES(kMainThreadContext); // Blocks the thread waiting for up to graceTimeMs in case the fence is about to signal. static bool isFencePending(const FenceTimePtr&, int graceTimeMs); // Calculates the expected present time for this frame. For negative offsets, performs a // correction using the predicted vsync for the next frame instead. TimePoint calculateExpectedPresentTime(TimePoint frameTime) const; /* * 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) REQUIRES(mStateLock); void releaseVirtualDisplay(VirtualDisplayId); void onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr, const DisplayDevice& activeDisplay) REQUIRES(mStateLock, kMainThreadContext); void onActiveDisplaySizeChanged(const DisplayDevice&); /* * Debugging & dumpsys */ void dumpAllLocked(const DumpArgs& args, const std::string& compositionLayers, std::string& result) const REQUIRES(mStateLock); void dumpHwcLayersMinidumpLocked(std::string& result) const REQUIRES(mStateLock); void appendSfConfigString(std::string& result) const; void listLayersLocked(std::string& result) const; void dumpStatsLocked(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); void clearStatsLocked(const DumpArgs& args, std::string& result); 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); LayersProto dumpDrawingStateProto(uint32_t traceFlags) const; void dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t traceFlags = LayerTracing::TRACE_ALL) const; google::protobuf::RepeatedPtrField dumpDisplayProto() const; void addToLayerTracing(bool visibleRegionDirty, int64_t time, int64_t vsyncId) REQUIRES(kMainThreadContext); // Dumps state from HW Composer void dumpHwc(std::string& result) const; LayersProto dumpProtoFromMainThread(uint32_t traceFlags = LayerTracing::TRACE_ALL) EXCLUDES(mStateLock); void dumpOffscreenLayers(std::string& result) 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; sp mStartPropertySetThread; surfaceflinger::Factory& mFactory; pid_t mPid; std::future 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; SortedVector> mLayersPendingRemoval; // 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; size_t mMaxGraphicBufferProducerListSize = MAX_LAYERS; // If there are more GraphicBufferProducers tracked by SurfaceFlinger than // this threshold, then begin logging. size_t mGraphicBufferProducerListSizeLogThreshold = static_cast(0.95 * static_cast(MAX_LAYERS)); // 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; #ifdef MTK_AOSP_DISPLAY_BUGFIX std::atomic_bool mGeometryDirtyLayerCapture = false; mutable Mutex mReleaseVirtualDisplayLock; #endif #ifdef MTK_SF_HWC_REPAINT_SUPPORT std::atomic mRepaintByHWComposer = -1; int mHWCRepaintFmt = 0; #endif // constant members (no synchronization needed for access) const nsecs_t mBootTime = systemTime(); bool mIsUserBuild = true; // Can only accessed from the main thread, these members // don't need synchronization State mDrawingState{LayerVector::StateSet::Drawing}; bool mVisibleRegionsDirty = false; bool mHdrLayerInfoChanged = false; // 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 mForceTransactionDisplayChange = false; // Set if LayerMetadata has changed since the last LayerMetadata snapshot. bool mLayerMetadataSnapshotNeeded = false; // TODO(b/238781169) validate these on composition // Tracks layers that have pending frames which are candidates for being // latched. std::unordered_set, SpHash> mLayersWithQueuedFrames; std::unordered_set, SpHash> mLayersWithBuffersRemoved; // Tracks layers that need to update a display's dirty region. std::vector> mLayersPendingRefresh; // 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; }; 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. display::DisplayMap, const sp> mDisplays GUARDED_BY(mStateLock); display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock); // The inner or outer display for foldables, assuming they have mutually exclusive power states. // Atomic because writes from onActiveDisplayChangedLocked are not always under mStateLock, but // reads from ISchedulerCallback::requestDisplayModes may happen concurrently. std::atomic mActiveDisplayId GUARDED_BY(mStateLock); 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; bool mLayerTracingEnabled = false; std::optional mTransactionTracing; std::atomic mTracingEnabledChanged = false; 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; std::atomic mFrameMissedCount = 0; std::atomic mHwcFrameMissedCount = 0; std::atomic mGpuFrameMissedCount = 0; TransactionCallbackInvoker mTransactionCallbackInvoker; // We maintain a pool of pre-generated texture names to hand out to avoid // layer creation needing to run on the main thread (which it would // otherwise need to do to access RenderEngine). std::mutex mTexturePoolMutex; uint32_t mTexturePoolSize = 0; std::vector mTexturePool; 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; ui::Dataspace mColorSpaceAgnosticDataspace; float mDimmingRatio = -1.f; std::unique_ptr mRenderEngine; std::atomic mNumTrustedPresentationListeners = 0; std::unique_ptr mCompositionEngine; CompositionCoverageFlags 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; /* * Scheduler */ std::unique_ptr mScheduler; scheduler::ConnectionHandle mAppConnectionHandle; scheduler::ConnectionHandle mSfConnectionHandle; // Stores phase offsets configured per refresh rate. std::unique_ptr mVsyncConfiguration; std::unique_ptr mRefreshRateStats; scheduler::PresentLatencyTracker mPresentLatencyTracker GUARDED_BY(kMainThreadContext); struct FenceWithFenceTime { sp fence = Fence::NO_FENCE; FenceTimePtr fenceTime = FenceTime::NO_FENCE; }; #ifdef MTK_SF_EXTEND_BACKPRESSURE // size should be longest sf-duration / shortest vsync period and round up std::array mPreviousPresentFences; // currently consier 166hz. #else std::array mPreviousPresentFences; #endif TimePoint mScheduledPresentTime GUARDED_BY(kMainThreadContext); TimePoint mExpectedPresentTime GUARDED_BY(kMainThreadContext); // below flags are set by main thread only bool mSetActiveModePending = false; 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); // Flag used to set override desired display mode from backdoor bool mDebugDisplayModeSetByBackdoor = false; // A set of layers that have no parent so they are not drawn on screen. // Should only be accessed by the main thread. // The Layer pointer is removed from the set when the destructor is called so there shouldn't // be any issues with a raw pointer referencing an invalid object. std::unordered_set mOffscreenLayers; #if ((defined MTK_SF_CPU_POLICY) || (defined MTK_SF_CPU_POLICY_FOR_LEGACY)) bool mForceFPSGOForground = false; bool mForceFPSGOEnable = false; int mForceFPSGOTimeout = 0; // ms nsecs_t mForceFPSGOTime = 0; mutable std::mutex mForceFPSGOLock; SfCpuPolicyInterface *mSfCpuPolicy = nullptr; #endif BufferCountTracker mBufferCountTracker; std::unordered_map> mHdrLayerInfoListeners GUARDED_BY(mStateLock); mutable std::mutex mCreatedLayersLock; // A temporay pool that store the created layers and will be added to current state in main // thread. std::vector mCreatedLayers GUARDED_BY(mCreatedLayersLock); bool commitCreatedLayers(VsyncId, std::vector& createdLayers); void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock); mutable std::mutex mMirrorDisplayLock; struct MirrorDisplayState { MirrorDisplayState(ui::LayerStack layerStack, sp& rootHandle, const sp& client) : layerStack(layerStack), rootHandle(rootHandle), client(client) {} ui::LayerStack layerStack; sp rootHandle; const sp client; }; std::vector mMirrorDisplays GUARDED_BY(mMirrorDisplayLock); bool commitMirrorDisplays(VsyncId); 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(); }); } 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; FlagManager mFlagManager; // 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; bool mLayerLifecycleManagerEnabled = false; bool mLegacyFrontEndEnabled = true; frontend::LayerLifecycleManager mLayerLifecycleManager; frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}}; frontend::LayerSnapshotBuilder mLayerSnapshotBuilder; std::vector mDestroyedHandles; std::vector> mNewLayers; std::vector mNewLayerArgs; // These classes do not store any client state but help with managing transaction callbacks // and stats. std::unordered_map> mLegacyLayers; TransactionHandler mTransactionHandler; display::DisplayMap mFrontEndDisplayInfos; bool mFrontEndDisplayInfosChanged = false; // WindowInfo ids visible during the last commit. std::unordered_set mVisibleWindowIds; #ifdef MTK_COMPOSER_EXT private: void initMtkComposerExt(); ::ComposerExt::ClientInterface* mMtkComposerExtIntf = nullptr; #endif #if ((defined MTK_SF_CPU_POLICY) || (defined MTK_SF_CPU_POLICY_FOR_LEGACY)) public: bool mUserHeavyLoading = false; void notifyVpLpEnable(bool enable); void notifyLayerConnect(const void * token, const std::string& name); void notifyLayerDisconnect(const void * token); void notifyLayerSetBuffer(const void * token, const sp& buffer); #endif #ifdef MTK_COMPOSER_EXT #if ((defined MTK_SF_CPU_POLICY) || (defined MTK_SF_CPU_POLICY_FOR_LEGACY)) public: void notifyHwcHwbinderTid(const int& tid); #endif #endif #ifdef MTK_SF_DEBUG_SUPPORT private: void mtkDump(std::string& result); void mtkDumpLayerDebug(std::string& result) const REQUIRES(mStateLock); static status_t getProcessName(int pid, std::string& name); bool mtkCheckTransactCodeCredentials(uint32_t code); bool mtkIsTransact(uint32_t code); status_t mtkOnTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); #endif #ifdef MTK_SF_GUI_DEBUG_SUPPORT bool mIsDumpLayers = false; void fastMtkDumpLayerDebug(std::vector& layerInfo) const REQUIRES(mStateLock); #endif #ifdef MTK_AOSP_DISPLAY_BUGFIX bool mIsBootDisplayModeSupport; #endif #ifdef MTK_SF_MSYNC_3 private: struct { float frameRate = 0.0f; int8_t compatibility; int8_t strategy; int64_t vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID; float ctrlFrameRate = 0.0f; std::string layerName; std::string ctrlLayerName; } mPendingFrameRateChanged; size_t mMsync3Shift = 0; bool mIsTargetNext2Vsync = false; public: void changeToForeground() override; #endif #ifdef MTK_SF_HINT_LOW_POWER public: void hintLowPower(bool enabled) override; bool setPELT32(bool enabled); #endif #ifdef MTK_SF_HINT_DISPLAY_INFO private: int32_t mHintFps = 0; void hintDisplayInfo(const int& policy, const bool& enable) REQUIRES(mStateLock); #endif #ifdef MTK_VDS_HDCP private: void setNextDisplayUsage(bool isWFD, bool isSecure); #endif #ifdef MTK_SF_UPDATE_DISPLAY_CAP private: bool updateDisplayCapability() REQUIRES(mStateLock);; #endif #ifdef MTK_SF_MSYNC private: friend class MSyncSfApi; friend class MSyncTester; std::shared_ptr mMSyncSfApi = nullptr; public: bool isMsyncOn() const; #endif #ifdef MTK_SF_NOTIFY_EXPECTED_PRESENT_TIME #ifdef MTK_COMPOSER_EXT private: int mIsCtIdSupported = -1; #endif #endif #ifdef MTK_SF_DEBUG_SUPPORT public: BufferCountTracker mLayerTracker; private: BufferCountTracker mMirrorDisplayHandleTracker; #endif #ifdef MTK_SF_MBRAIN_FPS_SUPPORT public: int64_t getDisplayFrameCount() const; private: int64_t mDisplayFrameCount; #endif }; class SurfaceComposerAIDL : public gui::BnSurfaceComposer { public: 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 createDisplay(const std::string& displayName, bool secure, float requestedRefreshRate, sp* outDisplay) override; binder::Status destroyDisplay(const sp& display) 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 captureDisplay(const DisplayCaptureArgs&, const sp&) override; binder::Status captureDisplayById(int64_t, const sp&) override; binder::Status captureLayers(const LayerCaptureArgs&, const sp&) override; // 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 getLayerDebugInfo(std::vector* outLayers) override; binder::Status getColorManagement(bool* outGetColorManagement) 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 setOverrideFrameRate(int32_t uid, float frameRate) 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; private: static const constexpr bool kUsePermissionCache = true; status_t checkAccessPermission(bool usePermissionCache = kUsePermissionCache); status_t checkControlDisplayBrightnessPermission(); status_t checkReadFrameBufferPermission(); static void getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo& info, gui::DynamicDisplayInfo*& outInfo); private: sp mFlinger; }; } // namespace android