Loading libs/hwui/BakedOpDispatcher.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading libs/hwui/FrameBuilder.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading libs/hwui/RecordedOp.h +11 −0 Original line number Diff line number Diff line Loading @@ -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) \ Loading Loading @@ -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 Loading libs/hwui/RecordingCanvas.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading libs/hwui/tests/unit/FrameBuilderTests.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -427,7 +427,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 Loading
libs/hwui/BakedOpDispatcher.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -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); } Loading
libs/hwui/FrameBuilder.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/hwui/RecordedOp.h +11 −0 Original line number Diff line number Diff line Loading @@ -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) \ Loading Loading @@ -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 Loading
libs/hwui/RecordingCanvas.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -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) { Loading
libs/hwui/tests/unit/FrameBuilderTests.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -427,7 +427,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