diff options
author | 2022-03-18 17:42:15 -0500 | |
---|---|---|
committer | 2022-03-22 18:08:38 -0500 | |
commit | adba0b18617163f3e8a26928a2063e1a48e85ccf (patch) | |
tree | e79e7b09227eb22f7a7072e060ad67588845fef3 | |
parent | b3c1d1984edbd827a069ea5264f1c31ec9f98b5d (diff) |
Add forceDrawNextFrame function for HardwareRenderer
The forceDraw flag in HardwareRenderer will ensure a frame is drawn when
requested even if it would end up drawing multiple frames in a single
vsync.
This is to help blast sync when we want to synchronize the
buffer. We want to make sure we are guaranteed a callback since we don't
want to wait for retries, especially in the case when trying to synchronize
multiple buffers.
There was already a global flag to handle this, but would use the flag
for all draws. This new function is set per draw so once a frame is
drawn it's unset. The global flag was only used for tests so updated the
test to set the flag before every draw and deleted the global property.
Test: Underlying code was in place. This is just piping a new setter. No
usages yet.
Test: TestSceneRunner
Bug: 200284684
Change-Id: Ie1c9950cabb7331cfed1721564a51a1a15cd1624
-rw-r--r-- | graphics/java/android/graphics/HardwareRenderer.java | 10 | ||||
-rw-r--r-- | libs/hwui/Properties.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/TreeInfo.h | 2 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 10 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 1 | ||||
-rw-r--r-- | libs/hwui/tests/macrobench/TestSceneRunner.cpp | 3 |
10 files changed, 35 insertions, 4 deletions
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index fd4bed19e927..61dc136e8d65 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -849,6 +849,14 @@ public class HardwareRenderer { 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 @@ public class HardwareRenderer { 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 30ca7d155c4c..86ae3995eeed 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -69,7 +69,6 @@ RenderPipelineType Properties::sRenderPipelineType = RenderPipelineType::NotInit 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 cc9094c8afe9..6b8f43946a74 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -100,6 +100,8 @@ public: 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 27865b3972d7..7a8ddfba949b 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -259,7 +259,8 @@ static void android_view_ThreadedRenderer_setIsHighEndGfx(JNIEnv* env, jobject c } 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); @@ -413,6 +414,12 @@ static void android_view_ThreadedRenderer_setContentDrawBounds(JNIEnv* env, 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) {} @@ -935,6 +942,7 @@ static const JNINativeMethod gMethods[] = { {"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 bdad7727071f..122c77f3dadc 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -390,7 +390,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t sy 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 2357dfec72a6..59c914f0198c 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -148,6 +148,8 @@ void DrawFrameTask::run() { 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 25ed935b7a76..d6fc292d5900 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -88,6 +88,8 @@ public: mFrameCompleteCallback = std::move(callback); } + void forceDrawNextFrame() { mForceDrawFrame = true; } + private: class HintSessionWrapper { public: @@ -132,6 +134,8 @@ private: 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 026699c63e16..57ef4f4f8f60 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -133,6 +133,10 @@ int64_t* RenderProxy::frameInfo() { 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 491dbd72a14d..0f5a41cfbe38 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -82,6 +82,7 @@ public: 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 de2c6214088d..613a6aee3a5b 100644 --- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp +++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp @@ -104,7 +104,6 @@ static void doRun(const TestScene::Info& info, const TestScene::Options& opts, i // 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 @@ static void doRun(const TestScene::Info& info, const TestScene::Options& opts, i .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID, UiFrameInfoBuilder::UNKNOWN_DEADLINE, UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL); + proxy->forceDrawNextFrame(); proxy->syncAndDrawFrame(); } @@ -163,6 +163,7 @@ static void doRun(const TestScene::Info& info, const TestScene::Options& opts, i UiFrameInfoBuilder::UNKNOWN_DEADLINE, UiFrameInfoBuilder::UNKNOWN_FRAME_INTERVAL); scene->doFrame(i); + proxy->forceDrawNextFrame(); proxy->syncAndDrawFrame(); } if (opts.reportFrametimeWeight) { |