diff options
author | 2014-08-21 09:11:37 -0700 | |
---|---|---|
committer | 2014-08-21 09:11:38 -0700 | |
commit | 53fecfb15d254397ab03032b888daa9d15c487b6 (patch) | |
tree | 369d07782c33d2a1547b155f46c6d4beb1a2686e /src | |
parent | c2d04e1bb8e8a0973e74d17811c6a9b586719766 (diff) |
Our SkPicture::Analysis visitors should recurse into nested pictures.
BUG=skia:
R=tomhudson@google.com, mtklein@google.com, reed@google.com
Author: mtklein@chromium.org
Review URL: https://codereview.chromium.org/495793002
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkPicture.cpp | 39 | ||||
-rw-r--r-- | src/core/SkRecords.h | 30 |
2 files changed, 43 insertions, 26 deletions
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 160dd4b420..515f28d079 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -68,9 +68,12 @@ struct BitmapTester { // Main entry for visitor: + // If the command is a DrawPicture, recurse. // If the command has a bitmap directly, return true. // If the command has a paint and the paint has a bitmap, return true. // Otherwise, return false. + bool operator()(const SkRecords::DrawPicture& op) { return op.picture->willPlayBackBitmaps(); } + template <typename T> bool operator()(const T& r) { return CheckBitmap(r); } @@ -112,10 +115,21 @@ bool WillPlaybackBitmaps(const SkRecord& record) { return false; } +// SkRecord visitor to find recorded text. +struct TextHunter { + // All ops with text have that text as a char array member named "text". + SK_CREATE_MEMBER_DETECTOR(text); + bool operator()(const SkRecords::DrawPicture& op) { return op.picture->hasText(); } + template <typename T> SK_WHEN(HasMember_text<T>, bool) operator()(const T&) { return true; } + template <typename T> SK_WHEN(!HasMember_text<T>, bool) operator()(const T&) { return false; } +}; + +} // namespace + /** SkRecords visitor to determine heuristically whether or not a SkPicture will be performant when rasterized on the GPU. */ -struct PathCounter { +struct SkPicture::PathCounter { SK_CREATE_MEMBER_DETECTOR(paint); PathCounter() @@ -125,6 +139,18 @@ struct PathCounter { , numAAHairlineConcavePaths (0) { } + // Recurse into nested pictures. + void operator()(const SkRecords::DrawPicture& op) { + // If you're not also SkRecord-backed, tough luck. Get on the bandwagon. + if (op.picture->fRecord.get() == NULL) { + return; + } + const SkRecord& nested = *op.picture->fRecord; + for (unsigned i = 0; i < nested.count(); i++) { + nested.visit<void>(i, *this); + } + } + void checkPaint(const SkPaint* paint) { if (paint && paint->getPathEffect()) { numPaintWithPathEffectUses++; @@ -164,23 +190,12 @@ struct PathCounter { template <typename T> SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing */ } - int numPaintWithPathEffectUses; int numFastPathDashEffects; int numAAConcavePaths; int numAAHairlineConcavePaths; }; -// SkRecord visitor to find recorded text. -struct TextHunter { - // All ops with text have that text as a char array member named "text". - SK_CREATE_MEMBER_DETECTOR(text); - template <typename T> SK_WHEN(HasMember_text<T>, bool) operator()(const T&) { return true; } - template <typename T> SK_WHEN(!HasMember_text<T>, bool) operator()(const T&) { return false; } -}; - -} // namespace - SkPicture::Analysis::Analysis(const SkRecord& record) { fWillPlaybackBitmaps = WillPlaybackBitmaps(record); diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h index 6baabe6b76..f3d96d4aa9 100644 --- a/src/core/SkRecords.h +++ b/src/core/SkRecords.h @@ -14,18 +14,6 @@ namespace SkRecords { -template <typename T> -class RefBox : SkNoncopyable { -public: - RefBox(const T* obj) : fObj(SkRef(obj)) {} - ~RefBox() { fObj->unref(); } - - operator const T*() const { return fObj; } - -private: - const T* fObj; -}; - // A list of all the types of canvas calls we can record. // Each of these is reified into a struct below. // @@ -132,6 +120,18 @@ struct T { \ T* operator->() { return ptr; } \ const T* operator->() const { return ptr; } +template <typename T> +class RefBox : SkNoncopyable { +public: + RefBox(T* obj) : fObj(SkRef(obj)) {} + ~RefBox() { fObj->unref(); } + + ACT_AS_PTR(fObj); + +private: + T* fObj; +}; + // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data. template <typename T> class Optional : SkNoncopyable { @@ -231,7 +231,9 @@ RECORD2(DrawOval, SkPaint, paint, SkRect, oval); RECORD1(DrawPaint, SkPaint, paint); RECORD2(DrawPath, SkPaint, paint, SkPath, path); //RECORD2(DrawPatch, SkPaint, paint, SkPatch, patch); -RECORD3(DrawPicture, Optional<SkPaint>, paint, RefBox<SkPicture>, picture, Optional<SkMatrix>, matrix); +RECORD3(DrawPicture, Optional<SkPaint>, paint, + RefBox<const SkPicture>, picture, + Optional<SkMatrix>, matrix); RECORD4(DrawPoints, SkPaint, paint, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts); RECORD4(DrawPosText, SkPaint, paint, PODArray<char>, text, @@ -251,7 +253,7 @@ RECORD5(DrawText, SkPaint, paint, SkScalar, x, SkScalar, y); RECORD4(DrawTextBlob, SkPaint, paint, - RefBox<SkTextBlob>, blob, + RefBox<const SkTextBlob>, blob, SkScalar, x, SkScalar, y); RECORD5(DrawTextOnPath, SkPaint, paint, |