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

Commit 152f76ee authored by Chris Craik's avatar Chris Craik Committed by android-build-merger
Browse files

Prevent EndLayerOps when Begin was rejected

am: 3c53ec51

Change-Id: I075b68a1b7bdee4cbebd734748dd485ff6cd67b3
parents 46846727 3c53ec51
Loading
Loading
Loading
Loading
+37 −34
Original line number Original line Diff line number Diff line
@@ -149,26 +149,26 @@ int RecordingCanvas::saveLayer(float left, float top, float right, float bottom,


    // Map visible bounds back to layer space, and intersect with parameter bounds
    // Map visible bounds back to layer space, and intersect with parameter bounds
    Rect layerBounds = visibleBounds;
    Rect layerBounds = visibleBounds;
    if (CC_LIKELY(!layerBounds.isEmpty())) {
        // if non-empty, can safely map by the inverse transform
        Matrix4 inverse;
        Matrix4 inverse;
        inverse.loadInverse(*previous.transform);
        inverse.loadInverse(*previous.transform);
        inverse.mapRect(layerBounds);
        inverse.mapRect(layerBounds);
        layerBounds.doIntersect(unmappedBounds);
        layerBounds.doIntersect(unmappedBounds);
    }


    int saveValue = mState.save((int) flags);
    int saveValue = mState.save((int) flags);
    Snapshot& snapshot = *mState.writableSnapshot();
    Snapshot& snapshot = *mState.writableSnapshot();


    // layerBounds is in original bounds space, but clipped by current recording clip
    // layerBounds is in original bounds space, but clipped by current recording clip
    if (layerBounds.isEmpty() || unmappedBounds.isEmpty()) {
    if (!layerBounds.isEmpty() && !unmappedBounds.isEmpty()) {
        // Don't bother recording layer, since it's been rejected
        if (CC_LIKELY(clippedLayer)) {
            snapshot.resetClip(0, 0, 0, 0);
        }
        return saveValue;
    }

        if (CC_LIKELY(clippedLayer)) {
        if (CC_LIKELY(clippedLayer)) {
        auto previousClip = getRecordedClip(); // note: done before new snapshot's clip has changed
            auto previousClip = getRecordedClip(); // capture before new snapshot clip has changed

            if (addOp(alloc().create_trivial<BeginLayerOp>(
                    unmappedBounds,
                    *previous.transform, // transform to *draw* with
                    previousClip, // clip to *draw* with
                    refPaint(paint))) >= 0) {
                snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer;
                snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer;
                snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight());
                snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight());
                snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f);
                snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f);
@@ -177,22 +177,25 @@ int RecordingCanvas::saveLayer(float left, float top, float right, float bottom,
                clip.translate(-unmappedBounds.left, -unmappedBounds.top);
                clip.translate(-unmappedBounds.left, -unmappedBounds.top);
                snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
                snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
                snapshot.roundRectClipState = nullptr;
                snapshot.roundRectClipState = nullptr;

                return saveValue;
        addOp(alloc().create_trivial<BeginLayerOp>(
            }
                unmappedBounds,
                *previous.transform, // transform to *draw* with
                previousClip, // clip to *draw* with
                refPaint(paint)));
        } else {
        } else {
        snapshot.flags |= Snapshot::kFlagIsLayer;
            if (addOp(alloc().create_trivial<BeginUnclippedLayerOp>(

        addOp(alloc().create_trivial<BeginUnclippedLayerOp>(
                    unmappedBounds,
                    unmappedBounds,
                    *mState.currentSnapshot()->transform,
                    *mState.currentSnapshot()->transform,
                    getRecordedClip(),
                    getRecordedClip(),
                refPaint(paint)));
                    refPaint(paint))) >= 0) {
                snapshot.flags |= Snapshot::kFlagIsLayer;
                return saveValue;
            }
        }
    }
    }


    // Layer not needed, so skip recording it...
    if (CC_LIKELY(clippedLayer)) {
        // ... and set empty clip to reject inner content, if possible
        snapshot.resetClip(0, 0, 0, 0);
    }
    return saveValue;
    return saveValue;
}
}


@@ -619,7 +622,7 @@ void RecordingCanvas::callDrawGLFunction(Functor* functor,
            functor));
            functor));
}
}


size_t RecordingCanvas::addOp(RecordedOp* op) {
int RecordingCanvas::addOp(RecordedOp* op) {
    // skip op with empty clip
    // skip op with empty clip
    if (op->localClip && op->localClip->rect.isEmpty()) {
    if (op->localClip && op->localClip->rect.isEmpty()) {
        // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
        // NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
+1 −1
Original line number Original line Diff line number Diff line
@@ -208,7 +208,7 @@ private:
    void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
    void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);




    size_t addOp(RecordedOp* op);
    int addOp(RecordedOp* op);
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// lazy object copy
// lazy object copy
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
+15 −0
Original line number Original line Diff line number Diff line
@@ -545,6 +545,21 @@ TEST(RecordingCanvas, saveLayer_rotateClipped) {
    EXPECT_EQ(3, count);
    EXPECT_EQ(3, count);
}
}


TEST(RecordingCanvas, saveLayer_rejectBegin) {
    auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
        canvas.save(SaveFlags::MatrixClip);
        canvas.translate(0, -20); // avoid identity case
        // empty clip rect should force layer + contents to be rejected
        canvas.clipRect(0, -20, 200, -20, SkRegion::kIntersect_Op);
        canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
        canvas.drawRect(0, 0, 200, 200, SkPaint());
        canvas.restore();
        canvas.restore();
    });

    ASSERT_EQ(0u, dl->getOps().size()) << "Begin/Rect/End should all be rejected.";
}

TEST(RecordingCanvas, drawRenderNode_rejection) {
TEST(RecordingCanvas, drawRenderNode_rejection) {
    auto child = TestUtils::createNode(50, 50, 150, 150,
    auto child = TestUtils::createNode(50, 50, 150, 150,
            [](RenderProperties& props, RecordingCanvas& canvas) {
            [](RenderProperties& props, RecordingCanvas& canvas) {