diff options
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.h')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 1031 |
1 files changed, 416 insertions, 615 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 380f444221..ccaeb2d858 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -33,6 +33,7 @@ #include <gui/ITransactionCompletedListener.h> #include <gui/LayerState.h> #include <gui/OccupancyTracker.h> +#include <input/ISetInputWindowsListener.h> #include <layerproto/LayerProtoHeader.h> #include <math/mat4.h> #include <renderengine/LayerSettings.h> @@ -52,19 +53,17 @@ #include "DisplayDevice.h" #include "DisplayHardware/HWC2.h" #include "DisplayHardware/PowerAdvisor.h" -#include "DisplayIdGenerator.h" #include "Effects/Daltonizer.h" -#include "Fps.h" #include "FrameTracker.h" #include "LayerVector.h" #include "Scheduler/RefreshRateConfigs.h" #include "Scheduler/RefreshRateStats.h" #include "Scheduler/Scheduler.h" -#include "Scheduler/VsyncModulator.h" +#include "Scheduler/VSyncModulator.h" #include "SurfaceFlingerFactory.h" #include "SurfaceTracing.h" #include "TracedOrdinal.h" -#include "TransactionCallbackInvoker.h" +#include "TransactionCompletedThread.h" #include <atomic> #include <cstdint> @@ -89,30 +88,16 @@ namespace android { class Client; class EventThread; -class FpsReporter; -class TunnelModeEnabledReporter; -class HdrLayerInfoReporter; class HWComposer; -struct SetInputWindowsListener; class IGraphicBufferProducer; +class IInputFlinger; class Layer; class MessageBase; class RefreshRateOverlay; class RegionSamplingThread; -class RenderArea; class TimeStats; class FrameTracer; -using gui::ScreenCaptureResults; - -namespace frametimeline { -class FrameTimeline; -} - -namespace os { - class IInputFlinger; -} - namespace compositionengine { class DisplaySurface; class OutputLayer; @@ -124,6 +109,10 @@ namespace renderengine { class RenderEngine; } // namespace renderengine +namespace dvr { +class VrFlinger; +} // namespace dvr + enum { eTransactionNeeded = 0x01, eTraversalNeeded = 0x02, @@ -135,7 +124,13 @@ enum { using DisplayColorSetting = compositionengine::OutputColorSetting; -struct SurfaceFlingerBE { +class SurfaceFlingerBE +{ +public: + SurfaceFlingerBE(); + + const std::string mHwcServiceName; // "default" for real use, something else for testing. + FenceTimeline mGlCompositionDoneTimeline; FenceTimeline mDisplayTimeline; @@ -170,26 +165,22 @@ struct SurfaceFlingerBE { }; mutable Mutex mBufferingStatsMutex; std::unordered_map<std::string, BufferingStats> mBufferingStats; + + // The composer sequence id is a monotonically increasing integer that we + // use to differentiate callbacks from different hardware composer + // instances. Each hardware composer instance gets a different sequence id. + int32_t mComposerSequenceId = 0; }; class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, + public ClientCache::ErasedRecipient, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private 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"; } + SurfaceFlingerBE& getBE() { return mBE; } + const SurfaceFlingerBE& getBE() const { return mBE; } // This is the phase offset in nanoseconds of the software vsync event // relative to the vsync event reported by HWComposer. The software vsync @@ -217,7 +208,7 @@ public: // If fences from sync Framework are supported. static bool hasSyncFramework; - // The offset in nanoseconds to use when VsyncController timestamps present fence + // The offset in nanoseconds to use when DispSync timestamps present fence // signaling time. static int64_t dispSyncPresentTimeOffset; @@ -227,6 +218,10 @@ public: // GL composition. static bool useHwcForRgbToYuv; + // Maximum dimension supported by HWC for virtual display. + // Equal to min(max_height, max_width). + static uint64_t maxVirtualDisplaySize; + // Controls the number of buffers SurfaceFlinger will allocate for use in // FramebufferSurface static int64_t maxFrameBufferAcquiredBuffers; @@ -264,13 +259,17 @@ public: // overhead that is caused by reading from sysprop. static bool useFrameRateApi; - static constexpr SkipInitializationTag SkipInitialization; + // set main thread scheduling policy + static status_t setSchedFifo(bool enabled) ANDROID_API; - // Whether or not SDR layers should be dimmed to the desired SDR white point instead of - // being treated as native display brightness - static bool enableSdrDimming; + static char const* getServiceName() ANDROID_API { + return "SurfaceFlinger"; + } - static bool enableLatchUnsignaled; + struct SkipInitializationTag {}; + static constexpr SkipInitializationTag SkipInitialization; + SurfaceFlinger(surfaceflinger::Factory&, SkipInitializationTag) ANDROID_API; + explicit SurfaceFlinger(surfaceflinger::Factory&) ANDROID_API; // must be called before clients can connect void init() ANDROID_API; @@ -278,9 +277,6 @@ public: // starts SurfaceFlinger main loop in the current thread void run() ANDROID_API; - SurfaceFlingerBE& getBE() { return mBE; } - const SurfaceFlingerBE& getBE() const { return mBE; } - // Schedule an asynchronous or synchronous task on the main thread. template <typename F, typename T = std::invoke_result_t<F>> [[nodiscard]] std::future<T> schedule(F&&); @@ -300,10 +296,17 @@ public: // utility function to delete a texture on the main thread void deleteTextureAsync(uint32_t texture); + // enable/disable h/w composer event + // TODO: this should be made accessible only to EventThread + void setPrimaryVsyncEnabled(bool enabled); + + // main thread function to enable/disable h/w composer event + void setPrimaryVsyncEnabledInternal(bool enabled) REQUIRES(mStateLock); + // called on the main thread by MessageQueue when an internal message // is received // TODO: this should be made accessible only to MessageQueue - void onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime); + void onMessageReceived(int32_t what, nsecs_t expectedVSyncTime); renderengine::RenderEngine& getRenderEngine() const; @@ -313,14 +316,10 @@ public: void onLayerFirstRef(Layer*); void onLayerDestroyed(Layer*); - void removeHierarchyFromOffscreenLayers(Layer* layer); void removeFromOffscreenLayers(Layer* layer); - // TODO: Remove atomic if move dtor to main thread CL lands - std::atomic<uint32_t> mNumClones; - - TransactionCallbackInvoker& getTransactionCallbackInvoker() { - return mTransactionCallbackInvoker; + TransactionCompletedThread& getTransactionCompletedThread() { + return mTransactionCompletedThread; } // Converts from a binder handle to a Layer @@ -328,43 +327,20 @@ public: // Otherwise, returns a weak reference so that callers off the main-thread // won't accidentally hold onto the last strong reference. wp<Layer> fromHandle(const sp<IBinder>& handle); - wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock); + wp<Layer> fromHandleLocked(const sp<IBinder>& handle) REQUIRES(mStateLock); + + // Inherit from ClientCache::ErasedRecipient + void bufferErased(const client_cache_t& clientCacheId) override; // If set, disables reusing client composition buffers. This can be set by // debug.sf.disable_client_composition_cache bool mDisableClientCompositionCache = false; - void setInputWindowsFinished(); - - // Disables expensive rendering for all displays - // This is scheduled on the main thread - void disableExpensiveRendering(); - -protected: - // We're reference counted, never destroy SurfaceFlinger directly - virtual ~SurfaceFlinger(); - - virtual uint32_t setClientStateLocked( - const FrameTimelineInfo& info, const ComposerState& composerState, - int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, - uint32_t permissions, - std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) - REQUIRES(mStateLock); - virtual void commitTransactionLocked(); - - // Used internally by computeLayerBounds() to gets the clip rectangle to use for the - // root layers on a particular display in layer-coordinate space. The - // layers (and effectively their children) will be clipped against this - // rectangle. The base behavior is to clip to the visible region of the - // display. - virtual FloatRect getLayerClipBoundsForDisplay(const DisplayDevice&) const; 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; @@ -374,20 +350,22 @@ private: // For unit tests friend class TestableSurfaceFlinger; friend class TransactionApplicationTest; - friend class TunnelModeEnabledReporterTest; - - using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate; - using VsyncModulator = scheduler::VsyncModulator; - using TransactionSchedule = scheduler::TransactionSchedule; - using TraverseLayersFunction = std::function<void(const LayerVector::Visitor&)>; - using RenderAreaFuture = std::future<std::unique_ptr<RenderArea>>; - using DumpArgs = Vector<String16>; - using Dumper = std::function<void(const DumpArgs&, bool asProto, std::string&)>; // This value is specified in number of frames. Log frame stats at most // every half hour. enum { LOG_FRAME_STATS_PERIOD = 30*60*60 }; + static const int MAX_TRACING_MEMORY = 100 * 1024 * 1024; // 100MB + +protected: + // We're reference counted, never destroy SurfaceFlinger directly + virtual ~SurfaceFlinger(); + +private: + /* ------------------------------------------------------------------------ + * Internal data structures + */ + class State { public: explicit State(LayerVector::StateSet set) : stateSet(set), layersSortedByZ(set) {} @@ -419,243 +397,72 @@ private: 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<std::mutex> 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<int32_t>* counter) { - std::lock_guard<std::mutex> lock(mLock); - mCounterByLayerHandle[layerHandle] = std::make_pair(name, counter); - } - - void remove(BBinder* layerHandle) { - std::lock_guard<std::mutex> lock(mLock); - mCounterByLayerHandle.erase(layerHandle); - } - - private: - std::mutex mLock; - std::unordered_map<BBinder*, std::pair<std::string, std::atomic<int32_t>*>> - mCounterByLayerHandle GUARDED_BY(mLock); - }; - - struct ActiveModeInfo { - DisplayModeId modeId; - Scheduler::ModeEvent event = Scheduler::ModeEvent::None; - - bool operator!=(const ActiveModeInfo& other) const { - return modeId != other.modeId || event != other.event; - } - }; - - enum class BootStage { - BOOTLOADER, - BOOTANIMATION, - FINISHED, - }; - - struct HotplugEvent { - hal::HWDisplayId hwcDisplayId; - hal::Connection connection = hal::Connection::INVALID; - }; - - class CountDownLatch { - public: - enum { - eSyncTransaction = 1 << 0, - eSyncInputWindows = 1 << 1, - }; - explicit CountDownLatch(uint32_t flags) : mFlags(flags) {} - - // True if there is no waiting condition after count down. - bool countDown(uint32_t flag) { - std::unique_lock<std::mutex> lock(mMutex); - if (mFlags == 0) { - return true; - } - mFlags &= ~flag; - if (mFlags == 0) { - mCountDownComplete.notify_all(); - return true; - } - return false; - } - - // Return true if triggered. - bool wait_until(const std::chrono::seconds& timeout) const { - std::unique_lock<std::mutex> lock(mMutex); - const auto untilTime = std::chrono::system_clock::now() + timeout; - while (mFlags != 0) { - // Conditional variables can be woken up sporadically, so we check count - // to verify the wakeup was triggered by |countDown|. - if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) { - return false; - } - } - return true; - } - - private: - uint32_t mFlags; - mutable std::condition_variable mCountDownComplete; - mutable std::mutex mMutex; - }; - - struct TransactionState { - TransactionState(const FrameTimelineInfo& frameTimelineInfo, - const Vector<ComposerState>& composerStates, - const Vector<DisplayState>& displayStates, uint32_t transactionFlags, - const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime, - bool isAutoTimestamp, const client_cache_t& uncacheBuffer, - int64_t postTime, uint32_t permissions, bool hasListenerCallbacks, - std::vector<ListenerCallbacks> listenerCallbacks, int originPid, - int originUid, uint64_t transactionId) - : frameTimelineInfo(frameTimelineInfo), - states(composerStates), - displays(displayStates), - flags(transactionFlags), - applyToken(applyToken), - inputWindowCommands(inputWindowCommands), - desiredPresentTime(desiredPresentTime), - isAutoTimestamp(isAutoTimestamp), - buffer(uncacheBuffer), - postTime(postTime), - permissions(permissions), - hasListenerCallbacks(hasListenerCallbacks), - listenerCallbacks(listenerCallbacks), - originPid(originPid), - originUid(originUid), - id(transactionId) {} - - void traverseStatesWithBuffers(std::function<void(const layer_state_t&)> visitor); - - FrameTimelineInfo frameTimelineInfo; - Vector<ComposerState> states; - Vector<DisplayState> displays; - uint32_t flags; - sp<IBinder> applyToken; - InputWindowCommands inputWindowCommands; - const int64_t desiredPresentTime; - const bool isAutoTimestamp; - client_cache_t buffer; - const int64_t postTime; - uint32_t permissions; - bool hasListenerCallbacks; - std::vector<ListenerCallbacks> listenerCallbacks; - int originPid; - int originUid; - uint64_t id; - std::shared_ptr<CountDownLatch> transactionCommittedSignal; - }; - - template <typename F, std::enable_if_t<!std::is_member_function_pointer_v<F>>* = nullptr> - static Dumper dumper(F&& dump) { - using namespace std::placeholders; - return std::bind(std::forward<F>(dump), _3); - } - - template <typename F, std::enable_if_t<std::is_member_function_pointer_v<F>>* = nullptr> - Dumper dumper(F dump) { - using namespace std::placeholders; - return std::bind(dump, this, _3); - } - - template <typename F> - Dumper argsDumper(F dump) { - using namespace std::placeholders; - return std::bind(dump, this, _1, _3); - } - - template <typename F> - Dumper protoDumper(F dump) { - using namespace std::placeholders; - return std::bind(dump, this, _1, _2, _3); - } - - template <typename... Args, - typename Handler = VsyncModulator::VsyncConfigOpt (VsyncModulator::*)(Args...)> - void modulateVsync(Handler handler, Args... args) { - if (const auto config = (*mVsyncModulator.*handler)(args...)) { - const auto vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod(); - 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. + /* ------------------------------------------------------------------------ + * IBinder interface + */ status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override; status_t dump(int fd, const Vector<String16>& args) override { return priorityDump(fd, args); } bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true) EXCLUDES(mStateLock); - // Implements ISurfaceComposer + /* ------------------------------------------------------------------------ + * ISurfaceComposer interface + */ sp<ISurfaceComposerClient> createConnection() override; sp<IBinder> createDisplay(const String8& displayName, bool secure) override; void destroyDisplay(const sp<IBinder>& displayToken) override; std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override; sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override; - status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo, - const Vector<ComposerState>& state, - const Vector<DisplayState>& displays, uint32_t flags, - const sp<IBinder>& applyToken, - const InputWindowCommands& inputWindowCommands, - int64_t desiredPresentTime, bool isAutoTimestamp, - const client_cache_t& uncacheBuffer, bool hasListenerCallbacks, - const std::vector<ListenerCallbacks>& listenerCallbacks, - uint64_t transactionId) override; + void setTransactionState(const Vector<ComposerState>& state, + const Vector<DisplayState>& displays, uint32_t flags, + const sp<IBinder>& applyToken, + const InputWindowCommands& inputWindowCommands, + int64_t desiredPresentTime, const client_cache_t& uncacheBuffer, + bool hasListenerCallbacks, + const std::vector<ListenerCallbacks>& listenerCallbacks) override; void bootFinished() override; bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const override; status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const override; sp<IDisplayEventConnection> createDisplayEventConnection( ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp, - ISurfaceComposer::EventRegistrationFlags eventRegistration = {}) override; - status_t captureDisplay(const DisplayCaptureArgs& args, - const sp<IScreenCaptureListener>& captureListener) override; - status_t captureDisplay(uint64_t displayOrLayerStack, - const sp<IScreenCaptureListener>& captureListener) override; - status_t captureLayers(const LayerCaptureArgs& args, - const sp<IScreenCaptureListener>& captureListener) override; + ISurfaceComposer::ConfigChanged configChanged = + ISurfaceComposer::eConfigChangedSuppress) override; + status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer, + bool& outCapturedSecureLayers, ui::Dataspace reqDataspace, + ui::PixelFormat reqPixelFormat, const Rect& sourceCrop, + uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform, + ui::Rotation rotation, bool captureSecureLayers) override; + status_t captureScreen(uint64_t displayOrLayerStack, ui::Dataspace* outDataspace, + sp<GraphicBuffer>* outBuffer) override; + status_t captureLayers( + const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer, + const ui::Dataspace reqDataspace, const ui::PixelFormat reqPixelFormat, + const Rect& sourceCrop, + const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& exclude, + float frameScale, bool childrenOnly) override; status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats) override; - status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) - EXCLUDES(mStateLock) override; - status_t getStaticDisplayInfo(const sp<IBinder>& displayToken, ui::StaticDisplayInfo*) - EXCLUDES(mStateLock) override; - status_t getDynamicDisplayInfo(const sp<IBinder>& displayToken, ui::DynamicDisplayInfo*) - EXCLUDES(mStateLock) override; + status_t getDisplayState(const sp<IBinder>& displayToken, ui::DisplayState*) override; + status_t getDisplayInfo(const sp<IBinder>& displayToken, DisplayInfo*) override; + status_t getDisplayConfigs(const sp<IBinder>& displayToken, Vector<DisplayConfig>*) override; + int getActiveConfig(const sp<IBinder>& displayToken) override; + status_t getDisplayColorModes(const sp<IBinder>& displayToken, Vector<ui::ColorMode>*) override; status_t getDisplayNativePrimaries(const sp<IBinder>& displayToken, ui::DisplayPrimaries&) override; + ui::ColorMode getActiveColorMode(const sp<IBinder>& displayToken) override; status_t setActiveColorMode(const sp<IBinder>& displayToken, ui::ColorMode colorMode) override; + status_t getAutoLowLatencyModeSupport(const sp<IBinder>& displayToken, + bool* outSupported) const override; void setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) override; + status_t getGameContentTypeSupport(const sp<IBinder>& displayToken, + bool* outSupported) const override; void setGameContentType(const sp<IBinder>& displayToken, bool on) override; void setPowerMode(const sp<IBinder>& displayToken, int mode) override; status_t clearAnimationFrameStats() override; status_t getAnimationFrameStats(FrameStats* outStats) const override; - status_t overrideHdrTypes(const sp<IBinder>& displayToken, - const std::vector<ui::Hdr>& hdrTypes) override; - status_t onPullAtom(const int32_t atomId, std::string* pulledData, bool* success) override; + status_t getHdrCapabilities(const sp<IBinder>& displayToken, + HdrCapabilities* outCapabilities) const override; status_t enableVSyncInjections(bool enable) override; status_t injectVSync(nsecs_t when) override; status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) override; @@ -678,78 +485,56 @@ private: status_t addRegionSamplingListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle, const sp<IRegionSamplingListener>& listener) override; status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override; - status_t addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener) override; - status_t removeFpsListener(const sp<gui::IFpsListener>& listener) override; - status_t addTunnelModeEnabledListener( - const sp<gui::ITunnelModeEnabledListener>& listener) override; - status_t removeTunnelModeEnabledListener( - const sp<gui::ITunnelModeEnabledListener>& listener) override; - status_t setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, - ui::DisplayModeId displayModeId, bool allowGroupSwitching, - float primaryRefreshRateMin, float primaryRefreshRateMax, - float appRequestRefreshRateMin, - float appRequestRefreshRateMax) override; - status_t getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken, - ui::DisplayModeId* outDefaultMode, - bool* outAllowGroupSwitching, - float* outPrimaryRefreshRateMin, - float* outPrimaryRefreshRateMax, - float* outAppRequestRefreshRateMin, - float* outAppRequestRefreshRateMax) override; + status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, int32_t displayModeId, + float primaryRefreshRateMin, float primaryRefreshRateMax, + float appRequestRefreshRateMin, + float appRequestRefreshRateMax) override; + status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, + int32_t* outDefaultConfig, + float* outPrimaryRefreshRateMin, + float* outPrimaryRefreshRateMax, + float* outAppRequestRefreshRateMin, + float* outAppRequestRefreshRateMax) override; status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken, bool* outSupport) const override; - status_t setDisplayBrightness(const sp<IBinder>& displayToken, - const gui::DisplayBrightness& brightness) override; - status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken, - const sp<gui::IHdrLayerInfoListener>& listener) override; - status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken, - const sp<gui::IHdrLayerInfoListener>& listener) override; - status_t notifyPowerBoost(int32_t boostId) override; + status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override; + status_t notifyPowerHint(int32_t hintId) override; status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) override; status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate, - int8_t compatibility, int8_t changeFrameRateStrategy) override; + int8_t compatibility) override; status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) override; - - status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& surface, - const FrameTimelineInfo& frameTimelineInfo) override; - - status_t addTransactionTraceListener( - const sp<gui::ITransactionTraceListener>& listener) override; - - int getGPUContextPriority() override; - - status_t getMaxAcquiredBufferCount(int* buffers) const override; - - // Implements IBinder::DeathRecipient. + /* ------------------------------------------------------------------------ + * DeathRecipient interface + */ void binderDied(const wp<IBinder>& who) override; - // Implements RefBase. + /* ------------------------------------------------------------------------ + * RefBase interface + */ void onFirstRef() override; - // HWC2::ComposerCallback overrides: - void onComposerHalVsync(hal::HWDisplayId, int64_t timestamp, - std::optional<hal::VsyncPeriodNanos>) 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; - - /* + /* ------------------------------------------------------------------------ + * HWC2::ComposerCallback / HWComposer::EventHandler interface + */ + void onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, int64_t timestamp, + std::optional<hal::VsyncPeriodNanos> vsyncPeriod) override; + void onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, + hal::Connection connection) override; + void onRefreshReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId) override; + void onVsyncPeriodTimingChangedReceived( + int32_t sequenceId, hal::HWDisplayId display, + const hal::VsyncPeriodChangeTimeline& updatedTimeline) override; + void onSeamlessPossible(int32_t sequenceId, hal::HWDisplayId display) override; + + /* ------------------------------------------------------------------------ * ISchedulerCallback */ - - // Toggles hardware VSYNC by calling into HWC. - void setVsyncEnabled(bool) override; - // Initiates a refresh rate change to be applied on invalidate. - void changeRefreshRate(const Scheduler::RefreshRate&, Scheduler::ModeEvent) override; - // Forces full composition on all displays without resetting the scheduler idle timer. + void changeRefreshRate(const Scheduler::RefreshRate&, Scheduler::ConfigEvent) override; + // force full composition on all displays without resetting the scheduler idle timer. void repaintEverythingForHWC() 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(); // Keeps track of whether the kernel idle timer is currently enabled, so we don't have to @@ -757,10 +542,7 @@ private: bool mKernelIdleTimerEnabled = false; // Keeps track of whether the kernel timer is supported on the SF side. bool mSupportKernelIdleTimer = false; - // Show spinner with refresh rate overlay - bool mRefreshRateOverlaySpinner = false; - - /* + /* ------------------------------------------------------------------------ * Message handling */ // Can only be called from the main thread or with mStateLock held @@ -769,33 +551,43 @@ private: void signalLayerUpdate(); void signalRefresh(); - // Called on the main thread in response to initializeDisplays() + using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate; + + struct ActiveConfigInfo { + HwcConfigIndexType configId; + Scheduler::ConfigEvent event = Scheduler::ConfigEvent::None; + + bool operator!=(const ActiveConfigInfo& other) const { + return configId != other.configId || event != other.event; + } + }; + + // 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) REQUIRES(mStateLock); - status_t setActiveMode(const sp<IBinder>& displayToken, int id); - // Once HWC has returned the present fence, this sets the active mode and a new refresh + // Sets the desired active config bit. It obtains the lock, and sets mDesiredActiveConfig. + void setDesiredActiveConfig(const ActiveConfigInfo& info) REQUIRES(mStateLock); + status_t setActiveConfig(const sp<IBinder>& displayToken, int id); + // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. - void setActiveModeInternal() REQUIRES(mStateLock); - // Calls to setActiveMode on the main thread if there is a pending mode change + void setActiveConfigInternal() REQUIRES(mStateLock); + // Calls to setActiveConfig on the main thread if there is a pending config // that needs to be applied. - void performSetActiveMode() REQUIRES(mStateLock); - void clearDesiredActiveModeState() REQUIRES(mStateLock) EXCLUDES(mActiveModeLock); - // Called when active mode is no longer is progress - void desiredActiveModeChangeDone() REQUIRES(mStateLock); - // Called on the main thread in response to setPowerMode() + void performSetActiveConfig() REQUIRES(mStateLock); + // Called when active config is no longer is progress + void desiredActiveConfigChangeDone() REQUIRES(mStateLock); + // called on the main thread in response to setPowerMode() void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) REQUIRES(mStateLock); - // Sets the desired display mode specs. - status_t setDesiredDisplayModeSpecsInternal( + // Sets the desired display configs. + status_t setDesiredDisplayConfigSpecsInternal( const sp<DisplayDevice>& display, const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) EXCLUDES(mStateLock); // Handle the INVALIDATE message queue event, latching new buffers and applying // incoming transactions - void onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTime); + void onMessageInvalidate(nsecs_t expectedVSyncTime); // Returns whether the transaction actually modified any state bool handleMessageTransaction(); @@ -813,11 +605,9 @@ private: void updateInputFlinger(); void updateInputWindowInfo(); void commitInputWindowCommands() REQUIRES(mStateLock); + void setInputWindowsFinished(); void updateCursorAsync(); - - void initScheduler(const DisplayDeviceState&) REQUIRES(mStateLock); - void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock); - void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod); + void initScheduler(DisplayId primaryDisplayId); /* handlePageFlip - latch a new buffer if available and compute the dirty * region. Returns whether a new buffer has been latched, i.e., whether it @@ -825,20 +615,19 @@ private: */ bool handlePageFlip(); - /* + /* ------------------------------------------------------------------------ * Transactions */ - void applyTransactionState(const FrameTimelineInfo& info, const Vector<ComposerState>& state, + void applyTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const InputWindowCommands& inputWindowCommands, - const int64_t desiredPresentTime, bool isAutoTimestamp, + const int64_t desiredPresentTime, const client_cache_t& uncacheBuffer, const int64_t postTime, - uint32_t permissions, bool hasListenerCallbacks, + bool privileged, bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks, - int originPid, int originUid, uint64_t transactionId) - REQUIRES(mStateLock); - // flush pending transaction that was presented after desiredPresentTime. - void flushTransactionQueues(); + bool isMainThread = false) REQUIRES(mStateLock); + // Returns true if at least one transaction was flushed + bool flushTransactionQueues(); // Returns true if there is at least one transaction that needs to be flushed bool transactionFlushNeeded(); uint32_t getTransactionFlags(uint32_t flags); @@ -851,26 +640,38 @@ private: // but there is no need to try and wake up immediately to do it. Rather we rely on // onFrameAvailable or another layer update to wake us up. void setTraversalNeeded(); - uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule, const sp<IBinder>& = {}); + uint32_t setTransactionFlags(uint32_t flags, Scheduler::TransactionStart transactionStart); void commitTransaction() REQUIRES(mStateLock); void commitOffscreenLayers(); - bool transactionIsReadyToBeApplied( - const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime, - uid_t originUid, const Vector<ComposerState>& states, - const std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& - bufferLayersReadyToPresent) const REQUIRES(mStateLock); + bool transactionIsReadyToBeApplied(int64_t desiredPresentTime, + const Vector<ComposerState>& states); 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; - /* + +protected: + virtual uint32_t setClientStateLocked( + const ComposerState& composerState, int64_t desiredPresentTime, int64_t postTime, + bool privileged, + std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) + REQUIRES(mStateLock); + virtual void commitTransactionLocked(); + + // Used internally by computeLayerBounds() to gets the clip rectangle to use for the + // root layers on a particular display in layer-coordinate space. The + // layers (and effectively their children) will be clipped against this + // rectangle. The base behavior is to clip to the visible region of the + // display. + virtual FloatRect getLayerClipBoundsForDisplay(const DisplayDevice&) const; + +private: + /* ------------------------------------------------------------------------ * Layer management */ status_t createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, LayerMetadata metadata, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, - const sp<IBinder>& parentHandle, int32_t* outLayerId, - const sp<Layer>& parentLayer = nullptr, + const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr, uint32_t* outTransformHint = nullptr); status_t createBufferQueueLayer(const sp<Client>& client, std::string name, uint32_t w, @@ -891,7 +692,7 @@ private: sp<IBinder>* outHandle, sp<Layer>* outLayer); status_t mirrorLayer(const sp<Client>& client, const sp<IBinder>& mirrorFromHandle, - sp<IBinder>* outHandle, int32_t* outLayerId); + sp<IBinder>* outHandle); std::string getUniqueLayerName(const char* name); @@ -905,38 +706,52 @@ private: status_t addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc, const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer, - bool addToRoot, uint32_t* outTransformHint); + bool addToCurrentState, uint32_t* outTransformHint); // Traverse through all the layers and compute and cache its bounds. void computeLayerBounds(); - // Boot animation, on/off animations and screen capture + /* ------------------------------------------------------------------------ + * Boot animation, on/off animations and screen capture + */ + void startBootAnim(); - status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, - ui::PixelFormat, bool allowProtected, bool grayscale, - const sp<IScreenCaptureListener>&); - status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool regionSampling, bool grayscale, - const sp<IScreenCaptureListener>&); - status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool canCaptureBlackoutContent, bool regionSampling, - bool grayscale, ScreenCaptureResults&); - - // 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&); + using TraverseLayersFunction = std::function<void(const LayerVector::Visitor&)>; + + void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers, + ANativeWindowBuffer* buffer, bool useIdentityTransform, + bool regionSampling, int* outSyncFd); + status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers, + sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat, + bool useIdentityTransform, bool& outCapturedSecureLayers); + status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers, + const sp<GraphicBuffer>& buffer, bool useIdentityTransform, + bool regionSampling, bool& outCapturedSecureLayers); + sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); + sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack) REQUIRES(mStateLock); + status_t captureScreenImplLocked(const RenderArea& renderArea, + TraverseLayersFunction traverseLayers, + ANativeWindowBuffer* buffer, bool useIdentityTransform, + bool forSystem, int* outSyncFd, bool regionSampling, + bool& outCapturedSecureLayers); + void traverseLayersInDisplay(const sp<const DisplayDevice>& display, + const LayerVector::Visitor& visitor); + + sp<StartPropertySetThread> mStartPropertySetThread; + /* ------------------------------------------------------------------------ + * Properties + */ void readPersistentProperties(); + /* ------------------------------------------------------------------------ + * EGL + */ size_t getMaxTextureSize() const; size_t getMaxViewportDims() const; - int getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const; - - /* + /* ------------------------------------------------------------------------ * Display and layer stack management */ // called when starting, or restarting after system_server death @@ -952,14 +767,6 @@ private: return it == mDisplays.end() ? nullptr : it->second; } - sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const - REQUIRES(mStateLock) { - if (const auto token = getPhysicalDisplayTokenLocked(id)) { - return getDisplayDeviceLocked(token); - } - return nullptr; - } - sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) { return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked(); } @@ -976,36 +783,39 @@ private: return getDefaultDisplayDeviceLocked(); } - // Returns the first display that matches a `bool(const DisplayDevice&)` predicate. - template <typename Predicate> - sp<DisplayDevice> 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; - } - - sp<const DisplayDevice> getDisplayDeviceLocked(DisplayId id) const REQUIRES(mStateLock) { - // TODO(b/182939859): Replace tokens with IDs for display lookup. - return findDisplay([id](const auto& display) { return display.getId() == id; }); - } + std::optional<DeviceProductInfo> getDeviceProductInfoLocked(const DisplayDevice&) const; // mark a region of a layer stack dirty. this updates the dirty // region of all screens presenting this layer stack. void invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty); - /* + /* ------------------------------------------------------------------------ * 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 + + // The current hardware composer interface. + // + // The following thread safety rules apply when accessing mHwc, either + // directly or via getHwComposer(): + // + // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc + // only when switching into and out of vr. Recreating mHwc must only be + // done on the main thread. + // + // 2. When accessing mHwc on the main thread, it's not necessary to acquire + // mStateLock. + // + // 3. When accessing mHwc 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. + // in the process of destroying the current mHwc instance. + // + // The above thread safety rules only apply to SurfaceFlinger.cpp. In + // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never + // destroy it, so it's always safe to access mHwc from any thread without + // acquiring mStateLock. HWComposer& getHwComposer() const; - /* + /* ------------------------------------------------------------------------ * Compositing */ void invalidateHwcGeometry(); @@ -1019,11 +829,9 @@ private: void postFrame(); - /* + /* ------------------------------------------------------------------------ * Display management */ - void loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes, - DisplayModePtr& outActiveMode) const REQUIRES(mStateLock); sp<DisplayDevice> setupNewDisplayDeviceInternal( const wp<IBinder>& displayToken, std::shared_ptr<compositionengine::Display> compositionDisplay, @@ -1041,25 +849,21 @@ private: void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); - /* - * VSYNC + /* ------------------------------------------------------------------------ + * VSync */ - nsecs_t getVsyncPeriodFromHWC() const REQUIRES(mStateLock); + nsecs_t getVsyncPeriod() const REQUIRES(mStateLock); // Sets the refresh rate by switching active configs, if they are available for // the desired refresh rate. - void changeRefreshRateLocked(const RefreshRate&, Scheduler::ModeEvent) REQUIRES(mStateLock); - - bool isDisplayModeAllowed(DisplayModeId) const REQUIRES(mStateLock); + void changeRefreshRateLocked(const RefreshRate&, Scheduler::ConfigEvent event) + REQUIRES(mStateLock); - struct FenceWithFenceTime { - sp<Fence> fence = Fence::NO_FENCE; - std::shared_ptr<FenceTime> fenceTime = FenceTime::NO_FENCE; - }; + bool isDisplayConfigAllowed(HwcConfigIndexType configId) const REQUIRES(mStateLock); // Gets the fence for the previous frame. // Must be called on the main thread. - FenceWithFenceTime previousFrameFence(); + sp<Fence> 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 @@ -1075,20 +879,18 @@ private: // 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; + nsecs_t calculateExpectedPresentTime(nsecs_t now) const; /* * Display identification */ - sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const - REQUIRES(mStateLock) { + sp<IBinder> getPhysicalDisplayTokenLocked(DisplayId displayId) const REQUIRES(mStateLock) { const auto it = mPhysicalDisplayTokens.find(displayId); return it != mPhysicalDisplayTokens.end() ? it->second : nullptr; } - std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked( - const sp<IBinder>& displayToken) const REQUIRES(mStateLock) { + std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const + REQUIRES(mStateLock) { for (const auto& [id, token] : mPhysicalDisplayTokens) { if (token == displayToken) { return id; @@ -1103,22 +905,41 @@ private: return displayId ? getPhysicalDisplayTokenLocked(*displayId) : nullptr; } - std::optional<PhysicalDisplayId> getInternalDisplayIdLocked() const REQUIRES(mStateLock) { + std::optional<DisplayId> getInternalDisplayIdLocked() const REQUIRES(mStateLock) { const auto hwcDisplayId = getHwComposer().getInternalHwcDisplayId(); return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; } - // 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) - REQUIRES(mStateLock); - void releaseVirtualDisplay(VirtualDisplayId); - /* * Debugging & dumpsys */ + using DumpArgs = Vector<String16>; + using Dumper = std::function<void(const DumpArgs&, bool asProto, std::string&)>; + + template <typename F, std::enable_if_t<!std::is_member_function_pointer_v<F>>* = nullptr> + static Dumper dumper(F&& dump) { + using namespace std::placeholders; + return std::bind(std::forward<F>(dump), _3); + } + + template <typename F, std::enable_if_t<std::is_member_function_pointer_v<F>>* = nullptr> + Dumper dumper(F dump) { + using namespace std::placeholders; + return std::bind(dump, this, _3); + } + + template <typename F> + Dumper argsDumper(F dump) { + using namespace std::placeholders; + return std::bind(dump, this, _1, _3); + } + + template <typename F> + Dumper protoDumper(F dump) { + using namespace std::placeholders; + return std::bind(dump, this, _1, _2, _3); + } + void dumpAllLocked(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); void appendSfConfigString(std::string& result) const; @@ -1126,7 +947,6 @@ private: 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(); void dumpVSync(std::string& result) const REQUIRES(mStateLock); @@ -1148,7 +968,10 @@ private: LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL) EXCLUDES(mStateLock); void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock); - void dumpPlannerInfo(const DumpArgs& args, std::string& result) const REQUIRES(mStateLock); + + bool isLayerTripleBufferingDisabled() const { + return this->mLayerTripleBufferingDisabled; + } status_t doDump(int fd, const DumpArgs& args, bool asProto); @@ -1160,51 +983,28 @@ private: void onFrameRateFlexibilityTokenReleased(); - 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<std::string, uint32_t>& getGenericLayerMetadataKeyMap() const; - - /* - * Misc + /* ------------------------------------------------------------------------ + * VrFlinger */ + void resetDisplayState() REQUIRES(mStateLock); - std::optional<ActiveModeInfo> getDesiredActiveMode() EXCLUDES(mActiveModeLock) { - std::lock_guard<std::mutex> lock(mActiveModeLock); - if (mDesiredActiveModeChanged) return mDesiredActiveMode; - return std::nullopt; - } + // Check to see if we should handoff to vr flinger. + void updateVrFlinger(); - std::vector<ui::ColorMode> getDisplayColorModes(PhysicalDisplayId displayId) - REQUIRES(mStateLock); + void updateColorMatrixLocked(); - static int calculateMaxAcquiredBufferCount(Fps refreshRate, - std::chrono::nanoseconds presentLatency); - int getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const; + /* ------------------------------------------------------------------------ + * Attributes + */ - sp<StartPropertySetThread> mStartPropertySetThread; surfaceflinger::Factory& mFactory; - std::future<void> mRenderEnginePrimeCacheFuture; - // access must be protected by mStateLock mutable Mutex mStateLock; State mCurrentState{LayerVector::StateSet::Current}; std::atomic<int32_t> mTransactionFlags = 0; - std::vector<std::shared_ptr<CountDownLatch>> mTransactionCommittedSignals; + Condition mTransactionCV; + bool mTransactionPending = false; bool mAnimTransactionPending = false; SortedVector<sp<Layer>> mLayersPendingRemoval; bool mForceTraversal = false; @@ -1217,10 +1017,6 @@ private: // Can't be unordered_set because wp<> isn't hashable std::set<wp<IBinder>> mGraphicBufferProducerList; 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<size_t>(0.95 * static_cast<double>(MAX_LAYERS)); void removeGraphicBufferProducerAsync(const wp<IBinder>&); @@ -1239,31 +1035,14 @@ private: // 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; - - // 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. + // Set during transaction commit stage to track if the input info for a layer has changed. bool mInputInfoChanged = false; - bool mSomeChildrenChanged; - bool mSomeDataspaceChanged = false; - bool mForceTransactionDisplayChange = false; - bool mGeometryInvalid = false; bool mAnimCompositionPending = false; - - // Tracks layers that have pending frames which are candidates for being - // latched. - std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> mLayersWithQueuedFrames; + std::vector<sp<Layer>> mLayersWithQueuedFrames; // Tracks layers that need to update a display's dirty region. std::vector<sp<Layer>> mLayersPendingRefresh; - std::array<FenceWithFenceTime, 2> mPreviousPresentFences; + std::array<sp<Fence>, 2> mPreviousPresentFences = {Fence::NO_FENCE, Fence::NO_FENCE}; // 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. @@ -1275,20 +1054,23 @@ private: // did not change. bool mReusedClientComposition = false; + enum class BootStage { + BOOTLOADER, + BOOTANIMATION, + FINISHED, + }; BootStage mBootStage = BootStage::BOOTLOADER; + struct HotplugEvent { + hal::HWDisplayId hwcDisplayId; + hal::Connection connection = hal::Connection::INVALID; + }; std::vector<HotplugEvent> mPendingHotplugEvents GUARDED_BY(mStateLock); // this may only be written from the main thread with mStateLock held // it may be read from other threads with mStateLock held std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock); - std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens - GUARDED_BY(mStateLock); - - struct { - DisplayIdGenerator<GpuVirtualDisplayId> gpu; - std::optional<DisplayIdGenerator<HalVirtualDisplayId>> hal; - } mVirtualDisplayIdGenerators; + std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens GUARDED_BY(mStateLock); std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock); @@ -1296,31 +1078,35 @@ private: int mDebugRegion = 0; bool mDebugDisableHWC = false; bool mDebugDisableTransformHint = false; - bool mLayerCachingEnabled = false; volatile nsecs_t mDebugInTransaction = 0; bool mForceFullDamage = false; + bool mPropagateBackpressure = true; bool mPropagateBackpressureClientComposition = false; - sp<SurfaceInterceptor> mInterceptor; + std::unique_ptr<SurfaceInterceptor> mInterceptor; SurfaceTracing mTracing{*this}; std::mutex mTracingLock; bool mTracingEnabled = false; - bool mTracePostComposition = false; + bool mAddCompositionStateToTrace = false; std::atomic<bool> mTracingEnabledChanged = false; const std::shared_ptr<TimeStats> mTimeStats; const std::unique_ptr<FrameTracer> mFrameTracer; - const std::unique_ptr<frametimeline::FrameTimeline> mFrameTimeline; - + bool mUseHwcVirtualDisplays = false; // If blurs should be enabled on this device. bool mSupportsBlur = false; + // Disable blurs, for debugging + std::atomic<bool> mDisableBlurs = false; // If blurs are considered expensive and should require high GPU frequency. bool mBlursAreExpensive = false; std::atomic<uint32_t> mFrameMissedCount = 0; std::atomic<uint32_t> mHwcFrameMissedCount = 0; std::atomic<uint32_t> mGpuFrameMissedCount = 0; - TransactionCallbackInvoker mTransactionCallbackInvoker; + TransactionCompletedThread mTransactionCompletedThread; + + // Restrict layers to use two buffers in their bufferqueues. + bool mLayerTripleBufferingDisabled = false; // these are thread safe std::unique_ptr<MessageQueue> mEventQueue; @@ -1341,12 +1127,35 @@ private: uint32_t mTexturePoolSize = 0; std::vector<uint32_t> mTexturePool; - mutable Mutex mQueueLock; - Condition mTransactionQueueCV; - std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> - mPendingTransactionQueues GUARDED_BY(mQueueLock); - std::queue<TransactionState> mTransactionQueue GUARDED_BY(mQueueLock); - /* + struct TransactionState { + TransactionState(const Vector<ComposerState>& composerStates, + const Vector<DisplayState>& displayStates, uint32_t transactionFlags, + int64_t desiredPresentTime, const client_cache_t& uncacheBuffer, + int64_t postTime, bool privileged, bool hasListenerCallbacks, + std::vector<ListenerCallbacks> listenerCallbacks) + : states(composerStates), + displays(displayStates), + flags(transactionFlags), + desiredPresentTime(desiredPresentTime), + buffer(uncacheBuffer), + postTime(postTime), + privileged(privileged), + hasListenerCallbacks(hasListenerCallbacks), + listenerCallbacks(listenerCallbacks) {} + + Vector<ComposerState> states; + Vector<DisplayState> displays; + uint32_t flags; + const int64_t desiredPresentTime; + client_cache_t buffer; + const int64_t postTime; + bool privileged; + bool hasListenerCallbacks; + std::vector<ListenerCallbacks> listenerCallbacks; + }; + std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash> mTransactionQueues; + + /* ------------------------------------------------------------------------ * Feature prototyping */ @@ -1355,6 +1164,10 @@ private: std::atomic<size_t> mNumLayers = 0; + // Verify that transaction is being called by an approved process: + // either AID_GRAPHICS or AID_SYSTEM. + status_t CheckTransactCodeCredentials(uint32_t code); + // to linkToDeath sp<IBinder> mWindowManager; // We want to avoid multiple calls to BOOT_FINISHED as they come in on @@ -1362,6 +1175,9 @@ private: // to mWindowManager or mInputFlinger std::atomic<bool> mBootFinished = false; + std::unique_ptr<dvr::VrFlinger> mVrFlinger; + std::atomic<bool> mVrFlingerRequestsDisplay = false; + static bool useVrFlinger; std::thread::id mMainThreadId = std::this_thread::get_id(); DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::kEnhanced; @@ -1382,11 +1198,7 @@ private: SurfaceFlingerBE mBE; std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine; - const std::string mHwcServiceName; - - bool hasMockHwc() const { return mHwcServiceName == "mock"; } - - /* + /* ------------------------------------------------------------------------ * Scheduler */ std::unique_ptr<Scheduler> mScheduler; @@ -1394,46 +1206,69 @@ private: scheduler::ConnectionHandle mSfConnectionHandle; // Stores phase offsets configured per refresh rate. - std::unique_ptr<scheduler::VsyncConfiguration> mVsyncConfiguration; + std::unique_ptr<scheduler::PhaseConfiguration> mPhaseConfiguration; - // Optional to defer construction until PhaseConfiguration is created. - sp<VsyncModulator> mVsyncModulator; + // Optional to defer construction until scheduler connections are created. + std::optional<scheduler::VSyncModulator> mVSyncModulator; std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs; std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats; std::atomic<nsecs_t> mExpectedPresentTime = 0; - nsecs_t mScheduledPresentTime = 0; hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE; - std::mutex mActiveModeLock; - // This bit is set once we start setting the mode. We read from this bit during the - // process. If at the end, this bit is different than mDesiredActiveMode, we restart + /* ------------------------------------------------------------------------ + * Generic Layer Metadata + */ + const std::unordered_map<std::string, uint32_t>& getGenericLayerMetadataKeyMap() const; + + /* ------------------------------------------------------------------------ + * Misc + */ + + std::optional<ActiveConfigInfo> getDesiredActiveConfig() EXCLUDES(mActiveConfigLock) { + std::lock_guard<std::mutex> lock(mActiveConfigLock); + if (mDesiredActiveConfigChanged) return mDesiredActiveConfig; + return std::nullopt; + } + + std::mutex mActiveConfigLock; + // This bit is set once we start setting the config. We read from this bit during the + // process. If at the end, this bit is different than mDesiredActiveConfig, we restart // the process. - ActiveModeInfo mUpcomingActiveMode; // Always read and written on the main thread. - // This bit can be set at any point in time when the system wants the new mode. - ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock); + ActiveConfigInfo mUpcomingActiveConfig; // Always read and written on the main thread. + // This bit can be set at any point in time when the system wants the new config. + ActiveConfigInfo mDesiredActiveConfig GUARDED_BY(mActiveConfigLock); // below flags are set by main thread only - TracedOrdinal<bool> mDesiredActiveModeChanged - GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false}; - bool mSetActiveModePending = false; + TracedOrdinal<bool> mDesiredActiveConfigChanged + GUARDED_BY(mActiveConfigLock) = {"DesiredActiveConfigChanged", false}; + bool mSetActiveConfigPending = false; bool mLumaSampling = true; sp<RegionSamplingThread> mRegionSamplingThread; - sp<FpsReporter> mFpsReporter; - sp<TunnelModeEnabledReporter> mTunnelModeEnabledReporter; ui::DisplayPrimaries mInternalDisplayPrimaries; const float mInternalDisplayDensity; const float mEmulatedDisplayDensity; - sp<os::IInputFlinger> mInputFlinger; + sp<IInputFlinger> mInputFlinger; + InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock); // Should only be accessed by the main thread. InputWindowCommands mInputWindowCommands; - sp<SetInputWindowsListener> mSetInputWindowsListener; + struct SetInputWindowsListener : BnSetInputWindowsListener { + explicit SetInputWindowsListener(sp<SurfaceFlinger> flinger) + : mFlinger(std::move(flinger)) {} + void onSetInputWindowsFinished() override; + + const sp<SurfaceFlinger> mFlinger; + }; + + const sp<SetInputWindowsListener> mSetInputWindowsListener = new SetInputWindowsListener(this); + + bool mPendingSyncInputWindows GUARDED_BY(mStateLock) = false; Hwc2::impl::PowerAdvisor mPowerAdvisor; // This should only be accessed on the main thread. @@ -1442,8 +1277,8 @@ private: void enableRefreshRateOverlay(bool enable); std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay GUARDED_BY(mStateLock); - // Flag used to set override desired display mode from backdoor - bool mDebugDisplayModeSetByBackdoor = false; + // Flag used to set override allowed display configs from backdoor + bool mDebugDisplayConfigSetByBackdoor = false; // A set of layers that have no parent so they are not drawn on screen. // Should only be accessed by the main thread. @@ -1451,50 +1286,16 @@ private: // be any issues with a raw pointer referencing an invalid object. std::unordered_set<Layer*> mOffscreenLayers; + // Fields tracking the current jank event: when it started and how many + // janky frames there are. + nsecs_t mMissedFrameJankStart = 0; + int32_t mMissedFrameJankCount = 0; + // Positive if jank should be uploaded in postComposition + nsecs_t mLastJankDuration = -1; + int mFrameRateFlexibilityTokenCount = 0; sp<IBinder> mDebugFrameRateFlexibilityToken; - - BufferCountTracker mBufferCountTracker; - - std::unordered_map<DisplayId, sp<HdrLayerInfoReporter>> mHdrLayerInfoListeners - GUARDED_BY(mStateLock); - mutable Mutex mCreatedLayersLock; - struct LayerCreatedState { - LayerCreatedState(const wp<Layer>& layer, const wp<IBinder>& parent, - const wp<Layer> parentLayer, const wp<IBinder>& producer, bool addToRoot) - : layer(layer), - initialParent(parent), - initialParentLayer(parentLayer), - initialProducer(producer), - addToRoot(addToRoot) {} - wp<Layer> 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<IBinder> initialParent; - wp<Layer> initialParentLayer; - // Indicates the initial graphic buffer producer of the created layer, only used for - // creating layer in SurfaceFlinger. - wp<IBinder> initialProducer; - // 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::unordered_map<BBinder*, std::unique_ptr<LayerCreatedState>> mCreatedLayers; - void setLayerCreatedState(const sp<IBinder>& handle, const wp<Layer>& layer, - const wp<IBinder>& parent, const wp<Layer> parentLayer, - const wp<IBinder>& producer, bool addToRoot); - auto getLayerCreatedState(const sp<IBinder>& handle); - sp<Layer> handleLayerCreatedLocked(const sp<IBinder>& handle) REQUIRES(mStateLock); - - std::atomic<ui::Transform::RotationFlags> mDefaultDisplayTransformHint; - - void scheduleRegionSamplingThread(); - void notifyRegionSamplingThread(); }; } // namespace android |