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
diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp
index 6b25b26..99bf6ba 100644
--- a/libs/gui/Choreographer.cpp
+++ b/libs/gui/Choreographer.cpp
@@ -101,8 +101,9 @@
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 501e69a..8a88377 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -37,9 +37,10 @@
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 c52fb6b..6849a95 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 @@
// ---------------------------------------------------------------------------
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 @@
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 @@
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 7aee882..c5f9c38 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 @@
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 597749a..9812142 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -68,9 +68,15 @@
/**
* 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 14a0e39..f01c2a9 100644
--- a/libs/gui/fuzzer/libgui_fuzzer_utils.h
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -64,7 +64,7 @@
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 89a7058..1df9b11 100644
--- a/libs/gui/include/gui/Choreographer.h
+++ b/libs/gui/include/gui/Choreographer.h
@@ -73,7 +73,8 @@
};
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 bf3a07b..140efa6 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -26,7 +26,8 @@
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 0f4907f..7fd6c35 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -119,7 +119,8 @@
*/
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 1d4fc7f..344b957 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -36,6 +36,7 @@
// ---------------------------------------------------------------------------
+class Choreographer;
class IGraphicBufferProducer;
class Surface;
class SurfaceComposerClient;
@@ -80,6 +81,9 @@
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 @@
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 9b2bf7f..babc197 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -725,6 +725,7 @@
binder::Status createDisplayEventConnection(
VsyncSource /*vsyncSource*/, EventRegistration /*eventRegistration*/,
+ const sp<IBinder>& /*layerHandle*/,
sp<gui::IDisplayEventConnection>* outConnection) override {
*outConnection = nullptr;
return binder::Status::ok();