Merge "Add forceDrawNextFrame function for HardwareRenderer" into tm-dev am: 3e3c3ab2da

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17263076

Change-Id: Iaf253798ddd4a0d752a4138aeff906ee8adb8a74
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index fd4bed1..61dc136 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -849,6 +849,14 @@
         nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
     }
 
+    /**
+     * Force the new frame to draw, ensuring the UI draw request will attempt a draw this vsync.
+     * @hide
+     */
+    public void forceDrawNextFrame() {
+        nForceDrawNextFrame(mNativeProxy);
+    }
+
     /** @hide */
     public void setPictureCaptureCallback(@Nullable PictureCapturedCallback callback) {
         nSetPictureCaptureCallback(mNativeProxy, callback);
@@ -1423,6 +1431,8 @@
     private static native void nSetContentDrawBounds(long nativeProxy, int left,
             int top, int right, int bottom);
 
+    private static native void nForceDrawNextFrame(long nativeProxy);
+
     private static native void nSetPictureCaptureCallback(long nativeProxy,
             PictureCapturedCallback callback);
 
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 30ca7d15..86ae399 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -69,7 +69,6 @@
 bool Properties::enableHighContrastText = false;
 
 bool Properties::waitForGpuCompletion = false;
-bool Properties::forceDrawFrame = false;
 
 bool Properties::filterOutTestOverhead = false;
 bool Properties::disableVsync = false;
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index cc9094c..6b8f439 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -100,6 +100,8 @@
 
     int stretchEffectCount = 0;
 
+    bool forceDrawFrame = false;
+
     struct Out {
         bool hasFunctors = false;
         // This is only updated if evaluateAnimations is true
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 3122e72..bf5bc30 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -267,7 +267,8 @@
 }
 
 static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
-        jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
+                                                          jlong proxyPtr, jlongArray frameInfo,
+                                                          jint frameInfoSize) {
     LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
                         "Mismatched size expectations, given %d expected %zu", frameInfoSize,
                         UI_THREAD_FRAME_INFO_SIZE);
@@ -421,6 +422,12 @@
     proxy->setContentDrawBounds(left, top, right, bottom);
 }
 
+static void android_view_ThreadedRenderer_forceDrawNextFrame(JNIEnv* env, jobject clazz,
+                                                             jlong proxyPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->forceDrawNextFrame();
+}
+
 class JGlobalRefHolder {
 public:
     JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
@@ -943,6 +950,7 @@
         {"nDrawRenderNode", "(JJ)V", (void*)android_view_ThreadedRendererd_drawRenderNode},
         {"nSetContentDrawBounds", "(JIIII)V",
          (void*)android_view_ThreadedRenderer_setContentDrawBounds},
+        {"nForceDrawNextFrame", "(J)V", (void*)android_view_ThreadedRenderer_forceDrawNextFrame},
         {"nSetPictureCaptureCallback",
          "(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
          (void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index bdad772..122c77f 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -390,7 +390,7 @@
         return;
     }
 
-    if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
+    if (CC_LIKELY(mSwapHistory.size() && !info.forceDrawFrame)) {
         nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
         SwapHistory& lastSwap = mSwapHistory.back();
         nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 2357dfe..59c914f 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -148,6 +148,8 @@
     bool canDrawThisFrame;
     {
         TreeInfo info(TreeInfo::MODE_FULL, *mContext);
+        info.forceDrawFrame = mForceDrawFrame;
+        mForceDrawFrame = false;
         canUnblockUiThread = syncFrameState(info);
         canDrawThisFrame = info.out.canDrawThisFrame;
 
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 25ed935..d6fc292 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -88,6 +88,8 @@
         mFrameCompleteCallback = std::move(callback);
     }
 
+    void forceDrawNextFrame() { mForceDrawFrame = true; }
+
 private:
     class HintSessionWrapper {
     public:
@@ -132,6 +134,8 @@
     nsecs_t mLastDequeueBufferDuration = 0;
     nsecs_t mLastTargetWorkDuration = 0;
     std::optional<HintSessionWrapper> mHintSessionWrapper;
+
+    bool mForceDrawFrame = false;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 65b51b4..df50557 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -137,6 +137,10 @@
     return mDrawFrameTask.frameInfo();
 }
 
+void RenderProxy::forceDrawNextFrame() {
+    mDrawFrameTask.forceDrawNextFrame();
+}
+
 int RenderProxy::syncAndDrawFrame() {
     return mDrawFrameTask.drawFrame();
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 5e2b457..b96b164 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -86,6 +86,7 @@
     void setOpaque(bool opaque);
     void setColorMode(ColorMode mode);
     int64_t* frameInfo();
+    void forceDrawNextFrame();
     int syncAndDrawFrame();
     void destroy();
 
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index de2c621..613a6ae 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -104,7 +104,6 @@
         // If we're reporting GPU memory usage we need to first start with a clean slate
         RenderProxy::purgeCaches();
     }
-    Properties::forceDrawFrame = true;
     TestContext testContext;
     testContext.setRenderOffscreen(opts.renderOffscreen);
 
@@ -144,6 +143,7 @@
             .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID,
                       UiFrameInfoBuilder::UNKNOWN_DEADLINE,
                       UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL);
+        proxy->forceDrawNextFrame();
         proxy->syncAndDrawFrame();
     }
 
@@ -163,6 +163,7 @@
                           UiFrameInfoBuilder::UNKNOWN_DEADLINE,
                           UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL);
             scene->doFrame(i);
+            proxy->forceDrawNextFrame();
             proxy->syncAndDrawFrame();
         }
         if (opts.reportFrametimeWeight) {