From d711d115d28b9838303dcc232516aa2f552f3a2a Mon Sep 17 00:00:00 2001 From: mtklein Date: Wed, 1 Jul 2015 07:04:37 -0700 Subject: [PATCH] Thread through a flag to force SkPicture::playback() when recording subpictures. This makes nanobench picture recording benchmarks somewhat useful again, as opposed to all taking about 5us to run no matter the content. ATTN Sheriff: this will probably trigger perf.skia.org alerts. BUG=skia: Review URL: https://codereview.chromium.org/1219873002 --- bench/RecordingBench.cpp | 5 +++-- include/core/SkPictureRecorder.h | 6 +++++- src/core/SkPictureRecorder.cpp | 5 ++++- src/core/SkRecorder.cpp | 17 ++++++++++++++--- src/core/SkRecorder.h | 4 +++- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/bench/RecordingBench.cpp b/bench/RecordingBench.cpp index cd029ddf14..eada9305f9 100644 --- a/bench/RecordingBench.cpp +++ b/bench/RecordingBench.cpp @@ -33,10 +33,11 @@ void RecordingBench::onDraw(const int loops, SkCanvas*) { const SkScalar w = fSrc->cullRect().width(), h = fSrc->cullRect().height(); + uint32_t flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag + | SkPictureRecorder::kPlaybackDrawPicture_RecordFlag; for (int i = 0; i < loops; i++) { SkPictureRecorder recorder; - fSrc->playback(recorder.beginRecording(w, h, fUseBBH ? &factory : NULL, - SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); + fSrc->playback(recorder.beginRecording(w, h, fUseBBH ? &factory : NULL, flags)); SkSafeUnref(recorder.endRecording()); } } diff --git a/include/core/SkPictureRecorder.h b/include/core/SkPictureRecorder.h index a84b721e44..811d02a36e 100644 --- a/include/core/SkPictureRecorder.h +++ b/include/core/SkPictureRecorder.h @@ -33,7 +33,11 @@ public: enum RecordFlags { // This flag indicates that, if some BHH is being computed, saveLayer // information should also be extracted at the same time. - kComputeSaveLayerInfo_RecordFlag = 0x01 + kComputeSaveLayerInfo_RecordFlag = 0x01, + + // If you call drawPicture() on the recording canvas, this flag forces + // that to use SkPicture::playback() immediately rather than (e.g.) reffing the picture. + kPlaybackDrawPicture_RecordFlag = 0x02, }; /** Returns the canvas that records the drawing commands. diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp index c110e0a2db..877314ccaf 100644 --- a/src/core/SkPictureRecorder.cpp +++ b/src/core/SkPictureRecorder.cpp @@ -38,7 +38,10 @@ SkCanvas* SkPictureRecorder::beginRecording(const SkRect& cullRect, if (!fRecord) { fRecord.reset(SkNEW(SkRecord)); } - fRecorder->reset(fRecord.get(), cullRect, &fMiniRecorder); + SkRecorder::DrawPictureMode dpm = (recordFlags & kPlaybackDrawPicture_RecordFlag) + ? SkRecorder::Playback_DrawPictureMode + : SkRecorder::Record_DrawPictureMode; + fRecorder->reset(fRecord.get(), cullRect, dpm, &fMiniRecorder); fActivelyRecording = true; return this->getRecordingCanvas(); } diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp index 6d7e5ee90b..a9d9ba9d14 100644 --- a/src/core/SkRecorder.cpp +++ b/src/core/SkRecorder.cpp @@ -6,6 +6,7 @@ */ #include "SkBigPicture.h" +#include "SkCanvasPriv.h" #include "SkPatchUtils.h" #include "SkPicture.h" #include "SkPictureUtils.h" @@ -35,18 +36,22 @@ void SkDrawableList::append(SkDrawable* drawable) { SkRecorder::SkRecorder(SkRecord* record, int width, int height, SkMiniRecorder* mr) : SkCanvas(SkIRect::MakeWH(width, height), SkCanvas::kConservativeRasterClip_InitFlag) + , fDrawPictureMode(Record_DrawPictureMode) , fApproxBytesUsedBySubPictures(0) , fRecord(record) , fMiniRecorder(mr) {} SkRecorder::SkRecorder(SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr) : SkCanvas(bounds.roundOut(), SkCanvas::kConservativeRasterClip_InitFlag) + , fDrawPictureMode(Record_DrawPictureMode) , fApproxBytesUsedBySubPictures(0) , fRecord(record) , fMiniRecorder(mr) {} -void SkRecorder::reset(SkRecord* record, const SkRect& bounds, SkMiniRecorder* mr) { +void SkRecorder::reset(SkRecord* record, const SkRect& bounds, + DrawPictureMode dpm, SkMiniRecorder* mr) { this->forgetRecord(); + fDrawPictureMode = dpm; fRecord = record; this->resetForNextPicture(bounds.roundOut()); fMiniRecorder = mr; @@ -254,8 +259,14 @@ void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, } void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, const SkPaint* paint) { - fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic); - APPEND(DrawPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I()); + if (fDrawPictureMode == Record_DrawPictureMode) { + fApproxBytesUsedBySubPictures += SkPictureUtils::ApproximateBytesUsed(pic); + APPEND(DrawPicture, this->copy(paint), pic, matrix ? *matrix : SkMatrix::I()); + } else { + SkASSERT(fDrawPictureMode == Playback_DrawPictureMode); + SkAutoCanvasMatrixPaint acmp(this, matrix, paint, pic->cullRect()); + pic->playback(this); + } } void SkRecorder::onDrawVertices(VertexMode vmode, diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h index 3809ae239d..688069bd50 100644 --- a/src/core/SkRecorder.h +++ b/src/core/SkRecorder.h @@ -41,7 +41,8 @@ public: SkRecorder(SkRecord*, int width, int height, SkMiniRecorder* = nullptr); // legacy version SkRecorder(SkRecord*, const SkRect& bounds, SkMiniRecorder* = nullptr); - void reset(SkRecord*, const SkRect& bounds, SkMiniRecorder* = nullptr); + enum DrawPictureMode { Record_DrawPictureMode, Playback_DrawPictureMode }; + void reset(SkRecord*, const SkRect& bounds, DrawPictureMode, SkMiniRecorder* = nullptr); size_t approxBytesUsedBySubPictures() const { return fApproxBytesUsedBySubPictures; } @@ -137,6 +138,7 @@ private: return devBounds; } + DrawPictureMode fDrawPictureMode; size_t fApproxBytesUsedBySubPictures; SkRecord* fRecord; SkAutoTDelete fDrawableList; -- 2.34.1