OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 // Some shared code used by both SkBigPicture and SkMiniPicture. | 8 // Some shared code used by both SkBigPicture and SkMiniPicture. |
9 // SkTextHunter -- SkRecord visitor that returns true when the op draws text
. | 9 // SkTextHunter -- SkRecord visitor that returns true when the op draws text
. |
10 // SkBitmapHunter -- SkRecord visitor that returns true when the op draws a bi
tmap or image. | 10 // SkBitmapHunter -- SkRecord visitor that returns true when the op draws a bi
tmap or image. |
11 // SkPathCounter -- SkRecord visitor that counts paths that draw slowly on th
e GPU. | 11 // SkPathCounter -- SkRecord visitor that counts paths that draw slowly on th
e GPU. |
12 | 12 |
13 #include "SkPathEffect.h" | 13 #include "SkPathEffect.h" |
14 #include "SkRecords.h" | 14 #include "SkRecords.h" |
15 #include "SkTLogic.h" | 15 #include "SkTLogic.h" |
16 | 16 |
17 struct SkTextHunter { | 17 struct SkTextHunter { |
18 // Most ops never have text. Some always do. Subpictures know themeselves. | 18 // Most ops never have text. Some always do. Subpictures know themeselves. |
19 template <typename T> bool operator()(const T&) { return false; } | |
20 bool operator()(const SkRecords::DrawPosText&) { return true; } | |
21 bool operator()(const SkRecords::DrawPosTextH&) { return true; } | |
22 bool operator()(const SkRecords::DrawText&) { return true; } | |
23 bool operator()(const SkRecords::DrawTextBlob&) { return true; } | |
24 bool operator()(const SkRecords::DrawTextOnPath&) { return true; } | |
25 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->hasTe
xt(); } | 19 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->hasTe
xt(); } |
| 20 bool operator()(const SkRecords::DrawDrawable&) { /*TODO*/ return false; } |
| 21 |
| 22 template <typename T> |
| 23 SK_WHEN(T::kTags & SkRecords::kHasText_Tag, bool) operator()(const T&) { ret
urn true; } |
| 24 template <typename T> |
| 25 SK_WHEN(!(T::kTags & SkRecords::kHasText_Tag), bool) operator()(const T&) {
return false; } |
26 }; | 26 }; |
27 | 27 |
28 | 28 |
29 // N.B. This name is slightly historical: hunting season is now open for SkImage
s too. | 29 // N.B. This name is slightly historical: hunting season is now open for SkImage
s too. |
30 struct SkBitmapHunter { | 30 struct SkBitmapHunter { |
31 // Helpers. These let us detect the presence of struct members with particu
lar names. | |
32 SK_CREATE_MEMBER_DETECTOR(bitmap); | |
33 SK_CREATE_MEMBER_DETECTOR(image); | |
34 SK_CREATE_MEMBER_DETECTOR(paint); | |
35 | |
36 template <typename T> | |
37 struct HasMember_bitmap_or_image { | |
38 static const bool value = HasMember_bitmap<T>::value || HasMember_image<
T>::value; | |
39 }; | |
40 | |
41 // Some ops have a paint, some have an optional paint. Either way, get back
a pointer. | 31 // Some ops have a paint, some have an optional paint. Either way, get back
a pointer. |
42 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } | 32 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } |
43 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return
p; } | 33 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return
p; } |
44 | 34 |
45 // Main entry for visitor: | 35 // Main entry for visitor: |
46 // If the op is a DrawPicture, recurse. | 36 // If the op is a DrawPicture, recurse. |
47 // If the op has a bitmap or image directly, return true. | 37 // If the op has a bitmap or image directly, return true. |
48 // If the op has a paint and the paint has a bitmap, return true. | 38 // If the op has a paint and the paint has a bitmap, return true. |
49 // Otherwise, return false. | 39 // Otherwise, return false. |
50 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->willP
layBackBitmaps(); } | 40 bool operator()(const SkRecords::DrawPicture& op) { return op.picture->willP
layBackBitmaps(); } |
| 41 bool operator()(const SkRecords::DrawDrawable&) { /*TODO*/ return false; } |
51 | 42 |
52 template <typename T> | 43 template <typename T> |
53 bool operator()(const T& r) { return CheckBitmap(r); } | 44 bool operator()(const T& op) { return CheckBitmap(op); } |
54 | 45 |
55 // If the op has a bitmap, of course we're going to play back bitmaps. | 46 // If the op is tagged as having an image, return true. |
56 template <typename T> | 47 template <typename T> |
57 static SK_WHEN(HasMember_bitmap_or_image<T>, bool) CheckBitmap(const T&) { | 48 static SK_WHEN(T::kTags & SkRecords::kHasImage_Tag, bool) CheckBitmap(const
T&) { |
58 return true; | 49 return true; |
59 } | 50 } |
60 | 51 |
61 // If not, look for one in its paint (if it has a paint). | 52 // If not, look for one in its paint (if it has a paint). |
62 template <typename T> | 53 template <typename T> |
63 static SK_WHEN(!HasMember_bitmap_or_image<T>, bool) CheckBitmap(const T& r)
{ | 54 static SK_WHEN(!(T::kTags & SkRecords::kHasImage_Tag), bool) CheckBitmap(con
st T& op) { |
64 return CheckPaint(r); | 55 return CheckPaint(op); |
65 } | 56 } |
66 | 57 |
67 // If we have a paint, dig down into the effects looking for a bitmap. | 58 // Most draws-type ops have paints. |
68 template <typename T> | 59 template <typename T> |
69 static SK_WHEN(HasMember_paint<T>, bool) CheckPaint(const T& r) { | 60 static SK_WHEN(T::kTags & SkRecords::kDraw_Tag, bool) CheckPaint(const T& op
) { |
70 const SkPaint* paint = AsPtr(r.paint); | 61 return PaintHasBitmap(AsPtr(op.paint)); |
| 62 } |
| 63 |
| 64 // SaveLayers also have a paint to check. |
| 65 static bool CheckPaint(const SkRecords::SaveLayer& op) { |
| 66 return PaintHasBitmap(AsPtr(op.paint)); |
| 67 } |
| 68 |
| 69 // Shouldn't be any non-Draw non-SaveLayer ops with paints. |
| 70 template <typename T> |
| 71 static SK_WHEN(!(T::kTags & SkRecords::kDraw_Tag), bool) CheckPaint(const T&
) { |
| 72 return false; |
| 73 } |
| 74 |
| 75 private: |
| 76 static bool PaintHasBitmap(const SkPaint* paint) { |
71 if (paint) { | 77 if (paint) { |
72 const SkShader* shader = paint->getShader(); | 78 const SkShader* shader = paint->getShader(); |
73 if (shader && shader->isABitmap()) { | 79 if (shader && shader->isABitmap()) { |
74 return true; | 80 return true; |
75 } | 81 } |
76 } | 82 } |
77 return false; | 83 return false; |
78 } | 84 } |
79 | |
80 // If we don't have a paint, that non-paint has no bitmap. | |
81 template <typename T> | |
82 static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return fals
e; } | |
83 }; | 85 }; |
84 | 86 |
85 // TODO: might be nicer to have operator() return an int (the number of slow pat
hs) ? | 87 // TODO: might be nicer to have operator() return an int (the number of slow pat
hs) ? |
86 struct SkPathCounter { | 88 struct SkPathCounter { |
87 SK_CREATE_MEMBER_DETECTOR(paint); | |
88 | |
89 // Some ops have a paint, some have an optional paint. Either way, get back
a pointer. | 89 // Some ops have a paint, some have an optional paint. Either way, get back
a pointer. |
90 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } | 90 static const SkPaint* AsPtr(const SkPaint& p) { return &p; } |
91 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return
p; } | 91 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return
p; } |
92 | 92 |
93 SkPathCounter() : fNumSlowPathsAndDashEffects(0) {} | 93 SkPathCounter() : fNumSlowPathsAndDashEffects(0) {} |
94 | 94 |
95 // Recurse into nested pictures. | 95 // Recurse into nested pictures. |
96 void operator()(const SkRecords::DrawPicture& op) { | 96 void operator()(const SkRecords::DrawPicture& op) { |
97 fNumSlowPathsAndDashEffects += op.picture->numSlowPaths(); | 97 fNumSlowPathsAndDashEffects += op.picture->numSlowPaths(); |
98 } | 98 } |
| 99 void operator()(const SkRecords::DrawDrawable&) { /* TODO */ } |
99 | 100 |
100 void checkPaint(const SkPaint* paint) { | 101 void checkPaint(const SkPaint* paint) { |
101 if (paint && paint->getPathEffect()) { | 102 if (paint && paint->getPathEffect()) { |
102 // Initially assume it's slow. | 103 // Initially assume it's slow. |
103 fNumSlowPathsAndDashEffects++; | 104 fNumSlowPathsAndDashEffects++; |
104 } | 105 } |
105 } | 106 } |
106 | 107 |
107 void operator()(const SkRecords::DrawPoints& op) { | 108 void operator()(const SkRecords::DrawPoints& op) { |
108 this->checkPaint(&op.paint); | 109 this->checkPaint(&op.paint); |
(...skipping 18 matching lines...) Expand all Loading... |
127 // AA hairline concave path is not slow. | 128 // AA hairline concave path is not slow. |
128 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width()
< 64.f && | 129 } else if (SkPaint::kFill_Style == paintStyle && pathBounds.width()
< 64.f && |
129 pathBounds.height() < 64.f && !op.path.isVolatile()) { | 130 pathBounds.height() < 64.f && !op.path.isVolatile()) { |
130 // AADF eligible concave path is not slow. | 131 // AADF eligible concave path is not slow. |
131 } else { | 132 } else { |
132 fNumSlowPathsAndDashEffects++; | 133 fNumSlowPathsAndDashEffects++; |
133 } | 134 } |
134 } | 135 } |
135 } | 136 } |
136 | 137 |
137 template <typename T> | 138 void operator()(const SkRecords::SaveLayer& op) { |
138 SK_WHEN(HasMember_paint<T>, void) operator()(const T& op) { | |
139 this->checkPaint(AsPtr(op.paint)); | 139 this->checkPaint(AsPtr(op.paint)); |
140 } | 140 } |
141 | 141 |
142 template <typename T> | 142 template <typename T> |
143 SK_WHEN(!HasMember_paint<T>, void) operator()(const T& op) { /* do nothing *
/ } | 143 SK_WHEN(T::kTags & SkRecords::kDraw_Tag, void) operator()(const T& op) { |
| 144 this->checkPaint(AsPtr(op.paint)); |
| 145 } |
| 146 |
| 147 template <typename T> |
| 148 SK_WHEN(!(T::kTags & SkRecords::kDraw_Tag), void) operator()(const T& op) {
/* do nothing */ } |
144 | 149 |
145 int fNumSlowPathsAndDashEffects; | 150 int fNumSlowPathsAndDashEffects; |
146 }; | 151 }; |
OLD | NEW |