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

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

Issue 269813010: Add SaveLayer-Draw-Restore optimization. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: returns Created 6 years, 7 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 /* 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 SkRecordNoopSaveRestores(record); 18 SkRecordNoopSaveRestores(record);
19 SkRecordNoopSaveLayerDrawRestores(record);
19 SkRecordAnnotateCullingPairs(record); 20 SkRecordAnnotateCullingPairs(record);
20 SkRecordReduceDrawPosTextStrength(record); // Helpful to run this before Bo undDrawPosTextH. 21 SkRecordReduceDrawPosTextStrength(record); // Helpful to run this before Bo undDrawPosTextH.
21 SkRecordBoundDrawPosTextH(record); 22 SkRecordBoundDrawPosTextH(record);
22 } 23 }
23 24
24 // 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:
25 // - a Pattern typedef 26 // - a Pattern typedef
26 // - a bool onMatch(SkRceord*, Pattern*, unsigned begin, unsigned end) method, 27 // - a bool onMatch(SkRceord*, Pattern*, unsigned begin, unsigned end) method,
27 // which returns true if it made changes and false if not. 28 // which returns true if it made changes and false if not.
28 29
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 record->replace<NoOp>(i); 63 record->replace<NoOp>(i);
63 } 64 }
64 return true; 65 return true;
65 } 66 }
66 }; 67 };
67 void SkRecordNoopSaveRestores(SkRecord* record) { 68 void SkRecordNoopSaveRestores(SkRecord* record) {
68 SaveRestoreNooper pass; 69 SaveRestoreNooper pass;
69 while (apply(&pass, record)); // Run until it stops changing things. 70 while (apply(&pass, record)); // Run until it stops changing things.
70 } 71 }
71 72
73 // For some SaveLayer-[drawing command]-Restore patterns, merge the SaveLayer's alpha into the
74 // draw, and no-op the SaveLayer and Restore.
75 struct SaveLayerDrawRestoreNooper {
76 typedef Pattern3<Is<SaveLayer>, IsDraw, Is<Restore> > Pattern;
77
78 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
79 SaveLayer* saveLayer = pattern->first<SaveLayer>();
80 if (saveLayer->bounds != NULL) {
81 // SaveLayer with bounds is too tricky for us.
82 return false;
83 }
84
85 SkPaint* layerPaint = saveLayer->paint;
86 if (NULL == layerPaint) {
87 // There wasn't really any point to this SaveLayer at all.
88 return KillSaveLayerAndRestore(record, begin);
89 }
90
91 SkPaint* drawPaint = pattern->second<SkPaint>();
92 if (drawPaint == NULL) {
93 // We can just give the draw the SaveLayer's paint.
94 // TODO(mtklein): figure out how to do this clearly
95 return false;
96 }
97
98 const uint32_t layerColor = layerPaint->getColor();
99 const uint32_t drawColor = drawPaint->getColor();
robertphillips 2014/05/07 14:28:15 In some cases we could (in the distant future) com
mtklein 2014/05/07 14:38:14 Oh, right. Noted. Seems everything I could find
100 if (!IsOnlyAlpha(layerColor) || !IsOpaque(drawColor) || HasAnyEffect(*la yerPaint)) {
101 // Too fancy for us.
102 return false;
103 }
104
105 drawPaint->setColor(SkColorSetA(drawColor, SkColorGetA(layerColor)));
106 return KillSaveLayerAndRestore(record, begin);
107 }
108
109 static bool KillSaveLayerAndRestore(SkRecord* record, unsigned saveLayerInde x) {
110 record->replace<NoOp>(saveLayerIndex); // SaveLayer
111 record->replace<NoOp>(saveLayerIndex+2); // Restore
112 return true;
113 }
114
115 static bool HasAnyEffect(const SkPaint& paint) {
116 return paint.getPathEffect() ||
117 paint.getShader() ||
118 paint.getXfermode() ||
119 paint.getMaskFilter() ||
120 paint.getColorFilter() ||
121 paint.getRasterizer() ||
122 paint.getLooper() ||
123 paint.getImageFilter();
124 }
125
126 static bool IsOpaque(SkColor color) {
127 return SkColorGetA(color) == SK_AlphaOPAQUE;
128 }
129 static bool IsOnlyAlpha(SkColor color) {
130 return SK_ColorTRANSPARENT == SkColorSetA(color, SK_AlphaTRANSPARENT);
131 }
132 };
133 void SkRecordNoopSaveLayerDrawRestores(SkRecord* record) {
134 SaveLayerDrawRestoreNooper pass;
135 apply(&pass, record);
136 }
137
138
72 // Replaces DrawPosText with DrawPosTextH when all Y coordinates are equal. 139 // Replaces DrawPosText with DrawPosTextH when all Y coordinates are equal.
73 struct StrengthReducer { 140 struct StrengthReducer {
74 typedef Pattern1<Is<DrawPosText> > Pattern; 141 typedef Pattern1<Is<DrawPosText> > Pattern;
75 142
76 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) { 143 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
77 SkASSERT(end == begin + 1); 144 SkASSERT(end == begin + 1);
78 DrawPosText* draw = pattern->first<DrawPosText>(); 145 DrawPosText* draw = pattern->first<DrawPosText>();
79 146
80 const unsigned points = draw->paint.countText(draw->text, draw->byteLeng th); 147 const unsigned points = draw->paint.countText(draw->text, draw->byteLeng th);
81 if (points == 0) { 148 if (points == 0) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 }; 258 };
192 259
193 SkTDArray<Pair> fPushStack; 260 SkTDArray<Pair> fPushStack;
194 SkRecord* fRecord; 261 SkRecord* fRecord;
195 unsigned fIndex; 262 unsigned fIndex;
196 }; 263 };
197 void SkRecordAnnotateCullingPairs(SkRecord* record) { 264 void SkRecordAnnotateCullingPairs(SkRecord* record) {
198 CullAnnotator pass; 265 CullAnnotator pass;
199 pass.apply(record); 266 pass.apply(record);
200 } 267 }
OLDNEW
« no previous file with comments | « src/record/SkRecordOpts.h ('k') | tests/RecordOptsTest.cpp » ('j') | tests/RecordOptsTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698