Add back render-ahead support
Currently only supported in the EGL path.
Vulkan support Coming Soon
Bug: 127822449
Test: trace of hwuimacro
Change-Id: Iac2b039e11d964aab5b8ca1bdf2a5430b187e2ea
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index baa41c1..4808d68 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -111,6 +111,7 @@
rootRenderNode->makeRoot();
mRenderNodes.emplace_back(rootRenderNode);
mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
+ setRenderAheadDepth(Properties::defaultRenderAhead);
}
CanvasContext::~CanvasContext() {
@@ -159,6 +160,7 @@
if (hasSurface) {
mHaveNewSurface = true;
mSwapHistory.clear();
+ applyRenderAheadSettings();
} else {
mRenderThread.removeFrameCallback(this);
mGenerationID++;
@@ -423,6 +425,12 @@
waitOnFences();
+ if (mRenderAheadDepth) {
+ auto presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+ (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
+ native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
+ }
+
bool requireSwap = false;
bool didSwap =
mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -636,6 +644,28 @@
return width == mLastFrameWidth && height == mLastFrameHeight;
}
+void CanvasContext::applyRenderAheadSettings() {
+ if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
+ // TODO: Fix SkiaVulkan's assumptions on buffer counts. And SIGBUS crashes.
+ mRenderAheadDepth = 0;
+ return;
+ }
+ if (mNativeSurface) {
+ native_window_set_buffer_count(mNativeSurface.get(), 3 + mRenderAheadDepth);
+ if (!mRenderAheadDepth) {
+ native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
+ }
+ }
+}
+
+void CanvasContext::setRenderAheadDepth(int renderAhead) {
+ if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+ return;
+ }
+ mRenderAheadDepth = renderAhead;
+ applyRenderAheadSettings();
+}
+
SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
if (frame.width() != mLastFrameWidth || frame.height() != mLastFrameHeight) {
// can't rely on prior content of window if viewport size changes