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;