Clip buffer damage to viewport bounds
bug:27287946
Change-Id: Ief3ae9c2dd92196b7d09f1b9fadf009eb228d80a
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index 5f689b4..c147384 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -296,12 +296,9 @@
}
}
- // dirty offscreenbuffer
- if (dirtyBounds && mRenderTarget.offscreenBuffer) {
- // register layer damage to draw-back region
- android::Rect dirty(dirtyBounds->left, dirtyBounds->top,
- dirtyBounds->right, dirtyBounds->bottom);
- mRenderTarget.offscreenBuffer->region.orSelf(dirty);
+ if (dirtyBounds) {
+ // dirty offscreenbuffer if present
+ dirtyRenderTarget(*dirtyBounds);
}
}
@@ -329,29 +326,9 @@
mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info);
}
-#define VALIDATE_RECT_ARG(rect, arg) \
- ((isnanf(rect.arg) || rect.arg < -10000 || rect.arg > 10000) ? (\
- ALOGW("suspicious " #rect "." #arg "! %f", rect.arg),\
- false) : true)
-
-#define VALIDATE_RECT(rect) \
- VALIDATE_RECT_ARG(rect, bottom) & \
- VALIDATE_RECT_ARG(rect, left) & \
- VALIDATE_RECT_ARG(rect, top) & \
- VALIDATE_RECT_ARG(rect, right)
-
void BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) {
if (mRenderTarget.offscreenBuffer) {
- bool valid = VALIDATE_RECT(uiDirty);
- android::Rect dirty;
- if (valid) {
- dirty = android::Rect(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom);
- } else {
- dirty = android::Rect(
- mRenderTarget.offscreenBuffer->viewportWidth,
- mRenderTarget.offscreenBuffer->viewportHeight);
- }
- mRenderTarget.offscreenBuffer->region.orSelf(dirty);
+ mRenderTarget.offscreenBuffer->dirty(uiDirty);
}
}
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index 54f38e8..5f984b5 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -54,6 +54,14 @@
return Rect(0, viewportHeight * texY, viewportWidth * texX, 0);
}
+void OffscreenBuffer::dirty(Rect dirtyArea) {
+ dirtyArea.doIntersect(0, 0, viewportWidth, viewportHeight);
+ if (!dirtyArea.isEmpty()) {
+ region.orSelf(android::Rect(dirtyArea.left, dirtyArea.top,
+ dirtyArea.right, dirtyArea.bottom));
+ }
+}
+
void OffscreenBuffer::updateMeshFromRegion() {
// avoid T-junctions as they cause artifacts in between the resultant
// geometry when complex transforms occur.
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.h b/libs/hwui/renderstate/OffscreenBufferPool.h
index 94155ef..089f131 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.h
+++ b/libs/hwui/renderstate/OffscreenBufferPool.h
@@ -48,6 +48,8 @@
Rect getTextureCoordinates();
+ void dirty(Rect dirtyArea);
+
// must be called prior to rendering, to construct/update vertex buffer
void updateMeshFromRegion();
diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
index 2fd8795..0c6eb57 100644
--- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp
@@ -55,6 +55,14 @@
});
}
+TEST(OffscreenBuffer, dirty) {
+ TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
+ OffscreenBuffer buffer(thread.renderState(), Caches::getInstance(), 256u, 256u);
+ buffer.dirty(Rect(-100, -100, 100, 100));
+ EXPECT_EQ(android::Rect(100, 100), buffer.region.getBounds());
+ });
+}
+
TEST(OffscreenBufferPool, construct) {
TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) {
OffscreenBufferPool pool;