From 1b0c49f83281b9433a6758ceb16ac4bc17a885f8 Mon Sep 17 00:00:00 2001 From: Huihong Luo Date: Tue, 15 Mar 2022 19:18:21 -0700 Subject: Migrate bootFinished of ISurfaceComposer to AIDL And createDisplayEventConnection is migrated too. Bug: 221898546 Bug: 211009610 Test: atest libsurfaceflinger_unittest libgui_test SurfaceFlinger_test Change-Id: I2d0968262b86829b4cce13158446f1c85a4e55e4 --- libs/gui/DisplayEventDispatcher.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'libs/gui/DisplayEventDispatcher.cpp') diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp index dfdce20438..501e69ade5 100644 --- a/libs/gui/DisplayEventDispatcher.cpp +++ b/libs/gui/DisplayEventDispatcher.cpp @@ -35,11 +35,14 @@ static const size_t EVENT_BUFFER_SIZE = 100; static constexpr nsecs_t WAITING_FOR_VSYNC_TIMEOUT = ms2ns(300); -DisplayEventDispatcher::DisplayEventDispatcher( - const sp& looper, ISurfaceComposer::VsyncSource vsyncSource, - ISurfaceComposer::EventRegistrationFlags eventRegistration) - : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false), - mLastVsyncCount(0), mLastScheduleVsyncTime(0) { +DisplayEventDispatcher::DisplayEventDispatcher(const sp& looper, + gui::ISurfaceComposer::VsyncSource vsyncSource, + EventRegistrationFlags eventRegistration) + : mLooper(looper), + mReceiver(vsyncSource, eventRegistration), + mWaitingForVsync(false), + mLastVsyncCount(0), + mLastScheduleVsyncTime(0) { ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this); } -- cgit v1.2.3-59-g8ed1b From 2248f52cd8102e5bc71c5c1dca7a85e90fea1276 Mon Sep 17 00:00:00 2001 From: Rachel Lee Date: Fri, 27 Jan 2023 16:45:23 -0800 Subject: Framework code for Attached Choreographer. Allows a direct association of a Layer (via LayerHistory) to attached choreographer. The EventThread checks whether the vsync is in phase for a choreographer. Bug: 255838011 Test: atest AttachedChoreographerNativeTest Change-Id: I9cb35bced5e6d4509609ad7698ab2902a31d5b98 --- libs/gui/Choreographer.cpp | 5 +++-- libs/gui/DisplayEventDispatcher.cpp | 5 +++-- libs/gui/DisplayEventReceiver.cpp | 11 ++++++++--- libs/gui/SurfaceControl.cpp | 22 ++++++++++++++++++++- libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 8 +++++++- libs/gui/fuzzer/libgui_fuzzer_utils.h | 2 +- libs/gui/include/gui/Choreographer.h | 3 ++- libs/gui/include/gui/DisplayEventDispatcher.h | 3 ++- libs/gui/include/gui/DisplayEventReceiver.h | 3 ++- libs/gui/include/gui/SurfaceControl.h | 5 +++++ libs/gui/tests/Surface_test.cpp | 1 + services/surfaceflinger/Scheduler/EventThread.cpp | 6 ++++++ services/surfaceflinger/Scheduler/EventThread.h | 3 +++ services/surfaceflinger/Scheduler/LayerHistory.cpp | 23 ++++++++++++++++++++++ services/surfaceflinger/Scheduler/LayerHistory.h | 9 +++++++++ services/surfaceflinger/Scheduler/Scheduler.cpp | 15 ++++++++++---- services/surfaceflinger/Scheduler/Scheduler.h | 6 ++++-- services/surfaceflinger/SurfaceFlinger.cpp | 9 +++++---- services/surfaceflinger/SurfaceFlinger.h | 4 +++- 19 files changed, 119 insertions(+), 24 deletions(-) (limited to 'libs/gui/DisplayEventDispatcher.cpp') diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp index 6b25b262c3..99bf6badee 100644 --- a/libs/gui/Choreographer.cpp +++ b/libs/gui/Choreographer.cpp @@ -101,8 +101,9 @@ Choreographer* Choreographer::getForThread() { return gChoreographer; } -Choreographer::Choreographer(const sp& looper) - : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp), +Choreographer::Choreographer(const sp& looper, const sp& layerHandle) + : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, {}, + layerHandle), mLooper(looper), mThreadId(std::this_thread::get_id()) { std::lock_guard _l(gChoreographers.lock); diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp index 501e69ade5..8a883770d8 100644 --- a/libs/gui/DisplayEventDispatcher.cpp +++ b/libs/gui/DisplayEventDispatcher.cpp @@ -37,9 +37,10 @@ static constexpr nsecs_t WAITING_FOR_VSYNC_TIMEOUT = ms2ns(300); DisplayEventDispatcher::DisplayEventDispatcher(const sp& looper, gui::ISurfaceComposer::VsyncSource vsyncSource, - EventRegistrationFlags eventRegistration) + EventRegistrationFlags eventRegistration, + const sp& layerHandle) : mLooper(looper), - mReceiver(vsyncSource, eventRegistration), + mReceiver(vsyncSource, eventRegistration, layerHandle), mWaitingForVsync(false), mLastVsyncCount(0), mLastScheduleVsyncTime(0) { diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp index c52fb6b7c3..6849a95d1e 100644 --- a/libs/gui/DisplayEventReceiver.cpp +++ b/libs/gui/DisplayEventReceiver.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "DisplayEventReceiver" + #include #include @@ -32,7 +34,8 @@ namespace android { // --------------------------------------------------------------------------- DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource, - EventRegistrationFlags eventRegistration) { + EventRegistrationFlags eventRegistration, + const sp& layerHandle) { sp sf(ComposerServiceAIDL::getComposerService()); if (sf != nullptr) { mEventConnection = nullptr; @@ -41,8 +44,8 @@ DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vs static_cast< gui::ISurfaceComposer::EventRegistration>( eventRegistration.get()), - &mEventConnection); - if (mEventConnection != nullptr) { + layerHandle, &mEventConnection); + if (status.isOk() && mEventConnection != nullptr) { mDataChannel = std::make_unique(); status = mEventConnection->stealReceiveChannel(mDataChannel.get()); if (!status.isOk()) { @@ -51,6 +54,8 @@ DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vs mDataChannel.reset(); mEventConnection.clear(); } + } else { + ALOGE("DisplayEventConnection creation failed: status=%s", status.toString8().c_str()); } } } diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 7aee882422..c5f9c38ca3 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -34,8 +35,9 @@ #include #include -#include #include +#include +#include #include #include #include @@ -191,6 +193,24 @@ const std::string& SurfaceControl::getName() const { return mName; } +std::shared_ptr SurfaceControl::getChoreographer() { + if (mChoreographer) { + return mChoreographer; + } + sp looper = Looper::getForThread(); + if (!looper.get()) { + ALOGE("%s: No looper prepared for thread", __func__); + return nullptr; + } + mChoreographer = std::make_shared(looper, getHandle()); + status_t result = mChoreographer->initialize(); + if (result != OK) { + ALOGE("Failed to initialize choreographer"); + mChoreographer = nullptr; + } + return mChoreographer; +} + sp SurfaceControl::getIGraphicBufferProducer() { getSurface(); diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index 597749acc4..981214212b 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -68,9 +68,15 @@ interface ISurfaceComposer { /** * Create a display event connection + * + * layerHandle + * Optional binder handle representing a Layer in SF to associate the new + * DisplayEventConnection with. This handle can be found inside a surface control after + * surface creation, see ISurfaceComposerClient::createSurface. Set to null if no layer + * association should be made. */ @nullable IDisplayEventConnection createDisplayEventConnection(VsyncSource vsyncSource, - EventRegistration eventRegistration); + EventRegistration eventRegistration, @nullable IBinder layerHandle); /** * Create a connection with SurfaceFlinger. diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h index 14a0e39813..f01c2a9e8e 100644 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h @@ -64,7 +64,7 @@ public: MOCK_METHOD(binder::Status, bootFinished, (), (override)); MOCK_METHOD(binder::Status, createDisplayEventConnection, (gui::ISurfaceComposer::VsyncSource, gui::ISurfaceComposer::EventRegistration, - sp*), + const sp& /*layerHandle*/, sp*), (override)); MOCK_METHOD(binder::Status, createConnection, (sp*), (override)); MOCK_METHOD(binder::Status, createDisplay, (const std::string&, bool, float, sp*), diff --git a/libs/gui/include/gui/Choreographer.h b/libs/gui/include/gui/Choreographer.h index 89a7058dd6..1df9b11432 100644 --- a/libs/gui/include/gui/Choreographer.h +++ b/libs/gui/include/gui/Choreographer.h @@ -73,7 +73,8 @@ public: }; static Context gChoreographers; - explicit Choreographer(const sp& looper) EXCLUDES(gChoreographers.lock); + explicit Choreographer(const sp& looper, const sp& layerHandle = nullptr) + EXCLUDES(gChoreographers.lock); void postFrameCallbackDelayed(AChoreographer_frameCallback cb, AChoreographer_frameCallback64 cb64, AChoreographer_vsyncCallback vsyncCallback, void* data, diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h index bf3a07b6b5..140efa6d97 100644 --- a/libs/gui/include/gui/DisplayEventDispatcher.h +++ b/libs/gui/include/gui/DisplayEventDispatcher.h @@ -26,7 +26,8 @@ public: explicit DisplayEventDispatcher(const sp& looper, gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - EventRegistrationFlags eventRegistration = {}); + EventRegistrationFlags eventRegistration = {}, + const sp& layerHandle = nullptr); status_t initialize(); void dispose(); diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h index 0f4907fcb9..7fd6c35c5e 100644 --- a/libs/gui/include/gui/DisplayEventReceiver.h +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -119,7 +119,8 @@ public: */ explicit DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - EventRegistrationFlags eventRegistration = {}); + EventRegistrationFlags eventRegistration = {}, + const sp& layerHandle = nullptr); /* * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h index 1d4fc7f06d..344b957ba7 100644 --- a/libs/gui/include/gui/SurfaceControl.h +++ b/libs/gui/include/gui/SurfaceControl.h @@ -36,6 +36,7 @@ namespace android { // --------------------------------------------------------------------------- +class Choreographer; class IGraphicBufferProducer; class Surface; class SurfaceComposerClient; @@ -80,6 +81,9 @@ public: int32_t getLayerId() const; const std::string& getName() const; + // TODO(b/267195698): Consider renaming. + std::shared_ptr getChoreographer(); + sp getIGraphicBufferProducer(); status_t clearLayerFrameStats() const; @@ -130,6 +134,7 @@ private: PixelFormat mFormat = PIXEL_FORMAT_NONE; uint32_t mCreateFlags = 0; uint64_t mFallbackFrameNumber = 100; + std::shared_ptr mChoreographer; }; }; // namespace android diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 9b2bf7ff31..babc197ae9 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -725,6 +725,7 @@ public: binder::Status createDisplayEventConnection( VsyncSource /*vsyncSource*/, EventRegistration /*eventRegistration*/, + const sp& /*layerHandle*/, sp* outConnection) override { *outConnection = nullptr; return binder::Status::ok(); diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 76e9416fec..5e79a5c13e 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -532,6 +532,12 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, const sp& connection) const { const auto throttleVsync = [&] { const auto& vsyncData = event.vsync.vsyncData; + if (connection->frameRate.isValid()) { + return !mVsyncSchedule->getTracker() + .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(), + connection->frameRate); + } + const auto expectedPresentTime = TimePoint::fromNs(vsyncData.preferredExpectedPresentationTime()); return !mEventThreadCallback.isVsyncTargetForUid(expectedPresentTime, diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index b86553bebe..aa27091908 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -97,6 +97,9 @@ public: const uid_t mOwnerUid; const EventRegistrationFlags mEventRegistration; + /** The frame rate set to the attached choreographer. */ + Fps frameRate; + private: virtual void onFirstRef(); EventThread* const mEventThread; diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 55fa402fa6..e853833bb9 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -32,6 +32,7 @@ #include #include "../Layer.h" +#include "EventThread.h" #include "LayerInfo.h" namespace android::scheduler { @@ -140,6 +141,22 @@ void LayerHistory::record(Layer* layer, nsecs_t presentTime, nsecs_t now, info->setLastPresentTime(presentTime, now, updateType, mModeChangePending, layerProps); + // Set frame rate to attached choreographer. + // TODO(b/260898223): Change to use layer hierarchy and handle frame rate vote. + if (updateType == LayerUpdateType::SetFrameRate) { + auto range = mAttachedChoreographers.equal_range(id); + auto it = range.first; + while (it != range.second) { + sp choreographerConnection = it->second.promote(); + if (choreographerConnection) { + choreographerConnection->frameRate = layer->getFrameRateForLayerTree().rate; + it++; + } else { + it = mAttachedChoreographers.erase(it); + } + } + } + // Activate layer if inactive. if (found == LayerStatus::LayerInInactiveMap) { mActiveLayerInfos.insert( @@ -294,6 +311,12 @@ float LayerHistory::getLayerFramerate(nsecs_t now, int32_t id) const { return 0.f; } +void LayerHistory::attachChoreographer(int32_t layerId, + const sp& choreographerConnection) { + std::lock_guard lock(mLock); + mAttachedChoreographers.insert({layerId, wp(choreographerConnection)}); +} + auto LayerHistory::findLayer(int32_t id) -> std::pair { // the layer could be in either the active or inactive map, try both auto it = mActiveLayerInfos.find(id); diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h index 5022906ff9..68e7030feb 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.h +++ b/services/surfaceflinger/Scheduler/LayerHistory.h @@ -27,6 +27,8 @@ #include #include +#include "EventThread.h" + #include "RefreshRateSelector.h" namespace android { @@ -80,6 +82,9 @@ public: // return the frames per second of the layer with the given sequence id. float getLayerFramerate(nsecs_t now, int32_t id) const; + void attachChoreographer(int32_t layerId, + const sp& choreographerConnection); + private: friend class LayerHistoryTest; friend class TestableScheduler; @@ -117,6 +122,10 @@ private: LayerInfos mActiveLayerInfos GUARDED_BY(mLock); LayerInfos mInactiveLayerInfos GUARDED_BY(mLock); + // Map keyed by layer ID (sequence) to choreographer connections. + std::unordered_multimap> mAttachedChoreographers + GUARDED_BY(mLock); + uint32_t mDisplayArea = 0; // Whether to emit systrace output and debug logs. diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index e6f46655fc..eed57ef4f1 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -47,6 +47,7 @@ #include "Display/DisplayMap.h" #include "EventThread.h" #include "FrameRateOverrideMappings.h" +#include "FrontEnd/LayerHandle.h" #include "OneShotTimer.h" #include "SurfaceFlingerProperties.h" #include "VSyncPredictor.h" @@ -232,15 +233,21 @@ ConnectionHandle Scheduler::createConnection(std::unique_ptr eventT } sp Scheduler::createConnectionInternal( - EventThread* eventThread, EventRegistrationFlags eventRegistration) { - return eventThread->createEventConnection([&] { resync(); }, eventRegistration); + EventThread* eventThread, EventRegistrationFlags eventRegistration, + const sp& layerHandle) { + int32_t layerId = static_cast(LayerHandle::getLayerId(layerHandle)); + auto connection = eventThread->createEventConnection([&] { resync(); }, eventRegistration); + mLayerHistory.attachChoreographer(layerId, connection); + return connection; } sp Scheduler::createDisplayEventConnection( - ConnectionHandle handle, EventRegistrationFlags eventRegistration) { + ConnectionHandle handle, EventRegistrationFlags eventRegistration, + const sp& layerHandle) { std::lock_guard lock(mConnectionsLock); RETURN_IF_INVALID_HANDLE(handle, nullptr); - return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration); + return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration, + layerHandle); } sp Scheduler::getEventConnection(ConnectionHandle handle) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index 8dc2def113..8c8fc21e09 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -147,7 +147,8 @@ public: std::chrono::nanoseconds readyDuration); sp createDisplayEventConnection( - ConnectionHandle, EventRegistrationFlags eventRegistration = {}); + ConnectionHandle, EventRegistrationFlags eventRegistration = {}, + const sp& layerHandle = nullptr); sp getEventConnection(ConnectionHandle); @@ -302,7 +303,8 @@ private: // Create a connection on the given EventThread. ConnectionHandle createConnection(std::unique_ptr); sp createConnectionInternal( - EventThread*, EventRegistrationFlags eventRegistration = {}); + EventThread*, EventRegistrationFlags eventRegistration = {}, + const sp& layerHandle = nullptr); // Update feature state machine to given state when corresponding timer resets or expires. void kernelIdleTimerCallback(TimerState) EXCLUDES(mDisplayLock); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6020aba4fd..4b3f9a1f7a 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1988,13 +1988,14 @@ status_t SurfaceFlinger::getDisplayDecorationSupport( // ---------------------------------------------------------------------------- sp SurfaceFlinger::createDisplayEventConnection( - gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) { + gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration, + const sp& layerHandle) { const auto& handle = vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle; - return mScheduler->createDisplayEventConnection(handle, eventRegistration); + return mScheduler->createDisplayEventConnection(handle, eventRegistration, layerHandle); } void SurfaceFlinger::scheduleCommit(FrameHint hint) { @@ -7455,9 +7456,9 @@ binder::Status SurfaceComposerAIDL::bootFinished() { binder::Status SurfaceComposerAIDL::createDisplayEventConnection( VsyncSource vsyncSource, EventRegistration eventRegistration, - sp* outConnection) { + const sp& layerHandle, sp* outConnection) { sp conn = - mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration); + mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration, layerHandle); if (conn == nullptr) { *outConnection = nullptr; return binderStatusFromStatusT(BAD_VALUE); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 1eb1fdaa48..e7d4f77c23 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -509,7 +509,8 @@ private: sp createDisplayEventConnection( gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - EventRegistrationFlags eventRegistration = {}); + EventRegistrationFlags eventRegistration = {}, + const sp& layerHandle = nullptr); status_t captureDisplay(const DisplayCaptureArgs&, const sp&); status_t captureDisplay(DisplayId, const sp&); @@ -1391,6 +1392,7 @@ public: binder::Status bootFinished() override; binder::Status createDisplayEventConnection( VsyncSource vsyncSource, EventRegistration eventRegistration, + const sp& layerHandle, sp* outConnection) override; binder::Status createConnection(sp* outClient) override; binder::Status createDisplay(const std::string& displayName, bool secure, -- cgit v1.2.3-59-g8ed1b