/* * 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 "ClientCache.h" #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayHardware/PowerAdvisor.h" #include "DisplayIdGenerator.h" #include "Effects/Daltonizer.h" #include "FlagManager.h" #include "FrameTracker.h" #include "LayerVector.h" #include "Scheduler/RefreshRateConfigs.h" #include "Scheduler/RefreshRateStats.h" #include "Scheduler/Scheduler.h" #include "Scheduler/VsyncModulator.h" #include "SurfaceFlingerFactory.h" #include "ThreadContext.h" #include "TracedOrdinal.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 #define RK_FPS (1) using namespace android::surfaceflinger; namespace android { class Client; 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 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, eTransactionMask = 0x1f, }; // 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). AutoSingleLayer, // All buffers are latched unsignaled. This behaviour is discouraged as it // can break sync transactions, stall the display and cause undesired side effects. Always, }; using DisplayColorSetting = compositionengine::OutputColorSetting; struct SurfaceFlingerBE { // protected by mCompositorTimingLock; mutable std::mutex mCompositorTimingLock; CompositorTiming mCompositorTiming; // Only accessed from the main thread. struct CompositePresentTime { nsecs_t composite = -1; std::shared_ptr display = FenceTime::NO_FENCE; }; std::queue mCompositePresentTimes; static const size_t NUM_BUCKETS = 8; // < 1-7, 7+ nsecs_t mFrameBuckets[NUM_BUCKETS] = {}; nsecs_t mTotalTime = 0; std::atomic mLastSwapTime = 0; }; 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"; } // This is the phase offset in nanoseconds of the software vsync event // relative to the vsync event reported by HWComposer. The software vsync // event is when SurfaceFlinger and Choreographer-based applications run each // frame. // // This phase offset allows adjustment of the minimum latency from application // wake-up time (by Choreographer) to the time at which the resulting window // image is displayed. This value may be either positive (after the HW vsync) // or negative (before the HW vsync). Setting it to 0 will result in a lower // latency bound of two vsync periods because the app and SurfaceFlinger // will run just after the HW vsync. Setting it to a positive number will // result in the minimum latency being: // // (2 * VSYNC_PERIOD - (vsyncPhaseOffsetNs % VSYNC_PERIOD)) // // Note that reducing this latency makes it more likely for the applications // to not have their window content image ready in time. When this happens // the latency will end up being an additional vsync period, and animations // will hiccup. Therefore, this latency should be tuned somewhat // conservatively (or at least with awareness of the trade-off being made). static int64_t vsyncPhaseOffsetNs; static int64_t sfVsyncPhaseOffsetNs; // 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 a device has wide color gamut display. This is typically // found on devices with wide color gamut (e.g. Display-P3) display. static bool hasWideColorDisplay; // 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; SurfaceFlingerBE& getBE() { return mBE; } const SurfaceFlingerBE& getBE() const { return mBE; } // 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; bool authenticateSurfaceTextureLocked( const sp& bufferProducer) const; void onLayerFirstRef(Layer*); void onLayerDestroyed(Layer*); void onLayerUpdate(); void removeHierarchyFromOffscreenLayers(Layer* layer); void removeFromOffscreenLayers(Layer* layer); // TODO: Remove atomic if move dtor to main thread CL lands std::atomic mNumClones; TransactionCallbackInvoker& getTransactionCallbackInvoker() { return mTransactionCallbackInvoker; } // Converts from a binder handle to a Layer // Returns nullptr if the handle does not point to an existing layer. // Otherwise, returns a weak reference so that callers off the main-thread // won't accidentally hold onto the last strong reference. wp fromHandle(const sp& handle) const; // If set, disables reusing client composition buffers. This can be set by // debug.sf.disable_client_composition_cache bool mDisableClientCompositionCache = false; void windowInfosReported(); // 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; 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( const BufferData& bufferData, const char* layerName) const; // Returns true if any display matches a `bool(const DisplayDevice&)` predicate. template bool hasDisplay(Predicate p) const REQUIRES(mStateLock) { return static_cast(findDisplay(p)); } #define UNUSED(x) ((void)x) bool exceedsMaxRenderTargetSize(uint32_t width, uint32_t height) const { #if MALI_PRODUCT_ID_450 UNUSED(width); UNUSED(height); return false; #else return width > mMaxRenderTargetSize || height > mMaxRenderTargetSize; #endif } private: friend class BufferLayer; friend class BufferQueueLayer; friend class BufferStateLayer; friend class Client; friend class FpsReporter; friend class TunnelModeEnabledReporter; friend class Layer; friend class MonitoredProducer; friend class RefreshRateOverlay; friend class RegionSamplingThread; friend class LayerRenderArea; friend class LayerTracing; // For unit tests friend class TestableSurfaceFlinger; friend class TransactionApplicationTest; friend class TunnelModeEnabledReporterTest; using VsyncModulator = scheduler::VsyncModulator; using TransactionSchedule = scheduler::TransactionSchedule; using TraverseLayersFunction = std::function; using RenderAreaFuture = ftl::Future>; using DumpArgs = Vector; using Dumper = std::function; // This value is specified in number of frames. Log frame stats at most // every half hour. enum { LOG_FRAME_STATS_PERIOD = 30*60*60 }; 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; DefaultKeyedVector< wp, DisplayDeviceState> displays; 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); } private: std::mutex mLock; std::unordered_map*>> mCounterByLayerHandle GUARDED_BY(mLock); }; using ActiveModeInfo = DisplayDevice::ActiveModeInfo; using KernelIdleTimerController = ::android::scheduler::RefreshRateConfigs::KernelIdleTimerController; enum class BootStage { BOOTLOADER, BOOTANIMATION, FINISHED, }; struct HotplugEvent { hal::HWDisplayId hwcDisplayId; hal::Connection connection = hal::Connection::INVALID; }; 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); } template void modulateVsync(Handler handler, Args... args) { if (const auto config = (*mVsyncModulator.*handler)(args...)) { const auto vsyncPeriod = mScheduler->getVsyncPeriodFromRefreshRateConfigs(); setVsyncConfig(*config, vsyncPeriod); } } static const int MAX_TRACING_MEMORY = 100 * 1024 * 1024; // 100MB // Maximum allowed number of display frames that can be set through backdoor static const int MAX_ALLOWED_DISPLAY_FRAMES = 2048; // 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 createConnection() override; sp createDisplay(const String8& displayName, bool secure); void destroyDisplay(const sp& displayToken); std::vector getPhysicalDisplayIds() const EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return getPhysicalDisplayIdsLocked(); } status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*) const EXCLUDES(mStateLock); sp getPhysicalDisplayToken(PhysicalDisplayId displayId) const; status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector& state, const Vector& displays, uint32_t flags, const sp& applyToken, const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, const std::vector& listenerCallbacks, uint64_t transactionId) override; void bootFinished() override; bool authenticateSurfaceTexture( const sp& bufferProducer) const override; status_t getSupportedFrameTimestamps(std::vector* outSupported) const override; sp createDisplayEventConnection( ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp, ISurfaceComposer::EventRegistrationFlags eventRegistration = {}) override; 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(const sp& displayToken, ui::StaticDisplayInfo*) EXCLUDES(mStateLock) override; status_t getDynamicDisplayInfo(const sp& displayToken, ui::DynamicDisplayInfo*) EXCLUDES(mStateLock) override; status_t getDisplayNativePrimaries(const sp& displayToken, ui::DisplayPrimaries&) override; status_t setActiveColorMode(const sp& displayToken, ui::ColorMode colorMode) override; status_t getBootDisplayModeSupport(bool* outSupport) const; status_t setBootDisplayMode(const sp& displayToken, ui::DisplayModeId id) override; status_t clearBootDisplayMode(const sp& displayToken); void setAutoLowLatencyMode(const sp& displayToken, bool on); void setGameContentType(const sp& displayToken, bool on); void setPowerMode(const sp& displayToken, int mode); status_t clearAnimationFrameStats() override; status_t getAnimationFrameStats(FrameStats* outStats) const override; status_t overrideHdrTypes(const sp& displayToken, const std::vector& hdrTypes) override; status_t onPullAtom(const int32_t atomId, std::string* pulledData, bool* success) override; status_t enableVSyncInjections(bool enable) override; status_t injectVSync(nsecs_t when) override; status_t getLayerDebugInfo(std::vector* outLayers) override; status_t getColorManagement(bool* outGetColorManagement) const override; status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat, ui::Dataspace* outWideColorGamutDataspace, ui::PixelFormat* outWideColorGamutPixelFormat) const override; status_t getDisplayedContentSamplingAttributes(const sp& displayToken, ui::PixelFormat* outFormat, ui::Dataspace* outDataspace, uint8_t* outComponentMask) const override; status_t setDisplayContentSamplingEnabled(const sp& displayToken, bool enable, uint8_t componentMask, uint64_t maxFrames) override; status_t getDisplayedContentSample(const sp& displayToken, uint64_t maxFrames, uint64_t timestamp, DisplayedFrameStats* outStats) const override; status_t getProtectedContentSupport(bool* outSupported) const override; status_t isWideColorDisplay(const sp& displayToken, bool* outIsWideColorDisplay) const; status_t addRegionSamplingListener(const Rect& samplingArea, const sp& stopLayerHandle, const sp& listener) override; status_t removeRegionSamplingListener(const sp& listener) override; status_t addFpsListener(int32_t taskId, const sp& listener) override; status_t removeFpsListener(const sp& listener) override; status_t addTunnelModeEnabledListener( const sp& listener) override; status_t removeTunnelModeEnabledListener( const sp& listener) override; status_t setDesiredDisplayModeSpecs(const sp& displayToken, ui::DisplayModeId displayModeId, bool allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin, float appRequestRefreshRateMax) override; status_t getDesiredDisplayModeSpecs(const sp& displayToken, ui::DisplayModeId* outDefaultMode, bool* outAllowGroupSwitching, float* outPrimaryRefreshRateMin, float* outPrimaryRefreshRateMax, float* outAppRequestRefreshRateMin, float* outAppRequestRefreshRateMax) override; 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) override; status_t getDisplayDecorationSupport( const sp& displayToken, std::optional* outSupport) const override; status_t setFrameRate(const sp& surface, float frameRate, int8_t compatibility, int8_t changeFrameRateStrategy) override; status_t setFrameTimelineInfo(const sp& surface, const FrameTimelineInfo& frameTimelineInfo) override; status_t setOverrideFrameRate(uid_t uid, float frameRate) override; status_t addTransactionTraceListener( const sp& listener) override; int getGPUContextPriority() override; status_t getMaxAcquiredBufferCount(int* buffers) const override; status_t addWindowInfosListener( const sp& windowInfosListener) const override; status_t removeWindowInfosListener( const sp& windowInfosListener) const override; // Implements IBinder::DeathRecipient. void binderDied(const wp& who) override; // HWC2::ComposerCallback overrides: void onComposerHalVsync(hal::HWDisplayId, int64_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; // ICompositor overrides: // Commits transactions for layers and displays. Returns whether any state has been invalidated, // i.e. whether a frame should be composited for each display. bool commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) override; #if RK_FPS //add by rk for fps void debugShowFPS() const; #endif // Composites a frame for each display. CompositionEngine performs GPU and/or HAL composition // via RenderEngine and the Composer HAL, respectively. void composite(nsecs_t frameTime, int64_t vsyncId) override; // Samples the composited frame via RegionSamplingThread. void sample() override; /* * ISchedulerCallback */ // Toggles hardware VSYNC by calling into HWC. void setVsyncEnabled(bool) override; // Sets the desired display mode if allowed by policy. void requestDisplayMode(DisplayModePtr, DisplayModeEvent) override; // Called when kernel idle timer has expired. Used to update the refresh rate overlay. void kernelTimerChanged(bool expired) override; // Called when the frame rate override list changed to trigger an event. void triggerOnFrameRateOverridesChanged() override; // Toggles the kernel idle timer on or off depending the policy decisions around refresh rates. void toggleKernelIdleTimer() REQUIRES(mStateLock); // 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; // Called on the main thread in response to initializeDisplays() void onInitializeDisplays() REQUIRES(mStateLock); // Sets the desired active mode bit. It obtains the lock, and sets mDesiredActiveMode. void setDesiredActiveMode(const ActiveModeInfo& info, bool force = false) REQUIRES(mStateLock); status_t setActiveModeFromBackdoor(const sp& displayToken, int id); // Sets the active mode and a new refresh rate in SF. void updateInternalStateWithChangedMode() REQUIRES(mStateLock); // Calls to setActiveMode on the main thread if there is a pending mode change // that needs to be applied. void setActiveModeInHwcIfNeeded() REQUIRES(mStateLock); 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); // Returns true if the display has a visible HDR layer in its layer stack. bool hasVisibleHdrLayer(const sp& display) REQUIRES(mStateLock); // Sets the desired display mode specs. status_t setDesiredDisplayModeSpecsInternal( const sp& display, const std::optional& policy, bool overridePolicy) EXCLUDES(mStateLock); status_t applyRefreshRateConfigsPolicy(const sp&, bool force = false) REQUIRES(mStateLock); void commitTransactions() EXCLUDES(mStateLock); void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock); void doCommitTransactions() REQUIRES(mStateLock); // Returns whether a new buffer has been latched. bool latchBuffers(); void updateLayerGeometry(); void updateInputFlinger(); void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext); void buildWindowInfos(std::vector& outWindowInfos, std::vector& outDisplayInfos); void commitInputWindowCommands() REQUIRES(mStateLock); void updateCursorAsync(); void initScheduler(const sp& display) REQUIRES(mStateLock); void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock); void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod); /* * Transactions */ bool applyTransactionState(const FrameTimelineInfo& info, Vector& state, Vector& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& uncacheBuffer, const int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, const std::vector& listenerCallbacks, int originPid, int originUid, uint64_t transactionId) REQUIRES(mStateLock); // flush pending transaction that was presented after desiredPresentTime. bool flushTransactionQueues(int64_t vsyncId); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded(); int flushPendingTransactionQueues( std::vector& transactions, std::unordered_map, uint64_t, SpHash>& bufferLayersReadyToPresent, std::unordered_set, SpHash>& applyTokensWithUnsignaledTransactions, bool tryApplyUnsignaled) REQUIRES(mStateLock, mQueueLock); int flushUnsignaledPendingTransactionQueues( std::vector& transactions, std::unordered_map, uint64_t, SpHash>& bufferLayersReadyToPresent, std::unordered_set, SpHash>& applyTokensWithUnsignaledTransactions) REQUIRES(mStateLock, mQueueLock); uint32_t setClientStateLocked(const FrameTimelineInfo&, ComposerState&, int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, uint32_t permissions) 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(); enum class TransactionReadiness { NotReady, NotReadyBarrier, Ready, ReadyUnsignaled, }; TransactionReadiness transactionIsReadyToBeApplied(TransactionState& state, const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime, uid_t originUid, const Vector& states, const std::unordered_map< sp, uint64_t, SpHash>& bufferLayersReadyToPresent, size_t totalTXapplied, bool tryApplyUnsignaled) const REQUIRES(mStateLock); static LatchUnsignaledConfig getLatchUnsignaledConfig(); bool shouldLatchUnsignaled(const sp& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied) const; bool stopTransactionProcessing(const std::unordered_set, SpHash>& applyTokensWithUnsignaledTransactions) const; bool applyTransactions(std::vector& transactions, int64_t vsyncId) REQUIRES(mStateLock); uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock); uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock); bool frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const; /* * Layer management */ status_t createLayer(LayerCreationArgs& args, sp* outHandle, const sp& parentHandle, int32_t* outLayerId, const sp& parentLayer = nullptr, uint32_t* outTransformHint = nullptr); status_t createBufferQueueLayer(LayerCreationArgs& args, PixelFormat& format, sp* outHandle, sp* outGbp, sp* outLayer); status_t createBufferStateLayer(LayerCreationArgs& args, sp* outHandle, sp* outLayer); status_t createEffectLayer(const LayerCreationArgs& args, sp* outHandle, sp* outLayer); status_t createContainerLayer(const LayerCreationArgs& args, sp* outHandle, sp* outLayer); status_t mirrorLayer(const LayerCreationArgs& args, const sp& mirrorFromHandle, sp* outHandle, int32_t* outLayerId); // called when all clients have released all their references to // this layer meaning it is entirely safe to destroy all // resources associated to this layer. void onHandleDestroyed(BBinder* handle, sp& layer); void markLayerPendingRemovalLocked(const sp& layer); // add a layer to SurfaceFlinger status_t addClientLayer(const sp& client, const sp& handle, const sp& lbc, const wp& parentLayer, bool addToRoot, 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, TraverseLayersFunction, ui::Size bufferSize, ui::PixelFormat, bool allowProtected, bool grayscale, const sp&); ftl::SharedFuture captureScreenCommon( RenderAreaFuture, TraverseLayersFunction, const std::shared_ptr&, bool regionSampling, bool grayscale, const sp&); ftl::SharedFuture renderScreenImpl( const RenderArea&, TraverseLayersFunction, const std::shared_ptr&, bool canCaptureBlackoutContent, bool regionSampling, bool grayscale, ScreenCaptureResults&) EXCLUDES(mStateLock); // 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, const LayerVector::Visitor&); void readPersistentProperties(); uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const; /* * Display and layer stack management */ // called when starting, or restarting after system_server death void initializeDisplays(); sp getDisplayDeviceLocked(const wp& displayToken) const REQUIRES(mStateLock) { return const_cast(this)->getDisplayDeviceLocked(displayToken); } sp getDisplayDeviceLocked(const wp& displayToken) REQUIRES(mStateLock) { const sp nullDisplay; return mDisplays.get(displayToken).value_or(std::cref(nullDisplay)); } 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(mActiveDisplayToken)) { return display; } // The active display is outdated, so fall back to the primary display. mActiveDisplayToken.clear(); return getDisplayDeviceLocked(getPrimaryDisplayTokenLocked()); } sp getDefaultDisplayDevice() const EXCLUDES(mStateLock) { Mutex::Autolock lock(mStateLock); return getDefaultDisplayDeviceLocked(); } // 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 sp& layer, const Region& dirty); bool isDisplayActiveLocked(const sp& display) const REQUIRES(mStateLock) { return display->getDisplayToken() == mActiveDisplayToken; } /* * 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(); void getCompositorTiming(CompositorTiming* compositorTiming); void updateCompositorTiming(const DisplayStatInfo& stats, nsecs_t compositeTime, std::shared_ptr& presentFenceTime); void setCompositorTimingSnapped(const DisplayStatInfo& stats, nsecs_t compositeToPresentLatency); void postFrame() REQUIRES(kMainThreadContext); /* * Display management */ std::pair loadDisplayModes(PhysicalDisplayId) const REQUIRES(mStateLock); sp setupNewDisplayDeviceInternal( const wp& displayToken, std::shared_ptr compositionDisplay, const DisplayDeviceState& state, const sp& displaySurface, const sp& producer) REQUIRES(mStateLock); void processDisplayChangesLocked() REQUIRES(mStateLock); void processDisplayRemoved(const wp& displayToken) REQUIRES(mStateLock); void processDisplayChanged(const wp& displayToken, const DisplayDeviceState& currentState, const DisplayDeviceState& drawingState) REQUIRES(mStateLock); void processDisplayHotplugEventsLocked() REQUIRES(mStateLock); void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); /* * VSYNC */ nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock); void setHWCVsyncEnabled(PhysicalDisplayId id, hal::Vsync enabled) { mLastHWCVsyncState = enabled; getHwComposer().setVsyncEnabled(id, enabled); } struct FenceWithFenceTime { sp fence = Fence::NO_FENCE; std::shared_ptr fenceTime = FenceTime::NO_FENCE; }; // Gets the fence for the previous frame. // Must be called on the main thread. FenceWithFenceTime previousFrameFence(); // Whether the previous frame has not yet been presented to the display. // If graceTimeMs is positive, this method waits for at most the provided // grace period before reporting if the frame missed. // Must be called on the main thread. bool previousFramePending(int graceTimeMs = 0); // Returns the previous time that the frame was presented. If the frame has // not been presented yet, then returns Fence::SIGNAL_TIME_PENDING. If there // is no pending frame, then returns Fence::SIGNAL_TIME_INVALID. // Must be called on the main thread. nsecs_t previousFramePresentTime(); // Calculates the expected present time for this frame. For negative offsets, performs a // correction using the predicted vsync for the next frame instead. nsecs_t calculateExpectedPresentTime(DisplayStatInfo) const; /* * Display identification */ sp getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { const sp nullToken; return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken)); } std::optional getPhysicalDisplayIdLocked( const sp& displayToken) const REQUIRES(mStateLock) { for (const auto& [id, token] : mPhysicalDisplayTokens) { if (token == displayToken) { return id; } } return {}; } // 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, ui::LayerStack layerStack) REQUIRES(mStateLock); void releaseVirtualDisplay(VirtualDisplayId); void onActiveDisplayChangedLocked(const sp& activeDisplay) REQUIRES(mStateLock); void onActiveDisplaySizeChanged(const sp& activeDisplay); /* * Debugging & dumpsys */ void dumpAllLocked(const DumpArgs& args, const std::string& compositionLayers, 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() REQUIRES(kMainThreadContext); void dumpVSync(std::string& result) const REQUIRES(mStateLock); void dumpStaticScreenStats(std::string& result) const; 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; void dumpDisplayProto(LayersTraceProto& layersTraceProto) const; // 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 void queueTransaction(TransactionState& state) EXCLUDES(mQueueLock); void waitForSynchronousTransaction(const CountDownLatch& transactionCommittedSignal); void signalSynchronousTransactions(const uint32_t flag); /* * Generic Layer Metadata */ const std::unordered_map& getGenericLayerMetadataKeyMap() const; /* * Misc */ std::vector getDisplayColorModes(const DisplayDevice&) REQUIRES(mStateLock); static int calculateMaxAcquiredBufferCount(Fps refreshRate, std::chrono::nanoseconds presentLatency); int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const; void updateInternalDisplayVsyncLocked(const sp& activeDisplay) REQUIRES(mStateLock); bool isHdrLayer(Layer* layer) const; ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const REQUIRES(mStateLock); sp mStartPropertySetThread; surfaceflinger::Factory& mFactory; pid_t mPid; std::future mRenderEnginePrimeCacheFuture; // access must be protected by mStateLock mutable Mutex mStateLock; State mCurrentState{LayerVector::StateSet::Current}; std::atomic mTransactionFlags = 0; std::vector> mTransactionCommittedSignals; bool mAnimTransactionPending = false; std::atomic mUniqueTransactionId = 1; SortedVector> mLayersPendingRemoval; // global color transform states Daltonizer mDaltonizer; float mGlobalSaturationFactor = 1.0f; mat4 mClientColorMatrix; size_t mMaxGraphicBufferProducerListSize = ISurfaceComposer::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; // constant members (no synchronization needed for access) const nsecs_t mBootTime = systemTime(); bool mGpuToCpuSupported = false; bool mIsUserBuild = true; // Can only accessed from the main thread, these members // don't need synchronization State mDrawingState{LayerVector::StateSet::Drawing}; bool mVisibleRegionsDirty = false; // VisibleRegions dirty is already cleared by postComp, but we need to track it to prevent // extra work in the HDR layer info listener. bool mVisibleRegionsWereDirtyThisFrame = 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 mInputInfoChanged = false; bool mSomeChildrenChanged; bool mSomeDataspaceChanged = false; bool mForceTransactionDisplayChange = false; bool mAnimCompositionPending = false; // Tracks layers that have pending frames which are candidates for being // latched. std::unordered_set, SpHash> mLayersWithQueuedFrames; // Tracks layers that need to update a display's dirty region. std::vector> mLayersPendingRefresh; std::array mPreviousPresentFences; // True if in the previous frame at least one layer was composed via the GPU. bool mHadClientComposition = false; // True if in the previous frame at least one layer was composed via HW Composer. // Note that it is possible for a frame to be composed via both client and device // composition, for example in the case of overlays. bool mHadDeviceComposition = false; // True if in the previous frame, the client composition was skipped by reusing the buffer // used in a previous composition. This can happed if the client composition requests // did not change. bool mReusedClientComposition = false; BootStage mBootStage = BootStage::BOOTLOADER; std::vector mPendingHotplugEvents GUARDED_BY(mStateLock); // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and // never removed, so take precedence over external and virtual displays. // // The static capacities were chosen to exceed a typical number of physical/virtual displays. // // May be read from any thread, but must only be written from the main thread. ftl::SmallMap, const sp, 5> mDisplays GUARDED_BY(mStateLock); ftl::SmallMap, 3> mPhysicalDisplayTokens 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 mPropagateBackpressureClientComposition = false; sp mInterceptor; LayerTracing mLayerTracing{*this}; 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; // If blurs should be enabled on this device. bool mSupportsBlur = false; // If blurs are considered expensive and should require high GPU frequency. bool mBlursAreExpensive = false; std::atomic mFrameMissedCount = 0; std::atomic mHwcFrameMissedCount = 0; std::atomic mGpuFrameMissedCount = 0; TransactionCallbackInvoker mTransactionCallbackInvoker; // Thread-safe. FrameTracker mAnimFrameTracker; // 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; mutable Mutex mQueueLock; Condition mTransactionQueueCV; std::unordered_map, std::queue, IListenerHash> mPendingTransactionQueues GUARDED_BY(mQueueLock); std::deque mTransactionQueue GUARDED_BY(mQueueLock); /* * Feature prototyping */ // Static screen stats bool mHasPoweredOff = false; 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; ui::Dataspace mDefaultCompositionDataspace; ui::Dataspace mWideColorGamutCompositionDataspace; ui::Dataspace mColorSpaceAgnosticDataspace; float mDimmingRatio = -1.f; SurfaceFlingerBE mBE; std::unique_ptr mCompositionEngine; // 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; bool hasMockHwc() const { return mHwcServiceName == "mock"; } /* * Scheduler */ std::unique_ptr mScheduler; scheduler::ConnectionHandle mAppConnectionHandle; scheduler::ConnectionHandle mSfConnectionHandle; // Stores phase offsets configured per refresh rate. std::unique_ptr mVsyncConfiguration; // Optional to defer construction until PhaseConfiguration is created. sp mVsyncModulator; std::unique_ptr mRefreshRateStats; std::atomic mExpectedPresentTime = 0; nsecs_t mScheduledPresentTime = 0; hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE; hal::Vsync mLastHWCVsyncState = hal::Vsync::DISABLE; // 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 mInternalDisplayDensity; const float mEmulatedDisplayDensity; // Should only be accessed by the main thread. sp mInputFlinger; InputWindowCommands mInputWindowCommands; std::unique_ptr mPowerAdvisor; void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock); // 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; BufferCountTracker mBufferCountTracker; std::unordered_map> mHdrLayerInfoListeners GUARDED_BY(mStateLock); mutable std::mutex mCreatedLayersLock; struct LayerCreatedState { LayerCreatedState(const wp& layer, const wp parent, bool addToRoot) : layer(layer), initialParent(parent), addToRoot(addToRoot) {} wp layer; // Indicates the initial parent of the created layer, only used for creating layer in // SurfaceFlinger. If nullptr, it may add the created layer into the current root layers. wp initialParent; // Indicates whether the layer getting created should be added at root if there's no parent // and has permission ACCESS_SURFACE_FLINGER. If set to false and no parent, the layer will // be added offscreen. bool addToRoot; }; // 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(); void handleLayerCreatedLocked(const LayerCreatedState& state) REQUIRES(mStateLock); std::atomic mActiveDisplayTransformHint; bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) { return hasDisplay( [](const auto& display) { return display.isRefreshRateOverlayEnabled(); }); } wp mActiveDisplayToken GUARDED_BY(mStateLock); 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; struct { bool late = false; bool early = false; } mPowerHintSessionMode; nsecs_t mAnimationTransactionTimeout = s2ns(5); #if RK_FPS //add by rk for fps int mDebugFPS; #endif friend class SurfaceComposerAIDL; }; class SurfaceComposerAIDL : public gui::BnSurfaceComposer { public: SurfaceComposerAIDL(sp sf) { mFlinger = sf; } binder::Status createDisplay(const std::string& displayName, bool secure, sp* outDisplay) override; binder::Status destroyDisplay(const sp& display) override; binder::Status getPhysicalDisplayIds(std::vector* outDisplayIds) override; binder::Status getPrimaryPhysicalDisplayId(int64_t* outDisplayId) override; binder::Status getPhysicalDisplayToken(int64_t displayId, sp* outDisplay) override; binder::Status setPowerMode(const sp& display, int mode) override; binder::Status getDisplayStats(const sp& display, gui::DisplayStatInfo* outStatInfo) override; binder::Status getDisplayState(const sp& display, gui::DisplayState* outState) override; binder::Status clearBootDisplayMode(const sp& display) override; binder::Status getBootDisplayModeSupport(bool* outMode) 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; binder::Status isWideColorDisplay(const sp& token, bool* outIsWideColorDisplay) 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; private: static const constexpr bool kUsePermissionCache = true; status_t checkAccessPermission(bool usePermissionCache = kUsePermissionCache); status_t checkControlDisplayBrightnessPermission(); private: sp mFlinger; }; } // namespace android