aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2014-08-21 09:11:37 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-21 09:11:38 -0700
commit53fecfb15d254397ab03032b888daa9d15c487b6 (patch)
tree369d07782c33d2a1547b155f46c6d4beb1a2686e /src
parentc2d04e1bb8e8a0973e74d17811c6a9b586719766 (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.cpp39
-rw-r--r--src/core/SkRecords.h30
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,