aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-05-23 03:16:21 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-05-23 03:16:21 +0000
commite55724765970cd22e74b8cfed61307c01c350e8d (patch)
treead9f2b5e710b4ec95013729f68f76d95dac92564
parent11a38692ac6c3acd61a98bd1f4a2655455ee1768 (diff)
parentebe3c5a8b33de0570d7d290faace8050a2807adc (diff)
downloadskia-android10-s3-release.tar.gz
Change-Id: Ib809b1833f22b388a2ac49ff6f8ea4b820cf642f
-rw-r--r--gm/savelayer.cpp33
-rw-r--r--include/core/SkCanvas.h7
-rw-r--r--include/core/SkCanvasVirtualEnforcer.h1
-rw-r--r--include/core/SkOverdrawCanvas.h1
-rw-r--r--include/utils/SkNWayCanvas.h1
-rw-r--r--include/utils/SkNoDrawCanvas.h1
-rw-r--r--include/utils/SkPaintFilterCanvas.h1
-rw-r--r--src/core/SkCanvas.cpp45
-rw-r--r--src/core/SkCanvasPriv.h10
-rw-r--r--src/core/SkLiteDL.cpp11
-rw-r--r--src/core/SkLiteDL.h1
-rw-r--r--src/core/SkLiteRecorder.cpp3
-rw-r--r--src/core/SkLiteRecorder.h1
-rw-r--r--src/core/SkOverdrawCanvas.cpp4
-rw-r--r--src/core/SkPictureFlat.h4
-rw-r--r--src/core/SkPicturePlayback.cpp8
-rw-r--r--src/core/SkPictureRecord.cpp9
-rw-r--r--src/core/SkPictureRecord.h1
-rw-r--r--src/core/SkRecordDraw.cpp5
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h1
-rw-r--r--src/core/SkRecords.h3
-rw-r--r--src/utils/SkNWayCanvas.cpp7
-rw-r--r--src/utils/SkPaintFilterCanvas.cpp7
-rw-r--r--tools/debugger/SkDebugCanvas.cpp4
-rw-r--r--tools/debugger/SkDebugCanvas.h1
-rw-r--r--tools/debugger/SkDrawCommand.cpp22
-rw-r--r--tools/debugger/SkDrawCommand.h13
28 files changed, 192 insertions, 17 deletions
diff --git a/gm/savelayer.cpp b/gm/savelayer.cpp
index d6a33b2d96..1347cbc8cd 100644
--- a/gm/savelayer.cpp
+++ b/gm/savelayer.cpp
@@ -281,7 +281,8 @@ DEF_SIMPLE_GM(savelayer_coverage, canvas, 500, 500) {
#include "SkGradientShader.h"
#include "SkTextBlob.h"
-static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkScalar w, SkScalar h) {
+static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkScalar w, SkScalar h,
+ bool useDrawBehind) {
SkRect r = SkRect::MakeWH(w, h);
SkPaint p;
p.setColor(c);
@@ -309,7 +310,12 @@ static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkSca
auto sh = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkShader::kClamp_TileMode);
p.setShader(sh);
p.setBlendMode(SkBlendMode::kDstIn);
- canvas->drawRect(r, p);
+
+ if (useDrawBehind) {
+ SkCanvasPriv::DrawBehind(canvas, p);
+ } else {
+ canvas->drawRect(r, p);
+ }
// this should restore the behind image
canvas->restore();
@@ -320,10 +326,9 @@ static void draw_cell(SkCanvas* canvas, sk_sp<SkTextBlob> blob, SkColor c, SkSca
p.reset();
p.setStyle(SkPaint::kStroke_Style);
p.setAlphaf(0.25f);
- canvas->drawRect(r, p);
}
-static void draw_list(SkCanvas* canvas, sk_sp<SkTextBlob> blob) {
+static void draw_list(SkCanvas* canvas, sk_sp<SkTextBlob> blob, bool useDrawBehind) {
SkAutoCanvasRestore acr(canvas, true);
SkRandom rand;
@@ -332,19 +337,27 @@ static void draw_list(SkCanvas* canvas, sk_sp<SkTextBlob> blob) {
for (int i = 0; i < 8; ++i) {
SkColor c = rand.nextU(); // ensure we're opaque
c = (c & 0xFFFFFF) | 0x80000000;
- draw_cell(canvas, blob, c, w, h);
+ draw_cell(canvas, blob, c, w, h, useDrawBehind);
canvas->translate(0, h);
}
}
-DEF_SIMPLE_GM(save_behind, canvas, 400, 670) {
+DEF_SIMPLE_GM(save_behind, canvas, 830, 670) {
SkFont font;
font.setSize(30);
const char text[] = "This is a very long line of text";
auto blob = SkTextBlob::MakeFromText(text, strlen(text), font);
- draw_list(canvas, blob);
- canvas->translate(0, 350);
- canvas->saveLayer({0, 0, 400, 320}, nullptr);
- draw_list(canvas, blob);
+ for (bool useDrawBehind : {false, true}) {
+ canvas->save();
+
+ draw_list(canvas, blob, useDrawBehind);
+ canvas->translate(0, 350);
+ canvas->saveLayer({0, 0, 400, 320}, nullptr);
+ draw_list(canvas, blob, useDrawBehind);
+ canvas->restore();
+
+ canvas->restore();
+ canvas->translate(430, 0);
+ }
}
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index 397939b32b..40f16010b1 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -2379,6 +2379,7 @@ protected:
// SkCanvasVirtualEnforcer (in SkCanvasVirtualEnforcer.h). This ensures that subclasses using
// that mechanism will be required to implement the new function.
virtual void onDrawPaint(const SkPaint& paint);
+ virtual void onDrawBehind(const SkPaint& paint);
virtual void onDrawRect(const SkRect& rect, const SkPaint& paint);
virtual void onDrawEdgeAARect(const SkRect& rect, QuadAAFlags edgeAA, SkColor color,
SkBlendMode mode);
@@ -2587,6 +2588,12 @@ private:
*/
int only_axis_aligned_saveBehind(const SkRect* subset);
+ /**
+ * Like drawPaint, but magically clipped to the most recent saveBehind buffer rectangle.
+ * If there is no active saveBehind, then this draws nothing.
+ */
+ void drawClippedToSaveBehind(const SkPaint&);
+
void resetForNextPicture(const SkIRect& bounds);
// needs gettotalclip()
diff --git a/include/core/SkCanvasVirtualEnforcer.h b/include/core/SkCanvasVirtualEnforcer.h
index f097911b1c..3a5dac3af3 100644
--- a/include/core/SkCanvasVirtualEnforcer.h
+++ b/include/core/SkCanvasVirtualEnforcer.h
@@ -20,6 +20,7 @@ public:
protected:
void onDrawPaint(const SkPaint& paint) override = 0;
+ void onDrawBehind(const SkPaint&) override {} // make zero after android updates
void onDrawRect(const SkRect& rect, const SkPaint& paint) override = 0;
void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override = 0;
void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
diff --git a/include/core/SkOverdrawCanvas.h b/include/core/SkOverdrawCanvas.h
index e0d05c82bd..c75d7ae369 100644
--- a/include/core/SkOverdrawCanvas.h
+++ b/include/core/SkOverdrawCanvas.h
@@ -25,6 +25,7 @@ public:
void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
const SkPaint&) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint& paint) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
void onDrawRegion(const SkRegion&, const SkPaint&) override;
diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h
index 09b071d5c7..de9f44bf09 100644
--- a/include/utils/SkNWayCanvas.h
+++ b/include/utils/SkNWayCanvas.h
@@ -41,6 +41,7 @@ protected:
const SkPaint& paint) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/include/utils/SkNoDrawCanvas.h b/include/utils/SkNoDrawCanvas.h
index ff1b027548..43b49bcf7f 100644
--- a/include/utils/SkNoDrawCanvas.h
+++ b/include/utils/SkNoDrawCanvas.h
@@ -49,6 +49,7 @@ protected:
const SkPaint&) override {}
void onDrawPaint(const SkPaint&) override {}
+ void onDrawBehind(const SkPaint&) override {}
void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint&) override {}
void onDrawRect(const SkRect&, const SkPaint&) override {}
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override {}
diff --git a/include/utils/SkPaintFilterCanvas.h b/include/utils/SkPaintFilterCanvas.h
index c1d31b6e6d..0d154e5f04 100644
--- a/include/utils/SkPaintFilterCanvas.h
+++ b/include/utils/SkPaintFilterCanvas.h
@@ -68,6 +68,7 @@ protected:
virtual bool onFilter(SkTCopyOnFirstWrite<SkPaint>* paint, Type type) const = 0;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 13688504dc..8e84c3205e 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1145,11 +1145,7 @@ void SkCanvas::internalSaveBehind(const SkRect* localBounds) {
SkPaint paint;
paint.setBlendMode(SkBlendMode::kClear);
- if (localBounds) {
- this->drawRect(*localBounds, paint);
- } else {
- this->drawPaint(paint);
- }
+ this->drawClippedToSaveBehind(paint);
}
void SkCanvas::internalRestore() {
@@ -1702,6 +1698,11 @@ void SkCanvas::drawRect(const SkRect& r, const SkPaint& paint) {
this->onDrawRect(r.makeSorted(), paint);
}
+void SkCanvas::drawClippedToSaveBehind(const SkPaint& paint) {
+ TRACE_EVENT0("skia", TRACE_FUNC);
+ this->onDrawBehind(paint);
+}
+
void SkCanvas::drawRegion(const SkRegion& region, const SkPaint& paint) {
TRACE_EVENT0("skia", TRACE_FUNC);
if (region.isEmpty()) {
@@ -2127,6 +2128,40 @@ void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
LOOPER_END
}
+void SkCanvas::onDrawBehind(const SkPaint& paint) {
+ SkIRect bounds;
+ SkDeque::Iter iter(fMCStack, SkDeque::Iter::kBack_IterStart);
+ for (;;) {
+ const MCRec* rec = (const MCRec*)iter.prev();
+ if (!rec) {
+ return; // no backimages, so nothing to draw
+ }
+ if (rec->fBackImage) {
+ bounds = SkIRect::MakeXYWH(rec->fBackImage->fLoc.fX, rec->fBackImage->fLoc.fY,
+ rec->fBackImage->fImage->width(),
+ rec->fBackImage->fImage->height());
+ break;
+ }
+ }
+
+ LOOPER_BEGIN(paint, nullptr)
+
+ while (iter.next()) {
+ SkBaseDevice* dev = iter.fDevice;
+
+ dev->save();
+ // We use clipRegion because it is already defined to operate in dev-space
+ // (i.e. ignores the ctm). However, it is going to first translate by -origin,
+ // but we don't want that, so we undo that before calling in.
+ SkRegion rgn(bounds.makeOffset(dev->fOrigin.fX, dev->fOrigin.fY));
+ dev->clipRegion(rgn, SkClipOp::kIntersect);
+ dev->drawPaint(looper.paint());
+ dev->restore(fMCRec->fMatrix);
+ }
+
+ LOOPER_END
+}
+
void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
SkASSERT(oval.isSorted());
if (paint.canComputeFastBounds()) {
diff --git a/src/core/SkCanvasPriv.h b/src/core/SkCanvasPriv.h
index cb2540177a..0c3a2d83ed 100644
--- a/src/core/SkCanvasPriv.h
+++ b/src/core/SkCanvasPriv.h
@@ -43,6 +43,16 @@ public:
static int SaveBehind(SkCanvas* canvas, const SkRect* subset) {
return canvas->only_axis_aligned_saveBehind(subset);
}
+
+ static void DrawBehind(SkCanvas* canvas, const SkPaint& paint) {
+ canvas->drawClippedToSaveBehind(paint);
+ }
+
+ // The experimental_DrawEdgeAAImageSet API accepts separate dstClips and preViewMatrices arrays,
+ // where entries refer into them, but no explicit size is provided. Given a set of entries,
+ // computes the minimum length for these arrays that would provide index access errors.
+ static void GetDstClipAndMatrixCounts(const SkCanvas::ImageSetEntry set[], int count,
+ int* totalDstClipCount, int* totalMatrixCount);
};
#endif
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index 1c9c742894..562cd4f148 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -52,7 +52,7 @@ namespace {
M(Flush) M(Save) M(Restore) M(SaveLayer) M(SaveBehind) \
M(Concat) M(SetMatrix) M(Translate) \
M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \
- M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawEdgeAARect) \
+ M(DrawPaint) M(DrawBehind) M(DrawPath) M(DrawRect) M(DrawEdgeAARect) \
M(DrawRegion) M(DrawOval) M(DrawArc) \
M(DrawRRect) M(DrawDRRect) M(DrawAnnotation) M(DrawDrawable) M(DrawPicture) \
M(DrawImage) M(DrawImageNine) M(DrawImageRect) M(DrawImageLattice) M(DrawImageSet) \
@@ -176,6 +176,12 @@ namespace {
SkPaint paint;
void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
};
+ struct DrawBehind final : Op {
+ static const auto kType = Type::DrawBehind;
+ DrawBehind(const SkPaint& paint) : paint(paint) {}
+ SkPaint paint;
+ void draw(SkCanvas* c, const SkMatrix&) const { SkCanvasPriv::DrawBehind(c, paint); }
+ };
struct DrawPath final : Op {
static const auto kType = Type::DrawPath;
DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
@@ -527,6 +533,9 @@ void SkLiteDL::clipRegion(const SkRegion& region, SkClipOp op) {
void SkLiteDL::drawPaint(const SkPaint& paint) {
this->push<DrawPaint>(0, paint);
}
+void SkLiteDL::drawBehind(const SkPaint& paint) {
+ this->push<DrawBehind>(0, paint);
+}
void SkLiteDL::drawPath(const SkPath& path, const SkPaint& paint) {
this->push<DrawPath>(0, path, paint);
}
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index a6041bc2d6..0758f01cd3 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -44,6 +44,7 @@ public:
void clipRegion(const SkRegion&, SkClipOp);
void drawPaint (const SkPaint&);
+ void drawBehind(const SkPaint&);
void drawPath (const SkPath&, const SkPaint&);
void drawRect (const SkRect&, const SkPaint&);
void drawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode);
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index 6dda8d6fa9..e4ea47e536 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -60,6 +60,9 @@ void SkLiteRecorder::onClipRegion(const SkRegion& region, SkClipOp op) {
void SkLiteRecorder::onDrawPaint(const SkPaint& paint) {
fDL->drawPaint(paint);
}
+void SkLiteRecorder::onDrawBehind(const SkPaint& paint) {
+ fDL->drawBehind(paint);
+}
void SkLiteRecorder::onDrawPath(const SkPath& path, const SkPaint& paint) {
fDL->drawPath(path, paint);
}
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index 81eedb341c..0bc5db3cf0 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -37,6 +37,7 @@ public:
void onClipRegion(const SkRegion&, SkClipOp) override;
void onDrawPaint (const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPath (const SkPath&, const SkPaint&) override;
void onDrawRect (const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp
index a7b39bbb66..a760ea0361 100644
--- a/src/core/SkOverdrawCanvas.cpp
+++ b/src/core/SkOverdrawCanvas.cpp
@@ -113,6 +113,10 @@ void SkOverdrawCanvas::onDrawPaint(const SkPaint& paint) {
}
}
+void SkOverdrawCanvas::onDrawBehind(const SkPaint& paint) {
+ fList[0]->onDrawBehind(this->overdrawPaint(paint));
+}
+
void SkOverdrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
fList[0]->onDrawRect(rect, this->overdrawPaint(paint));
}
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index de1c269485..cdea96d77b 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -103,7 +103,9 @@ enum DrawType {
DRAW_EDGEAA_RECT,
- LAST_DRAWTYPE_ENUM = DRAW_EDGEAA_RECT,
+ DRAW_BEHIND_PAINT,
+
+ LAST_DRAWTYPE_ENUM = DRAW_BEHIND_PAINT,
};
enum DrawVertexFlags {
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index e0120dddfd..9724695fad 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -368,6 +368,14 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
canvas->drawPaint(*paint);
}
} break;
+ case DRAW_BEHIND_PAINT: {
+ const SkPaint* paint = fPictureData->getPaint(reader);
+ BREAK_ON_READ_ERROR(reader);
+
+ if (paint) {
+ SkCanvasPriv::DrawBehind(canvas, *paint);
+ }
+ } break;
case DRAW_PATCH: {
const SkPaint* paint = fPictureData->getPaint(reader);
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 01115bfdce..f7d5971535 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -422,6 +422,15 @@ void SkPictureRecord::onDrawPaint(const SkPaint& paint) {
this->validate(initialOffset, size);
}
+void SkPictureRecord::onDrawBehind(const SkPaint& paint) {
+ // logically the same as drawPaint, but with a diff enum
+ // op + paint index
+ size_t size = 2 * kUInt32Size;
+ size_t initialOffset = this->addDraw(DRAW_BEHIND_PAINT, &size);
+ this->addPaint(paint);
+ this->validate(initialOffset, size);
+}
+
void SkPictureRecord::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) {
// op + paint index + mode + count + point data
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 77137c4716..59f16cf600 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -174,6 +174,7 @@ protected:
SkBlendMode, const SkRect*, const SkPaint*) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 4dcc45502f..fac7e68b14 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -88,6 +88,10 @@ template <> void Draw::draw(const SaveBehind& r) {
SkCanvasPriv::SaveBehind(fCanvas, r.subset);
}
+template <> void Draw::draw(const DrawBehind& r) {
+ SkCanvasPriv::DrawBehind(fCanvas, r.paint);
+}
+
DRAW(SetMatrix, setMatrix(SkMatrix::Concat(fInitialCTM, r.matrix)));
DRAW(Concat, concat(r.matrix));
DRAW(Translate, translate(r.dx, r.dy));
@@ -354,6 +358,7 @@ private:
Bounds bounds(const Flush&) const { return fCullRect; }
Bounds bounds(const DrawPaint&) const { return fCullRect; }
+ Bounds bounds(const DrawBehind&) const { return fCullRect; }
Bounds bounds(const NoOp&) const { return Bounds::MakeEmpty(); } // NoOps don't draw.
Bounds bounds(const DrawRect& op) const { return this->adjustAndMap(op.rect, &op.paint); }
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index bfe1067bbd..9a4e1f6a57 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -139,6 +139,10 @@ void SkRecorder::onDrawPaint(const SkPaint& paint) {
this->append<SkRecords::DrawPaint>(paint);
}
+void SkRecorder::onDrawBehind(const SkPaint& paint) {
+ this->append<SkRecords::DrawBehind>(paint);
+}
+
void SkRecorder::onDrawPoints(PointMode mode,
size_t count,
const SkPoint pts[],
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 6b4c7fe1cd..53fd3aad73 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -77,6 +77,7 @@ public:
const SkPaint& paint) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 8f80924ab4..66a5e283a1 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -60,6 +60,7 @@ namespace SkRecords {
M(DrawImageSet) \
M(DrawDRRect) \
M(DrawOval) \
+ M(DrawBehind) \
M(DrawPaint) \
M(DrawPath) \
M(DrawPatch) \
@@ -269,6 +270,8 @@ RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag,
SkRect oval);
RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag,
SkPaint paint);
+RECORD(DrawBehind, kDraw_Tag|kHasPaint_Tag,
+ SkPaint paint);
RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag,
SkPaint paint;
PreCachedPath path);
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 1e6cd89083..c952601154 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -147,6 +147,13 @@ void SkNWayCanvas::onDrawPaint(const SkPaint& paint) {
}
}
+void SkNWayCanvas::onDrawBehind(const SkPaint& paint) {
+ Iter iter(fList);
+ while (iter.next()) {
+ SkCanvasPriv::DrawBehind(iter.get(), paint);
+ }
+}
+
void SkNWayCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) {
Iter iter(fList);
diff --git a/src/utils/SkPaintFilterCanvas.cpp b/src/utils/SkPaintFilterCanvas.cpp
index ded7fc2fba..f06e565564 100644
--- a/src/utils/SkPaintFilterCanvas.cpp
+++ b/src/utils/SkPaintFilterCanvas.cpp
@@ -49,6 +49,13 @@ void SkPaintFilterCanvas::onDrawPaint(const SkPaint& paint) {
}
}
+void SkPaintFilterCanvas::onDrawBehind(const SkPaint& paint) {
+ AutoPaintFilter apf(this, kPaint_Type, paint);
+ if (apf.shouldDraw()) {
+ this->SkNWayCanvas::onDrawBehind(*apf.paint());
+ }
+}
+
void SkPaintFilterCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) {
AutoPaintFilter apf(this, kPoint_Type, paint);
diff --git a/tools/debugger/SkDebugCanvas.cpp b/tools/debugger/SkDebugCanvas.cpp
index 96c0de2776..59d3dd8116 100644
--- a/tools/debugger/SkDebugCanvas.cpp
+++ b/tools/debugger/SkDebugCanvas.cpp
@@ -429,6 +429,10 @@ void SkDebugCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4
this->addDrawCommand(new SkDrawPatchCommand(cubics, colors, texCoords, bmode, paint));
}
+void SkDebugCanvas::onDrawBehind(const SkPaint& paint) {
+ this->addDrawCommand(new SkDrawBehindCommand(paint));
+}
+
void SkDebugCanvas::onDrawVerticesObject(const SkVertices* vertices, const SkVertices::Bone bones[],
int boneCount, SkBlendMode bmode, const SkPaint& paint) {
// TODO: ANIMATION NOT LOGGED
diff --git a/tools/debugger/SkDebugCanvas.h b/tools/debugger/SkDebugCanvas.h
index 194ce119a9..83819bf6db 100644
--- a/tools/debugger/SkDebugCanvas.h
+++ b/tools/debugger/SkDebugCanvas.h
@@ -129,6 +129,7 @@ protected:
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawEdgeAARect(const SkRect&, SkCanvas::QuadAAFlags, SkColor, SkBlendMode) override;
diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp
index d9723acd7b..2de0c0cbf7 100644
--- a/tools/debugger/SkDrawCommand.cpp
+++ b/tools/debugger/SkDrawCommand.cpp
@@ -9,6 +9,7 @@
#include <algorithm>
#include "SkAutoMalloc.h"
+#include "SkCanvasPriv.h"
#include "SkClipOpPriv.h"
#include "SkColorFilter.h"
#include "SkDashPathEffect.h"
@@ -1639,6 +1640,27 @@ void SkDrawPathCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataMana
writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT); MakeJsonPaint(writer, fPaint, urlDataManager);
}
+SkDrawBehindCommand::SkDrawBehindCommand(const SkPaint& paint) : INHERITED(kDrawPaint_OpType) {
+ fPaint = paint;
+}
+
+void SkDrawBehindCommand::execute(SkCanvas* canvas) const {
+ SkCanvasPriv::DrawBehind(canvas, fPaint);
+}
+
+bool SkDrawBehindCommand::render(SkCanvas* canvas) const {
+ canvas->clear(0xFFFFFFFF);
+ SkCanvasPriv::DrawBehind(canvas, fPaint);
+ return true;
+}
+
+void SkDrawBehindCommand::toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const {
+ INHERITED::toJSON(writer, urlDataManager);
+ writer.appendName(SKDEBUGCANVAS_ATTRIBUTE_PAINT);
+ MakeJsonPaint(writer, fPaint, urlDataManager);
+}
+
+
SkDrawRegionCommand::SkDrawRegionCommand(const SkRegion& region, const SkPaint& paint)
: INHERITED(kDrawRegion_OpType) {
fRegion = region;
diff --git a/tools/debugger/SkDrawCommand.h b/tools/debugger/SkDrawCommand.h
index 7c386bcbc8..50d2cc5403 100644
--- a/tools/debugger/SkDrawCommand.h
+++ b/tools/debugger/SkDrawCommand.h
@@ -419,6 +419,19 @@ private:
typedef SkDrawCommand INHERITED;
};
+class SkDrawBehindCommand : public SkDrawCommand {
+public:
+ SkDrawBehindCommand(const SkPaint& paint);
+ void execute(SkCanvas* canvas) const override;
+ bool render(SkCanvas* canvas) const override;
+ void toJSON(SkJSONWriter& writer, UrlDataManager& urlDataManager) const override;
+
+private:
+ SkPaint fPaint;
+
+ typedef SkDrawCommand INHERITED;
+};
+
class SkDrawPathCommand : public SkDrawCommand {
public:
SkDrawPathCommand(const SkPath& path, const SkPaint& paint);