Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64db2bf1 authored by Chris Craik's avatar Chris Craik
Browse files

Clip buffer damage to viewport bounds

bug:27287946

Change-Id: Ief3ae9c2dd92196b7d09f1b9fadf009eb228d80a
parent 4876de16
Loading
Loading
Loading
Loading
+4 −27
Original line number Diff line number Diff line
@@ -296,12 +296,9 @@ void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const ClipBase* cli
        }
    }

    // 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 @@ void BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& sta
    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);
    }
}

+8 −0
Original line number Diff line number Diff line
@@ -54,6 +54,14 @@ Rect OffscreenBuffer::getTextureCoordinates() {
    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.
+2 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public:

    Rect getTextureCoordinates();

    void dirty(Rect dirtyArea);

    // must be called prior to rendering, to construct/update vertex buffer
    void updateMeshFromRegion();

+8 −0
Original line number Diff line number Diff line
@@ -55,6 +55,14 @@ TEST(OffscreenBuffer, getTextureCoordinates) {
    });
}

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;