add heuristic to pour small pictures into recordings, rather than ref'ing
BUG=skia:
Review URL: https://codereview.chromium.org/1118693003
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index dcbff3f..9282267 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -951,7 +951,9 @@
@param picture The recorded drawing commands to playback into this
canvas.
*/
- void drawPicture(const SkPicture* picture);
+ void drawPicture(const SkPicture* picture) {
+ this->drawPicture(picture, NULL, NULL);
+ }
/**
* Draw the picture into this canvas.
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 95f9560..c87c6c5 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2508,20 +2508,28 @@
}
///////////////////////////////////////////////////////////////////////////////
-void SkCanvas::drawPicture(const SkPicture* picture) {
- TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()");
- if (picture) {
- this->onDrawPicture(picture, NULL, NULL);
- }
-}
+
+/**
+ * This constant is trying to balance the speed of ref'ing a subpicture into a parent picture,
+ * against the playback cost of recursing into the subpicture to get at its actual ops.
+ *
+ * For now we pick a conservatively small value, though measurement (and other heuristics like
+ * the type of ops contained) may justify changing this value.
+ */
+#define kMaxPictureOpsToUnrollInsteadOfRef 1
void SkCanvas::drawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) {
- TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture(SkMatrix, SkPaint)");
+ TRACE_EVENT0("disabled-by-default-skia", "SkCanvas::drawPicture()");
if (picture) {
if (matrix && matrix->isIdentity()) {
matrix = NULL;
}
- this->onDrawPicture(picture, matrix, paint);
+ if (picture->approximateOpCount() <= kMaxPictureOpsToUnrollInsteadOfRef) {
+ SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
+ picture->playback(this);
+ } else {
+ this->onDrawPicture(picture, matrix, paint);
+ }
}
}
@@ -2537,7 +2545,6 @@
}
SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
-
picture->playback(this);
}
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index 4fe0837..16d98b3 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -1127,7 +1127,7 @@
r2.getRecordingCanvas()->drawPicture(empty.get());
SkAutoTUnref<SkPicture> nested(r2.endRecording());
- REPORTER_ASSERT(reporter, SkPictureUtils::ApproximateBytesUsed(nested.get()) >
+ REPORTER_ASSERT(reporter, SkPictureUtils::ApproximateBytesUsed(nested.get()) >=
SkPictureUtils::ApproximateBytesUsed(empty.get()));
}
diff --git a/tests/RecorderTest.cpp b/tests/RecorderTest.cpp
index 4fac1af..e67de58 100644
--- a/tests/RecorderTest.cpp
+++ b/tests/RecorderTest.cpp
@@ -89,28 +89,6 @@
REPORTER_ASSERT(r, paint.getShader()->unique());
}
-DEF_TEST(Recorder_RefPictures, r) {
- SkAutoTUnref<SkPicture> pic;
-
- {
- SkPictureRecorder pr;
- SkCanvas* canvas = pr.beginRecording(100, 100);
- canvas->drawColor(SK_ColorRED);
- pic.reset(pr.endRecording());
- }
- REPORTER_ASSERT(r, pic->unique());
-
- {
- SkRecord record;
- SkRecorder recorder(&record, 100, 100);
- recorder.drawPicture(pic);
- // the recorder should now also be an owner
- REPORTER_ASSERT(r, !pic->unique());
- }
- // the recorder destructor should have released us (back to unique)
- REPORTER_ASSERT(r, pic->unique());
-}
-
DEF_TEST(Recorder_drawImage_takeReference, reporter) {
SkAutoTUnref<SkImage> image;