Merge "Create first class unbounded ColorOp" into nyc-dev
am: 349c866
* commit '349c866e399a1eb2e85b1982d5d10f3a8cc4c69b':
Create first class unbounded ColorOp
This commit is contained in:
@@ -506,6 +506,22 @@ void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRe
|
|||||||
renderer.renderGlop(state, glop);
|
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) {
|
void BakedOpDispatcher::onFunctorOp(BakedOpRenderer& renderer, const FunctorOp& op, const BakedOpState& state) {
|
||||||
renderer.renderFunctor(op, state);
|
renderer.renderFunctor(op, state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,6 +572,12 @@ void FrameBuilder::deferCirclePropsOp(const CirclePropsOp& op) {
|
|||||||
deferOvalOp(*resolvedOp);
|
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) {
|
void FrameBuilder::deferFunctorOp(const FunctorOp& op) {
|
||||||
BakedOpState* bakedState = tryBakeUnboundedOpState(op);
|
BakedOpState* bakedState = tryBakeUnboundedOpState(op);
|
||||||
if (!bakedState) return; // quick rejected
|
if (!bakedState) return; // quick rejected
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ class Tree;
|
|||||||
UNMERGEABLE_OP_FN(ArcOp) \
|
UNMERGEABLE_OP_FN(ArcOp) \
|
||||||
UNMERGEABLE_OP_FN(BitmapMeshOp) \
|
UNMERGEABLE_OP_FN(BitmapMeshOp) \
|
||||||
UNMERGEABLE_OP_FN(BitmapRectOp) \
|
UNMERGEABLE_OP_FN(BitmapRectOp) \
|
||||||
|
UNMERGEABLE_OP_FN(ColorOp) \
|
||||||
UNMERGEABLE_OP_FN(FunctorOp) \
|
UNMERGEABLE_OP_FN(FunctorOp) \
|
||||||
UNMERGEABLE_OP_FN(LinesOp) \
|
UNMERGEABLE_OP_FN(LinesOp) \
|
||||||
UNMERGEABLE_OP_FN(OvalOp) \
|
UNMERGEABLE_OP_FN(OvalOp) \
|
||||||
@@ -256,6 +257,16 @@ struct CirclePropsOp : RecordedOp {
|
|||||||
const float* radius;
|
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 {
|
struct FunctorOp : RecordedOp {
|
||||||
// Note: undefined record-time bounds, since this op fills the clip
|
// Note: undefined record-time bounds, since this op fills the clip
|
||||||
// TODO: explicitly define bounds
|
// TODO: explicitly define bounds
|
||||||
|
|||||||
@@ -234,10 +234,10 @@ bool RecordingCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) {
|
|||||||
// android/graphics/Canvas draw operations
|
// android/graphics/Canvas draw operations
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) {
|
void RecordingCanvas::drawColor(int color, SkXfermode::Mode mode) {
|
||||||
SkPaint paint;
|
addOp(alloc().create_trivial<ColorOp>(
|
||||||
paint.setColor(color);
|
getRecordedClip(),
|
||||||
paint.setXfermodeMode(mode);
|
color,
|
||||||
drawPaint(paint);
|
mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingCanvas::drawPaint(const SkPaint& paint) {
|
void RecordingCanvas::drawPaint(const SkPaint& paint) {
|
||||||
|
|||||||
@@ -427,7 +427,31 @@ RENDERTHREAD_TEST(FrameBuilder, functor_reject) {
|
|||||||
EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected";
|
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 {
|
class RenderNodeTestRenderer : public TestRendererBase {
|
||||||
public:
|
public:
|
||||||
void onRectOp(const RectOp& op, const BakedOpState& state) override {
|
void onRectOp(const RectOp& op, const BakedOpState& state) override {
|
||||||
|
|||||||
@@ -226,9 +226,9 @@ TEST(RecordingCanvas, drawColor) {
|
|||||||
|
|
||||||
ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
|
ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
|
||||||
auto op = *(dl->getOps()[0]);
|
auto op = *(dl->getOps()[0]);
|
||||||
EXPECT_EQ(RecordedOpId::RectOp, op.opId);
|
EXPECT_EQ(RecordedOpId::ColorOp, op.opId);
|
||||||
EXPECT_EQ(nullptr, op.localClip);
|
EXPECT_EQ(nullptr, op.localClip);
|
||||||
EXPECT_TRUE(op.unmappedBounds.contains(Rect(200, 200))) << "Expect recording/clip bounds";
|
EXPECT_TRUE(op.unmappedBounds.isEmpty()) << "Expect undefined recorded bounds";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecordingCanvas, backgroundAndImage) {
|
TEST(RecordingCanvas, backgroundAndImage) {
|
||||||
|
|||||||
Reference in New Issue
Block a user