Avoid excessive KGSL maps

Hook MIN_UNDEQUEUED_BUFFERS if possible to avoid thrashing kgsl
maps when render_ahead is being used

Bug: 143555869
Test: verified kgsl maps only happened once per buffer
Change-Id: I985fae0a9a7635be3a1cf6177186e5541a1169df
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 335bcdc..a362bd2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -139,20 +139,22 @@
     mAnimationContext->destroy();
 }
 
+static void setBufferCount(ANativeWindow* window, uint32_t extraBuffers) {
+    int query_value;
+    int err = window->query(window, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &query_value);
+    if (err != 0 || query_value < 0) {
+        ALOGE("window->query failed: %s (%d) value=%d", strerror(-err), err, query_value);
+        return;
+    }
+    auto min_undequeued_buffers = static_cast<uint32_t>(query_value);
+
+    int bufferCount = min_undequeued_buffers + 2 + extraBuffers;
+    native_window_set_buffer_count(window, bufferCount);
+}
+
 void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
     ATRACE_CALL();
 
-    if (window) {
-        mNativeSurface = std::make_unique<ReliableSurface>(window);
-        mNativeSurface->init();
-        if (enableTimeout) {
-            // TODO: Fix error handling & re-shorten timeout
-            ANativeWindow_setDequeueTimeout(window, 4000_ms);
-        }
-    } else {
-        mNativeSurface = nullptr;
-    }
-
     if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f) {
         mFixedRenderAhead = false;
         mRenderAheadCapacity = 1;
@@ -161,9 +163,24 @@
         mRenderAheadCapacity = mRenderAheadDepth;
     }
 
+    if (window) {
+        mNativeSurface = std::make_unique<ReliableSurface>(window);
+        mNativeSurface->init();
+        if (enableTimeout) {
+            // TODO: Fix error handling & re-shorten timeout
+            ANativeWindow_setDequeueTimeout(window, 4000_ms);
+        }
+        mNativeSurface->setExtraBufferCount(mRenderAheadCapacity);
+    } else {
+        mNativeSurface = nullptr;
+    }
+
     bool hasSurface = mRenderPipeline->setSurface(
-            mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior,
-            mRenderAheadCapacity);
+            mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);
+
+    if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) {
+        setBufferCount(mNativeSurface->getNativeWindow(), mRenderAheadCapacity);
+    }
 
     mFrameNumber = -1;