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

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

Issue 452983002: SkRecord: Strip out cull-skipping and y-only drawPosTextH skipping. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove dead code. 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
« no previous file with comments | « src/core/SkRecordOpts.h ('k') | src/core/SkRecords.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 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 #include "SkRecordOpts.h" 8 #include "SkRecordOpts.h"
9 9
10 #include "SkRecordPattern.h" 10 #include "SkRecordPattern.h"
11 #include "SkRecords.h" 11 #include "SkRecords.h"
12 #include "SkTDArray.h" 12 #include "SkTDArray.h"
13 13
14 using namespace SkRecords; 14 using namespace SkRecords;
15 15
16 void SkRecordOptimize(SkRecord* record) { 16 void SkRecordOptimize(SkRecord* record) {
17 // TODO(mtklein): fuse independent optimizations to reduce number of passes? 17 // TODO(mtklein): fuse independent optimizations to reduce number of passes?
18 SkRecordNoopCulls(record);
19 SkRecordNoopSaveRestores(record); 18 SkRecordNoopSaveRestores(record);
20 // TODO(mtklein): figure out why we draw differently and reenable 19 // TODO(mtklein): figure out why we draw differently and reenable
21 //SkRecordNoopSaveLayerDrawRestores(record); 20 //SkRecordNoopSaveLayerDrawRestores(record);
22 21
23 SkRecordAnnotateCullingPairs(record);
24 SkRecordReduceDrawPosTextStrength(record); // Helpful to run this before Bo undDrawPosTextH. 22 SkRecordReduceDrawPosTextStrength(record); // Helpful to run this before Bo undDrawPosTextH.
25 SkRecordBoundDrawPosTextH(record);
26 } 23 }
27 24
28 // Most of the optimizations in this file are pattern-based. These are all defi ned as structs with: 25 // Most of the optimizations in this file are pattern-based. These are all defi ned as structs with:
29 // - a Pattern typedef 26 // - a Pattern typedef
30 // - a bool onMatch(SkRceord*, Pattern*, unsigned begin, unsigned end) method, 27 // - a bool onMatch(SkRceord*, Pattern*, unsigned begin, unsigned end) method,
31 // which returns true if it made changes and false if not. 28 // which returns true if it made changes and false if not.
32 29
33 // Run a pattern-based optimization once across the SkRecord, returning true if it made any changes. 30 // Run a pattern-based optimization once across the SkRecord, returning true if it made any changes.
34 // It looks for spans which match Pass::Pattern, and when found calls onMatch() with the pattern, 31 // It looks for spans which match Pass::Pattern, and when found calls onMatch() with the pattern,
35 // record, and [begin,end) span of the commands that matched. 32 // record, and [begin,end) span of the commands that matched.
36 template <typename Pass> 33 template <typename Pass>
37 static bool apply(Pass* pass, SkRecord* record) { 34 static bool apply(Pass* pass, SkRecord* record) {
38 typename Pass::Pattern pattern; 35 typename Pass::Pattern pattern;
39 bool changed = false; 36 bool changed = false;
40 unsigned begin, end = 0; 37 unsigned begin, end = 0;
41 38
42 while (pattern.search(record, &begin, &end)) { 39 while (pattern.search(record, &begin, &end)) {
43 changed |= pass->onMatch(record, &pattern, begin, end); 40 changed |= pass->onMatch(record, &pattern, begin, end);
44 } 41 }
45 return changed; 42 return changed;
46 } 43 }
47 44
48 struct CullNooper {
49 typedef Pattern3<Is<PushCull>, Star<Is<NoOp> >, Is<PopCull> > Pattern;
50
51 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
52 record->replace<NoOp>(begin); // PushCull
53 record->replace<NoOp>(end-1); // PopCull
54 return true;
55 }
56 };
57
58 void SkRecordNoopCulls(SkRecord* record) {
59 CullNooper pass;
60 while (apply(&pass, record));
61 }
62
63 // Turns the logical NoOp Save and Restore in Save-Draw*-Restore patterns into a ctual NoOps. 45 // Turns the logical NoOp Save and Restore in Save-Draw*-Restore patterns into a ctual NoOps.
64 struct SaveOnlyDrawsRestoreNooper { 46 struct SaveOnlyDrawsRestoreNooper {
65 typedef Pattern3<Is<Save>, 47 typedef Pattern3<Is<Save>,
66 Star<Or<Is<NoOp>, IsDraw> >, 48 Star<Or<Is<NoOp>, IsDraw> >,
67 Is<Restore> > 49 Is<Restore> >
68 Pattern; 50 Pattern;
69 51
70 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) { 52 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
71 record->replace<NoOp>(begin); // Save 53 record->replace<NoOp>(begin); // Save
72 record->replace<NoOp>(end-1); // Restore 54 record->replace<NoOp>(end-1); // Restore
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 DrawPosTextH, 185 DrawPosTextH,
204 (draw->paint, draw->text, draw->byteLength, scalars , firstY)); 186 (draw->paint, draw->text, draw->byteLength, scalars , firstY));
205 return true; 187 return true;
206 } 188 }
207 }; 189 };
208 void SkRecordReduceDrawPosTextStrength(SkRecord* record) { 190 void SkRecordReduceDrawPosTextStrength(SkRecord* record) {
209 StrengthReducer pass; 191 StrengthReducer pass;
210 apply(&pass, record); 192 apply(&pass, record);
211 } 193 }
212 194
213 // Tries to replace DrawPosTextH with BoundedDrawPosTextH, which knows conservat ive upper and lower
214 // bounds to use with SkCanvas::quickRejectY.
215 struct TextBounder {
216 typedef Pattern1<Is<DrawPosTextH> > Pattern;
217
218 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
219 SkASSERT(end == begin + 1);
220 DrawPosTextH* draw = pattern->first<DrawPosTextH>();
221
222 // If we're drawing vertical text, none of the checks we're about to do make any sense.
223 // We'll need to call SkPaint::computeFastBounds() later, so bail if tha t's not possible.
224 if (draw->paint.isVerticalText() || !draw->paint.canComputeFastBounds()) {
225 return false;
226 }
227
228 // Rather than checking the top and bottom font metrics, we guess. Actu ally looking up the
229 // top and bottom metrics is slow, and this overapproximation should be good enough.
230 const SkScalar buffer = draw->paint.getTextSize() * 1.5f;
231 SkDEBUGCODE(SkPaint::FontMetrics metrics;)
232 SkDEBUGCODE(draw->paint.getFontMetrics(&metrics);)
233 SkASSERT(-buffer <= metrics.fTop);
234 SkASSERT(+buffer >= metrics.fBottom);
235
236 // Let the paint adjust the text bounds. We don't care about left and r ight here, so we use
237 // 0 and 1 respectively just so the bounds rectangle isn't empty.
238 SkRect bounds;
239 bounds.set(0, draw->y - buffer, SK_Scalar1, draw->y + buffer);
240 SkRect adjusted = draw->paint.computeFastBounds(bounds, &bounds);
241
242 Adopted<DrawPosTextH> adopted(draw);
243 SkNEW_PLACEMENT_ARGS(record->replace<BoundedDrawPosTextH>(begin, adopted ),
244 BoundedDrawPosTextH,
245 (&adopted, adjusted.fTop, adjusted.fBottom));
246 return true;
247 }
248 };
249 void SkRecordBoundDrawPosTextH(SkRecord* record) {
250 TextBounder pass;
251 apply(&pass, record);
252 }
253
254 // Replaces PushCull with PairedPushCull, which lets us skip to the paired PopCu ll when the canvas
255 // can quickReject the cull rect.
256 // There's no efficient way (yet?) to express this one as a pattern, so we write a custom pass.
257 class CullAnnotator {
258 public:
259 // Do nothing to most ops.
260 template <typename T> void operator()(T*) {}
261
262 void operator()(PushCull* push) {
263 Pair pair = { fIndex, push };
264 fPushStack.push(pair);
265 }
266
267 void operator()(PopCull* pop) {
268 Pair push = fPushStack.top();
269 fPushStack.pop();
270
271 SkASSERT(fIndex > push.index);
272 unsigned skip = fIndex - push.index;
273
274 Adopted<PushCull> adopted(push.command);
275 SkNEW_PLACEMENT_ARGS(fRecord->replace<PairedPushCull>(push.index, adopte d),
276 PairedPushCull, (&adopted, skip));
277 }
278
279 void apply(SkRecord* record) {
280 for (fRecord = record, fIndex = 0; fIndex < record->count(); fIndex++) {
281 fRecord->mutate<void>(fIndex, *this);
282 }
283 }
284
285 private:
286 struct Pair {
287 unsigned index;
288 PushCull* command;
289 };
290
291 SkTDArray<Pair> fPushStack;
292 SkRecord* fRecord;
293 unsigned fIndex;
294 };
295 void SkRecordAnnotateCullingPairs(SkRecord* record) {
296 CullAnnotator pass;
297 pass.apply(record);
298 }
OLDNEW
« no previous file with comments | « src/core/SkRecordOpts.h ('k') | src/core/SkRecords.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698