diff options
author | 2023-01-27 16:45:23 -0800 | |
---|---|---|
committer | 2023-02-01 15:12:42 -0800 | |
commit | 2248f52cd8102e5bc71c5c1dca7a85e90fea1276 (patch) | |
tree | a9a684b8a16b2298412d2c0ac2aa2d232b0f766a | |
parent | ba75fbf758e90610799975c7c11e15a85c8e614e (diff) |
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
-rw-r--r-- | libs/gui/Choreographer.cpp | 5 | ||||
-rw-r--r-- | libs/gui/DisplayEventDispatcher.cpp | 5 | ||||
-rw-r--r-- | libs/gui/DisplayEventReceiver.cpp | 11 | ||||
-rw-r--r-- | libs/gui/SurfaceControl.cpp | 22 | ||||
-rw-r--r-- | libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 8 | ||||
-rw-r--r-- | libs/gui/fuzzer/libgui_fuzzer_utils.h | 2 | ||||
-rw-r--r-- | libs/gui/include/gui/Choreographer.h | 3 | ||||
-rw-r--r-- | libs/gui/include/gui/DisplayEventDispatcher.h | 3 | ||||
-rw-r--r-- | libs/gui/include/gui/DisplayEventReceiver.h | 3 | ||||
-rw-r--r-- | libs/gui/include/gui/SurfaceControl.h | 5 | ||||
-rw-r--r-- | libs/gui/tests/Surface_test.cpp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/EventThread.cpp | 6 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/EventThread.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerHistory.cpp | 23 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerHistory.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/Scheduler.cpp | 15 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/Scheduler.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 4 |
19 files changed, 119 insertions, 24 deletions
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>& looper) - : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp), +Choreographer::Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle) + : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, {}, + layerHandle), mLooper(looper), mThreadId(std::this_thread::get_id()) { std::lock_guard<std::mutex> _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>& looper, gui::ISurfaceComposer::VsyncSource vsyncSource, - EventRegistrationFlags eventRegistration) + EventRegistrationFlags eventRegistration, + const sp<IBinder>& 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 <string.h> #include <utils/Errors.h> @@ -32,7 +34,8 @@ namespace android { // --------------------------------------------------------------------------- DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource, - EventRegistrationFlags eventRegistration) { + EventRegistrationFlags eventRegistration, + const sp<IBinder>& layerHandle) { sp<gui::ISurfaceComposer> 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<gui::BitTube>(); 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 <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Log.h> +#include <utils/Looper.h> #include <utils/threads.h> #include <binder/IPCThreadState.h> @@ -34,8 +35,9 @@ #include <ui/Rect.h> #include <ui/StaticDisplayInfo.h> -#include <gui/BufferQueueCore.h> #include <gui/BLASTBufferQueue.h> +#include <gui/BufferQueueCore.h> +#include <gui/Choreographer.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> @@ -191,6 +193,24 @@ const std::string& SurfaceControl::getName() const { return mName; } +std::shared_ptr<Choreographer> SurfaceControl::getChoreographer() { + if (mChoreographer) { + return mChoreographer; + } + sp<Looper> looper = Looper::getForThread(); + if (!looper.get()) { + ALOGE("%s: No looper prepared for thread", __func__); + return nullptr; + } + mChoreographer = std::make_shared<Choreographer>(looper, getHandle()); + status_t result = mChoreographer->initialize(); + if (result != OK) { + ALOGE("Failed to initialize choreographer"); + mChoreographer = nullptr; + } + return mChoreographer; +} + sp<IGraphicBufferProducer> 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<gui::IDisplayEventConnection>*), + const sp<IBinder>& /*layerHandle*/, sp<gui::IDisplayEventConnection>*), (override)); MOCK_METHOD(binder::Status, createConnection, (sp<gui::ISurfaceComposerClient>*), (override)); MOCK_METHOD(binder::Status, createDisplay, (const std::string&, bool, float, sp<IBinder>*), 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>& looper) EXCLUDES(gChoreographers.lock); + explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& 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>& looper, gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - EventRegistrationFlags eventRegistration = {}); + EventRegistrationFlags eventRegistration = {}, + const sp<IBinder>& 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<IBinder>& 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<Choreographer> getChoreographer(); + sp<IGraphicBufferProducer> 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<Choreographer> 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<IBinder>& /*layerHandle*/, sp<gui::IDisplayEventConnection>* 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<EventThreadConnection>& 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 <utility> #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<EventThreadConnection> 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<EventThreadConnection>& choreographerConnection) { + std::lock_guard lock(mLock); + mAttachedChoreographers.insert({layerId, wp<EventThreadConnection>(choreographerConnection)}); +} + auto LayerHistory::findLayer(int32_t id) -> std::pair<LayerStatus, LayerPair*> { // 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 <utility> #include <vector> +#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<EventThreadConnection>& 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<int32_t, wp<EventThreadConnection>> 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<EventThread> eventT } sp<EventThreadConnection> Scheduler::createConnectionInternal( - EventThread* eventThread, EventRegistrationFlags eventRegistration) { - return eventThread->createEventConnection([&] { resync(); }, eventRegistration); + EventThread* eventThread, EventRegistrationFlags eventRegistration, + const sp<IBinder>& layerHandle) { + int32_t layerId = static_cast<int32_t>(LayerHandle::getLayerId(layerHandle)); + auto connection = eventThread->createEventConnection([&] { resync(); }, eventRegistration); + mLayerHistory.attachChoreographer(layerId, connection); + return connection; } sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection( - ConnectionHandle handle, EventRegistrationFlags eventRegistration) { + ConnectionHandle handle, EventRegistrationFlags eventRegistration, + const sp<IBinder>& layerHandle) { std::lock_guard<std::mutex> lock(mConnectionsLock); RETURN_IF_INVALID_HANDLE(handle, nullptr); - return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration); + return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration, + layerHandle); } sp<EventThreadConnection> 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<IDisplayEventConnection> createDisplayEventConnection( - ConnectionHandle, EventRegistrationFlags eventRegistration = {}); + ConnectionHandle, EventRegistrationFlags eventRegistration = {}, + const sp<IBinder>& layerHandle = nullptr); sp<EventThreadConnection> getEventConnection(ConnectionHandle); @@ -302,7 +303,8 @@ private: // Create a connection on the given EventThread. ConnectionHandle createConnection(std::unique_ptr<EventThread>); sp<EventThreadConnection> createConnectionInternal( - EventThread*, EventRegistrationFlags eventRegistration = {}); + EventThread*, EventRegistrationFlags eventRegistration = {}, + const sp<IBinder>& 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<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection( - gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) { + gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration, + const sp<IBinder>& 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<IDisplayEventConnection>* outConnection) { + const sp<IBinder>& layerHandle, sp<IDisplayEventConnection>* outConnection) { sp<IDisplayEventConnection> 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<IDisplayEventConnection> createDisplayEventConnection( gui::ISurfaceComposer::VsyncSource vsyncSource = gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, - EventRegistrationFlags eventRegistration = {}); + EventRegistrationFlags eventRegistration = {}, + const sp<IBinder>& layerHandle = nullptr); status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&); status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&); @@ -1391,6 +1392,7 @@ public: binder::Status bootFinished() override; binder::Status createDisplayEventConnection( VsyncSource vsyncSource, EventRegistration eventRegistration, + const sp<IBinder>& layerHandle, sp<gui::IDisplayEventConnection>* outConnection) override; binder::Status createConnection(sp<gui::ISurfaceComposerClient>* outClient) override; binder::Status createDisplay(const std::string& displayName, bool secure, |