Bag of scheduling tweaks
Bug: 15118640
* Prevent over-stuffing the queue by dropping frames
* Prevent double-drawing in one pulse by RT by deferring
vsync registration until post-draw so that it catches
the next vsync pulse instead of the current one
* Bias vsync race condition towards the UI thread
* Fix queueDelay to actually work
Change-Id: Ibf584258bd93ebcbba058bd976dc8b307f1c6155
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 215d294..4412584 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -44,6 +44,7 @@
RenderTask* next();
void queue(RenderTask* task);
+ void queueAtFront(RenderTask* task);
RenderTask* peek();
void remove(RenderTask* task);
@@ -66,12 +67,16 @@
// RenderThread takes complete ownership of tasks that are queued
// and will delete them after they are run
ANDROID_API void queue(RenderTask* task);
+ ANDROID_API void queueAtFront(RenderTask* task);
void queueDelayed(RenderTask* task, int delayMs);
void remove(RenderTask* task);
// Mimics android.view.Choreographer
void postFrameCallback(IFrameCallback* callback);
void removeFrameCallback(IFrameCallback* callback);
+ // If the callback is currently registered, it will be pushed back until
+ // the next vsync. If it is not currently registered this does nothing.
+ void pushBackFrameCallback(IFrameCallback* callback);
TimeLord& timeLord() { return mTimeLord; }
@@ -87,8 +92,9 @@
void initializeDisplayEventReceiver();
static int displayEventReceiverCallback(int fd, int events, void* data);
- void drainDisplayEventQueue();
+ void drainDisplayEventQueue(bool skipCallbacks = false);
void dispatchFrameCallbacks();
+ void requestVsync();
// Returns the next task to be run. If this returns NULL nextWakeup is set
// to the time to requery for the nextTask to run. mNextWakeup is also
@@ -104,6 +110,11 @@
DisplayEventReceiver* mDisplayEventReceiver;
bool mVsyncRequested;
std::set<IFrameCallback*> mFrameCallbacks;
+ // We defer the actual registration of these callbacks until
+ // both mQueue *and* mDisplayEventReceiver have been drained off all
+ // immediate events. This makes sure that we catch the next vsync, not
+ // the previous one
+ std::set<IFrameCallback*> mPendingRegistrationFrameCallbacks;
bool mFrameCallbackTaskPending;
DispatchFrameCallbacks* mFrameCallbackTask;