aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-08-14 10:39:28 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-14 15:29:05 +0000
commit7cc49d65fc5788f72458efc8fc4156cde4cca15a (patch)
tree00ef007c014f88c0949231653cd1b97290e829af
parent0db0779199ee74074c39c6ea4e870ea9b231622b (diff)
Record SkCanvas::flush().
We can record multiple frames in an .skp by recording SkCanvas::flush(). This should make SkPictures, SkLiteDL, and .skp files all record flush(). Change-Id: I6cf6e0e4ef993530d9f92fa168a53702ffce7d5e Reviewed-on: https://skia-review.googlesource.com/34081 Reviewed-by: Derek Sollenberger <djsollen@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
-rw-r--r--src/core/SkLiteDL.cpp11
-rw-r--r--src/core/SkLiteDL.h2
-rw-r--r--src/core/SkLiteRecorder.cpp2
-rw-r--r--src/core/SkLiteRecorder.h2
-rw-r--r--src/core/SkPictureFlat.h4
-rw-r--r--src/core/SkPicturePlayback.cpp7
-rw-r--r--src/core/SkPictureRecord.cpp6
-rw-r--r--src/core/SkPictureRecord.h2
-rw-r--r--src/core/SkRecordDraw.cpp3
-rw-r--r--src/core/SkRecorder.cpp4
-rw-r--r--src/core/SkRecorder.h2
-rw-r--r--src/core/SkRecords.h2
-rw-r--r--tests/PictureTest.cpp22
-rw-r--r--tests/SkLiteDLTest.cpp11
14 files changed, 75 insertions, 5 deletions
diff --git a/src/core/SkLiteDL.cpp b/src/core/SkLiteDL.cpp
index 1565dae5cc..c5144e50fe 100644
--- a/src/core/SkLiteDL.cpp
+++ b/src/core/SkLiteDL.cpp
@@ -47,8 +47,8 @@ static const D* pod(const T* op, size_t offset = 0) {
}
namespace {
-#define TYPES(M) \
- M(SetDrawFilter) M(Save) M(Restore) M(SaveLayer) \
+#define TYPES(M) \
+ M(SetDrawFilter) M(Flush) M(Save) M(Restore) M(SaveLayer) \
M(Concat) M(SetMatrix) M(Translate) \
M(ClipPath) M(ClipRect) M(ClipRRect) M(ClipRegion) \
M(DrawPaint) M(DrawPath) M(DrawRect) M(DrawRegion) M(DrawOval) M(DrawArc) \
@@ -81,6 +81,11 @@ namespace {
}
};
+ struct Flush final : Op {
+ static const auto kType = Type::Flush;
+ void draw(SkCanvas* c, const SkMatrix&) const { c->flush(); }
+ };
+
struct Save final : Op {
static const auto kType = Type::Save;
void draw(SkCanvas* c, const SkMatrix&) const { c->save(); }
@@ -530,6 +535,8 @@ void SkLiteDL::setDrawFilter(SkDrawFilter* df) {
}
#endif
+void SkLiteDL::flush() { this->push<Flush>(0); }
+
void SkLiteDL:: save() { this->push <Save>(0); }
void SkLiteDL::restore() { this->push<Restore>(0); }
void SkLiteDL::saveLayer(const SkRect* bounds, const SkPaint* paint,
diff --git a/src/core/SkLiteDL.h b/src/core/SkLiteDL.h
index 31ef38e6bf..6d63657084 100644
--- a/src/core/SkLiteDL.h
+++ b/src/core/SkLiteDL.h
@@ -29,6 +29,8 @@ public:
void setDrawFilter(SkDrawFilter*);
#endif
+ void flush();
+
void save();
void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, const SkImage*,
const SkMatrix*, SkCanvas::SaveLayerFlags);
diff --git a/src/core/SkLiteRecorder.cpp b/src/core/SkLiteRecorder.cpp
index dbee48e1bd..bd41ff3913 100644
--- a/src/core/SkLiteRecorder.cpp
+++ b/src/core/SkLiteRecorder.cpp
@@ -29,6 +29,8 @@ SkDrawFilter* SkLiteRecorder::setDrawFilter(SkDrawFilter* df) {
}
#endif
+void SkLiteRecorder::onFlush() { fDL->flush(); }
+
void SkLiteRecorder::willSave() { fDL->save(); }
SkCanvas::SaveLayerStrategy SkLiteRecorder::getSaveLayerStrategy(const SaveLayerRec& rec) {
fDL->saveLayer(rec.fBounds, rec.fPaint, rec.fBackdrop, rec.fClipMask, rec.fClipMatrix,
diff --git a/src/core/SkLiteRecorder.h b/src/core/SkLiteRecorder.h
index 4d49eb5336..92b425b528 100644
--- a/src/core/SkLiteRecorder.h
+++ b/src/core/SkLiteRecorder.h
@@ -27,6 +27,8 @@ public:
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
+ void onFlush() override;
+
void didConcat(const SkMatrix&) override;
void didSetMatrix(const SkMatrix&) override;
void didTranslate(SkScalar, SkScalar) override;
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 3c257b96ef..866c707359 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -95,7 +95,9 @@ enum DrawType {
DRAW_REGION,
DRAW_VERTICES_OBJECT,
- LAST_DRAWTYPE_ENUM = DRAW_VERTICES_OBJECT
+ FLUSH,
+
+ LAST_DRAWTYPE_ENUM = FLUSH
};
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 9ebb178aa5..c0adaaa941 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -134,9 +134,12 @@ void SkPicturePlayback::handleOp(SkReadBuffer* reader,
SkASSERT(size >= 4);
reader->skip(size - 4);
} break;
+ case FLUSH:
+ canvas->flush();
+ break;
case CLIP_PATH: {
- const SkPath& path = fPictureData->getPath(reader);
- uint32_t packed = reader->readInt();
+ const SkPath& path = fPictureData->getPath(reader);
+ uint32_t packed = reader->readInt();
SkClipOp clipOp = ClipParams_unpackRegionOp(reader, packed);
bool doAA = ClipParams_unpackDoAA(packed);
size_t offsetToRestore = reader->readInt();
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 4421633580..2ebe7bbe50 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -42,6 +42,12 @@ SkPictureRecord::~SkPictureRecord() {
///////////////////////////////////////////////////////////////////////////////
+void SkPictureRecord::onFlush() {
+ size_t size = sizeof(kUInt32Size);
+ size_t initialOffset = this->addDraw(FLUSH, &size);
+ this->validate(initialOffset, size);
+}
+
void SkPictureRecord::willSave() {
// record the offset to us, making it non-positive to distinguish a save
// from a clip entry.
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 9a93bf9e1c..f3d991ac35 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -157,6 +157,8 @@ protected:
sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
bool onPeekPixels(SkPixmap*) override { return false; }
+ void onFlush() override;
+
void willSave() override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index df68f8a622..56bde16726 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -73,6 +73,7 @@ namespace SkRecords {
template <> void Draw::draw(const NoOp&) {}
#define DRAW(T, call) template <> void Draw::draw(const T& r) { fCanvas->call; }
+DRAW(Flush, flush());
DRAW(Restore, restore());
DRAW(Save, save());
DRAW(SaveLayer, saveLayer(SkCanvas::SaveLayerRec(r.bounds,
@@ -388,6 +389,8 @@ private:
}
}
+ Bounds bounds(const Flush&) const { return fCurrentClipBounds; }
+
// FIXME: this method could use better bounds
Bounds bounds(const DrawText&) const { return fCurrentClipBounds; }
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 1eeef532e6..3d53e9384e 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -346,6 +346,10 @@ void SkRecorder::onDrawAnnotation(const SkRect& rect, const char key[], SkData*
APPEND(DrawAnnotation, rect, SkString(key), sk_ref_sp(value));
}
+void SkRecorder::onFlush() {
+ APPEND(Flush);
+}
+
void SkRecorder::willSave() {
APPEND(Save);
}
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 04e75edd26..382048f382 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -53,6 +53,8 @@ public:
// Make SkRecorder forget entirely about its SkRecord*; all calls to SkRecorder will fail.
void forgetRecord();
+ void onFlush() override;
+
void willSave() override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override {}
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 8821a3ea2a..bbac4452ca 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -47,6 +47,7 @@ namespace SkRecords {
// you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0.
#define SK_RECORD_TYPES(M) \
M(NoOp) \
+ M(Flush) \
M(Restore) \
M(Save) \
M(SaveLayer) \
@@ -174,6 +175,7 @@ struct T { \
};
RECORD(NoOp, 0);
+RECORD(Flush, 0);
RECORD(Restore, 0,
SkIRect devBounds;
TypedMatrix matrix);
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index d407fc0848..799405e558 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -1171,3 +1171,25 @@ DEF_TEST(Picture_UpdatedCull_2, r) {
pic = recorder.finishRecordingAsPicture();
REPORTER_ASSERT(r, pic->cullRect() == SkRect::MakeLargest());
}
+
+DEF_TEST(Picture_RecordsFlush, r) {
+ SkPictureRecorder recorder;
+
+ auto canvas = recorder.beginRecording(SkRect::MakeWH(100,100));
+ for (int i = 0; i < 10; i++) {
+ canvas->clear(0);
+ for (int j = 0; j < 10; j++) {
+ canvas->drawRect(SkRect::MakeXYWH(i*10,j*10,10,10), SkPaint());
+ }
+ canvas->flush();
+ }
+
+ // Did we record the flushes?
+ auto pic = recorder.finishRecordingAsPicture();
+ REPORTER_ASSERT(r, pic->approximateOpCount() == 120); // 10 clears, 100 draws, 10 flushes
+
+ // Do we serialize and deserialize flushes?
+ auto skp = pic->serialize();
+ auto back = SkPicture::MakeFromData(skp->data(), skp->size());
+ REPORTER_ASSERT(r, back->approximateOpCount() == pic->approximateOpCount());
+}
diff --git a/tests/SkLiteDLTest.cpp b/tests/SkLiteDLTest.cpp
index 514464aaf9..d719c0bb76 100644
--- a/tests/SkLiteDLTest.cpp
+++ b/tests/SkLiteDLTest.cpp
@@ -51,3 +51,14 @@ DEF_TEST(SkLiteRecorder, r) {
c->drawRect(SkRect{0,0,9,9}, SkPaint{});
c->restore();
}
+
+DEF_TEST(SkLiteRecorder_RecordsFlush, r) {
+ SkLiteDL dl;
+
+ SkLiteRecorder canvas;
+ canvas.reset(&dl, {0,0,100,100});
+
+ REPORTER_ASSERT(r, dl.empty());
+ canvas.flush();
+ REPORTER_ASSERT(r, !dl.empty());
+}