drm_hwcomposer: limit maximum depth of display composition queue

SurfaceFlinger will destroy our layer handles if we don't use them after about
a second. To get around this issue, we block SurfaceFlinger on hwc_set if the
display composition queue is getting too large. This often happens during
the init of the GLWorker or during heavy GPU usage.

Change-Id: Idb4a3a81e0d3a2caf7f94e5515a19ec16a1c67e3
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 7f43503..2021923 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -25,6 +25,7 @@
 
 #include <algorithm>
 #include <pthread.h>
+#include <sched.h>
 #include <sstream>
 #include <stdlib.h>
 #include <time.h>
@@ -35,6 +36,8 @@
 #include <sync/sync.h>
 #include <utils/Trace.h>
 
+#define DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH 3
+
 namespace android {
 
 DrmDisplayCompositor::DrmDisplayCompositor()
@@ -123,6 +126,14 @@
     return ret;
   }
 
+  // Block the queue if it gets too large. Otherwise, SurfaceFlinger will start
+  // to eat our buffer handles when we get about 1 second behind.
+  while (composite_queue_.size() >= DRM_DISPLAY_COMPOSITOR_MAX_QUEUE_DEPTH) {
+    pthread_mutex_unlock(&lock_);
+    sched_yield();
+    pthread_mutex_lock(&lock_);
+  }
+
   composite_queue_.push(std::move(composition));
 
   ret = pthread_mutex_unlock(&lock_);