renderthread: add EGL_EXT_buffer_age support
EGL_EXT_buffer_age is better than EGL_BUFFER_PRESERVED
because it can save memory bandwidth used to blit
back buffer into front buffer.
Change-Id: I2fea0ee08dc7dd66e348b04dd694d075d509d01b
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6dfb6e8..ea73387 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -98,6 +98,9 @@
setSurface(nullptr);
}
mHaveNewSurface = false;
+ if (mEglManager.useBufferAgeExt()) {
+ mDirtyHistory.prepend(Rect(dirty));
+ }
}
void CanvasContext::requireSurface() {
@@ -227,6 +230,8 @@
"drawRenderNode called on a context with no canvas or surface!");
SkRect dirty;
+ bool useBufferAgeExt = mEglManager.useBufferAgeExt();
+ Rect patchedDirty;
mDamageAccumulator.finish(&dirty);
// TODO: Re-enable after figuring out cause of b/22592975
@@ -237,12 +242,18 @@
mCurrentFrameInfo->markIssueDrawCommandsStart();
- EGLint width, height;
- mEglManager.beginFrame(mEglSurface, &width, &height);
+ EGLint width, height, framebufferAge;
+ mEglManager.beginFrame(mEglSurface, &width, &height, &framebufferAge);
+
+ if (useBufferAgeExt && mHaveNewSurface) {
+ mDirtyHistory.clear();
+ }
+
if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
mCanvas->setViewport(width, height);
dirty.setEmpty();
} else if (!mBufferPreserved || mHaveNewSurface) {
+ mDirtyHistory.clear();
dirty.setEmpty();
} else {
if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) {
@@ -253,9 +264,14 @@
profiler().unionDirty(&dirty);
}
- if (!dirty.isEmpty()) {
- mCanvas->prepareDirty(dirty.fLeft, dirty.fTop,
- dirty.fRight, dirty.fBottom, mOpaque);
+ patchedDirty = dirty;
+ if (useBufferAgeExt && !dirty.isEmpty()) {
+ patchedDirty = mDirtyHistory.unionWith(Rect(dirty), framebufferAge-1);
+ }
+
+ if (!patchedDirty.isEmpty()) {
+ mCanvas->prepareDirty(patchedDirty.left, patchedDirty.top,
+ patchedDirty.right, patchedDirty.bottom, mOpaque);
} else {
mCanvas->prepare(mOpaque);
}