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

Commit a204848b authored by Chris Craik's avatar Chris Craik
Browse files

Create first class unbounded ColorOp

bug:27810783

Previous drawColor->drawPaint conversion failed to preserve unbounded
nature of drawColor from old pipeline.

Change-Id: Ifd7a7b9d645f0887e252e48ca95d3195ee31615f
parent 1f6bdbca
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -506,6 +506,22 @@ void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRe
    renderer.renderGlop(state, glop);
}

void BakedOpDispatcher::onColorOp(BakedOpRenderer& renderer, const ColorOp& op, const BakedOpState& state) {
    SkPaint paint;
    paint.setColor(op.color);
    paint.setXfermodeMode(op.mode);

    Glop glop;
    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
            .setRoundRectClipState(state.roundRectClipState)
            .setMeshUnitQuad()
            .setFillPaint(paint, state.alpha)
            .setTransform(Matrix4::identity(), TransformFlags::None)
            .setModelViewMapUnitToRect(state.computedState.clipState->rect)
            .build();
    renderer.renderGlop(state, glop);
}

void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op, const BakedOpState& state) {
    renderer.renderFunctor(op, state);
}
+6 −0
Original line number Diff line number Diff line
@@ -572,6 +572,12 @@ void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) {
    deferOvalOp(*resolvedOp);
}

void FrameBuilder::deferColorOp(const ColorOp& op) {
    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
}

void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
    BakedOpState* bakedState = tryBakeUnboundedOpState(op);
    if (!bakedState) return; // quick rejected
+11 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ class Tree;
        UNMERGEABLE_OP_FN(ArcOp) \
        UNMERGEABLE_OP_FN(BitmapMeshOp) \
        UNMERGEABLE_OP_FN(BitmapRectOp) \
        UNMERGEABLE_OP_FN(ColorOp) \
        UNMERGEABLE_OP_FN(FunctorOp) \
        UNMERGEABLE_OP_FN(LinesOp) \
        UNMERGEABLE_OP_FN(OvalOp) \
@@ -256,6 +257,16 @@ struct CirclePropsOp : RecordedOp {
    const float* radius;
};

struct ColorOp : RecordedOp {
    // Note: unbounded op that will fillclip, so no bounds/matrix needed
    ColorOp(const ClipBase* localClip, int color, SkXfermode::Mode mode)
            : RecordedOp(RecordedOpId::ColorOp, Rect(), Matrix4::identity(), localClip, nullptr)
            , color(color)
            , mode(mode) {}
    const int color;
    const SkXfermode::Mode mode;
};

struct FunctorOp : RecordedOp {
    // Note: undefined record-time bounds, since this op fills the clip
    // TODO: explicitly define bounds
+4 −4
Original line number Diff line number Diff line
@@ -234,10 +234,10 @@ bool RecordingCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
// android/graphics/Canvas draw operations
// ----------------------------------------------------------------------------
void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) {
    SkPaint paint;
    paint.setColor(color);
    paint.setXfermodeMode(mode);
    drawPaint(paint);
    addOp(alloc().create_trivial<ColorOp>(
            getRecordedClip(),
            color,
            mode));
}

void RecordingCanvas::drawPaint(const SkPaint& paint) {
+25 −1
Original line number Diff line number Diff line
@@ -429,7 +429,31 @@ RENDERTHREAD_TEST(FrameBuilder, functor_reject) {
    EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected";
}

RENDERTHREAD_TEST(FrameBuilder, renderNode) {
RENDERTHREAD_TEST(FrameBuilder, deferColorOp_unbounded) {
    class ColorTestRenderer : public TestRendererBase {
    public:
        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
            EXPECT_EQ(0, mIndex++);
            EXPECT_EQ(Rect(200, 200), state.computedState.clippedBounds)
                    << "Color op should be expanded to bounds of surrounding";
        }
    };

    auto unclippedColorView = TestUtils::createNode(0, 0, 10, 10,
            [](RenderProperties& props, RecordingCanvas& canvas) {
        props.setClipToBounds(false);
        canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
    });

    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
            TestUtils::createSyncedNodeList(unclippedColorView),
            sLightGeometry, Caches::getInstance());
    ColorTestRenderer renderer;
    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
    EXPECT_EQ(1, renderer.getIndex()) << "ColorOp should not be rejected";
}

TEST(FrameBuilder, renderNode) {
    class RenderNodeTestRenderer : public TestRendererBase {
    public:
        void onRectOp(const RectOp& op, const BakedOpState& state) override {
Loading