Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: src/core/SkRecordAnalysis.cpp

Issue 364823009: Port suitableForGpuRasterization to SkRecord (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: More SkPicture.h cleanup Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include "SkRecordAnalysis.h" 1 #include "SkRecordAnalysis.h"
2 2
3 #include "SkPathEffect.h"
3 #include "SkShader.h" 4 #include "SkShader.h"
4 #include "SkTLogic.h" 5 #include "SkTLogic.h"
5 6
7
8 namespace {
9
6 /** SkRecords visitor to determine whether an instance may require an 10 /** SkRecords visitor to determine whether an instance may require an
7 "external" bitmap to rasterize. May return false positives. 11 "external" bitmap to rasterize. May return false positives.
8 Does not return true for bitmap text. 12 Does not return true for bitmap text.
9 13
10 Expected use is to determine whether images need to be decoded before 14 Expected use is to determine whether images need to be decoded before
11 rasterizing a particular SkRecord. 15 rasterizing a particular SkRecord.
12 */ 16 */
13 struct BitmapTester { 17 struct BitmapTester {
14 // Helpers. These create HasMember_bitmap and HasMember_paint. 18 // Helpers. These create HasMember_bitmap and HasMember_paint.
15 SK_CREATE_MEMBER_DETECTOR(bitmap); 19 SK_CREATE_MEMBER_DETECTOR(bitmap);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 } 52 }
49 } 53 }
50 return false; 54 return false;
51 } 55 }
52 56
53 // If we don't have a paint, that non-paint has no bitmap. 57 // If we don't have a paint, that non-paint has no bitmap.
54 template <typename T> 58 template <typename T>
55 static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return fals e; } 59 static SK_WHEN(!HasMember_paint<T>, bool) CheckPaint(const T&) { return fals e; }
56 }; 60 };
57 61
58 bool SkRecordWillPlaybackBitmaps(const SkRecord& record) { 62 bool SkWillPlaybackBitmaps(const SkRecord& record) {
59 BitmapTester tester; 63 BitmapTester tester;
60 for (unsigned i = 0; i < record.count(); i++) { 64 for (unsigned i = 0; i < record.count(); i++) {
61 if (record.visit<bool>(i, tester)) { 65 if (record.visit<bool>(i, tester)) {
62 return true; 66 return true;
63 } 67 }
64 } 68 }
65 return false; 69 return false;
66 } 70 }
71
72 struct PathCounter {
73 SK_CREATE_MEMBER_DETECTOR(paint);
74 SK_CREATE_TYPE_DETECTOR(DrawPoints);
75 SK_CREATE_TYPE_DETECTOR(DrawPath);
76
77 // Some commands have a paint, some have an optional paint. Either way, get back a pointer.
78 static const SkPaint* AsPtr(const SkPaint& p) { return &p; }
79 static const SkPaint* AsPtr(const SkRecords::Optional<SkPaint>& p) { return p; }
80
81 PathCounter()
82 : numPaintWithPathEffectUses (0)
83 , numFastPathDashEffects (0)
84 , numAAConcavePaths (0)
85 , numAAHairlineConcavePaths (0) {
86 }
87
88 // Must have a return type to make the SkRecord vistor templates happy.
89 template <typename T>
90 bool operator()(const T& r) {
91 CheckPaint(r);
92 CheckDrawPoints(r);
93 CheckDrawPath(r);
94 return true;
95 }
96
97 template <typename T>
98 SK_WHEN(HasMember_paint<T>, void) CheckPaint(const T& r) {
99 const SkPaint* paint = AsPtr(r.paint);
100 if (paint && paint->getPathEffect()) {
101 numPaintWithPathEffectUses++;
102 }
103 }
104
105 template <typename T>
106 SK_WHEN(!HasMember_paint<T>, void) CheckPaint(const T& r) { /* do nothing */ }
107
108 template <typename T>
109 SK_WHEN(HasType_DrawPoints<T>, void) CheckDrawPoints(const T& r) {
110 const SkPathEffect* effect = r.paint.getPathEffect();
111 if (effect) {
112 SkPathEffect::DashInfo info;
113 SkPathEffect::DashType dashType = effect->asADash(&info);
114 if (2 == r.count && SkPaint::kRound_Cap != r.paint.getStrokeCap() &&
115 SkPathEffect::kDash_DashType == dashType && 2 == info.fCount) {
116 numFastPathDashEffects++;
117 }
118 }
119 }
120
121 template <typename T>
122 SK_WHEN(!HasType_DrawPoints<T>, void) CheckDrawPoints(const T& r) { /* do no thing */ }
123
124 template <typename T>
125 SK_WHEN(HasType_DrawPath<T>, void) CheckDrawPath(const T& r) {
126 if (r.paint.isAntiAlias() && !r.path.isConvex()) {
127 numAAConcavePaths++;
128
129 if (SkPaint::kStroke_Style == r.paint.getStyle() &&
130 0 == r.paint.getStrokeWidth()) {
131 numAAHairlineConcavePaths++;
132 }
133 }
134 }
135
136 template <typename T>
137 SK_WHEN(!HasType_DrawPath<T>, void) CheckDrawPath(const T& r) { /* do nothin g */ }
138
139
140 int numPaintWithPathEffectUses;
141 int numFastPathDashEffects;
142 int numAAConcavePaths;
143 int numAAHairlineConcavePaths;
144 };
145
146 bool SkRecordSuitableForGpuRasterization(const SkRecord& record,
147 const char** reason = NULL,
148 int sampleCount = 0) {
149 PathCounter counter;
150 for (unsigned i = 0; i < record.count(); i++) {
151 record.visit<bool>(i, counter);
152 }
153
154 // TODO: the heuristic used here needs to be refined
155 static const int kNumPaintWithPathEffectsUsesTol = 1;
156 static const int kNumAAConcavePathsTol = 5;
157
158 int numNonDashedPathEffects = counter.numPaintWithPathEffectUses -
159 counter.numFastPathDashEffects;
160 bool suitableForDash = (0 == counter.numPaintWithPathEffectUses) ||
161 (numNonDashedPathEffects < kNumPaintWithPathEffectsUs esTol
162 && 0 == sampleCount);
163
164 bool ret = suitableForDash &&
165 (counter.numAAConcavePaths - counter.numAAHairlineConcavePaths)
166 < kNumAAConcavePathsTol;
167
168 if (!ret && NULL != reason) {
169 if (!suitableForDash) {
170 if (0 != sampleCount) {
171 *reason = "Can't use multisample on dash effect.";
172 } else {
173 *reason = "Too many non dashed path effects.";
174 }
175 } else if ((counter.numAAConcavePaths - counter.numAAHairlineConcavePath s)
176 >= kNumAAConcavePathsTol)
177 *reason = "Too many anti-aliased concave paths.";
178 else
179 *reason = "Unknown reason for GPU unsuitability.";
180 }
181 return ret;
182 }
183
184 } // namespace
185
186 SkRecordAnalysis AnalyzeSkRecord(const SkRecord& record) {
187 SkRecordAnalysis results;
188
189 results.fWillPlaybackBitmaps = SkWillPlaybackBitmaps(record);
190 results.fSuitableForGpuRasterization = SkRecordSuitableForGpuRasterization(r ecord);
191
192 return results;
193 }
194
OLDNEW
« src/core/SkRecord.h ('K') | « src/core/SkRecordAnalysis.h ('k') | tests/RecordTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698