[AChoreographer] Add private api that decouples from ALooper.
For ease of use by HWUI, we'll get rid of the reliance of a thread-local
ALooper:
* Rather than using AChoreographer_getInstance to access a thread-local
AChoreographer instance, the caller will be expected to create and
destroy its own instnace.
* For use by HWUI's own looper instance, _getFd() will expose the
underlying file descriptor from which events can be listened. The
corresponding choreographer combined callback can be called to flush
pending display events.
Bug: 136262896
Test: builds
Change-Id: I94f102da22974cbad37f21a68d2f04ac0cec5c78
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 7e71ede..1f77393 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -56,6 +56,7 @@
class Choreographer : public DisplayEventDispatcher, public MessageHandler {
public:
+ explicit Choreographer(const sp<Looper>& looper);
void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
AChoreographer_frameCallback64 cb64, void* data, nsecs_t delay);
void registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data);
@@ -68,12 +69,9 @@
virtual void handleMessage(const Message& message) override;
static Choreographer* getForThread();
-
-protected:
virtual ~Choreographer() = default;
private:
- explicit Choreographer(const sp<Looper>& looper);
Choreographer(const Choreographer&) = delete;
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
@@ -132,14 +130,22 @@
}
if (callback.dueTime <= now) {
if (std::this_thread::get_id() != mThreadId) {
- Message m{MSG_SCHEDULE_VSYNC};
- mLooper->sendMessage(this, m);
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_VSYNC};
+ mLooper->sendMessage(this, m);
+ } else {
+ scheduleVsync();
+ }
} else {
scheduleVsync();
}
} else {
- Message m{MSG_SCHEDULE_CALLBACKS};
- mLooper->sendMessageDelayed(delay, this, m);
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_CALLBACKS};
+ mLooper->sendMessageDelayed(delay, this, m);
+ } else {
+ scheduleCallbacks();
+ }
}
}
@@ -238,7 +244,7 @@
/* Glue for the NDK interface */
-using android::Choreographer;
+using namespace android;
static inline Choreographer* AChoreographer_to_Choreographer(AChoreographer* choreographer) {
return reinterpret_cast<Choreographer*>(choreographer);
@@ -281,3 +287,32 @@
AChoreographer_refreshRateCallback callback) {
AChoreographer_to_Choreographer(choreographer)->unregisterRefreshRateCallback(callback);
}
+
+AChoreographer* AChoreographer_create() {
+ Choreographer* choreographer = new Choreographer(nullptr);
+ status_t result = choreographer->initialize();
+ if (result != OK) {
+ ALOGW("Failed to initialize");
+ return nullptr;
+ }
+ return Choreographer_to_AChoreographer(choreographer);
+}
+
+void AChoreographer_destroy(AChoreographer* choreographer) {
+ if (choreographer == nullptr) {
+ return;
+ }
+
+ delete AChoreographer_to_Choreographer(choreographer);
+}
+
+int AChoreographer_getFd(AChoreographer* choreographer) {
+ return AChoreographer_to_Choreographer(choreographer)->getFd();
+}
+
+void AChoreographer_handlePendingEvents(AChoreographer* choreographer, void* data) {
+ // Pass dummy fd and events args to handleEvent, since the underlying
+ // DisplayEventDispatcher doesn't need them outside of validating that a
+ // Looper instance didn't break, but these args circumvent those checks.
+ AChoreographer_to_Choreographer(choreographer)->handleEvent(-1, Looper::EVENT_INPUT, data);
+}