Add support for render-ahead
For periods of time during which latency is less important
allow a client to request a deeper render-ahead pipeline.
The latency tradeoff results in less overall visual jank
Test: none, only used by macrobench
Change-Id: I516203b70bdc75b6415fa08bf9c4fb1b598b0102
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f4d8051..609d26c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -17,6 +17,7 @@
#include "CanvasContext.h"
#include <GpuMemoryTracker.h>
+#include "../Properties.h"
#include "AnimationContext.h"
#include "Caches.h"
#include "EglManager.h"
@@ -34,7 +35,6 @@
#include "renderstate/Stencil.h"
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
-#include "../Properties.h"
#include <cutils/properties.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -194,6 +194,7 @@
if (hasSurface) {
mHaveNewSurface = true;
mSwapHistory.clear();
+ updateBufferCount();
} else {
mRenderThread.removeFrameCallback(this);
}
@@ -427,6 +428,9 @@
waitOnFences();
+ frame.setPresentTime(mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+ (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)));
+
bool requireSwap = false;
bool didSwap =
mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -705,6 +709,26 @@
return mFrameNumber;
}
+void overrideBufferCount(const sp<Surface>& surface, int bufferCount) {
+ struct SurfaceExposer : Surface {
+ using Surface::setBufferCount;
+ };
+ // Protected is just a sign, not a cop
+ ((*surface.get()).*&SurfaceExposer::setBufferCount)(bufferCount);
+}
+
+void CanvasContext::updateBufferCount() {
+ overrideBufferCount(mNativeSurface, 3 + mRenderAheadDepth);
+}
+
+void CanvasContext::setRenderAheadDepth(int renderAhead) {
+ if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+ return;
+ }
+ mRenderAheadDepth = renderAhead;
+ updateBufferCount();
+}
+
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