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

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: notes 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
« no previous file with comments | « src/record/SkRecordOpts.h ('k') | tests/RecordOptsTest.cpp » ('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 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();
100 if (!IsOnlyAlpha(layerColor) || !IsOpaque(drawColor) || HasAnyEffect(*la yerPaint)) {
101 // Too fancy for us. Actually, as long as layerColor is just an alp ha
102 // we can blend it into drawColor's alpha; drawColor doesn't strictl y have to be opaque.
103 return false;
104 }
105
106 drawPaint->setColor(SkColorSetA(drawColor, SkColorGetA(layerColor)));
107 return KillSaveLayerAndRestore(record, begin);
108 }
109
110 static bool KillSaveLayerAndRestore(SkRecord* record, unsigned saveLayerInde x) {
111 record->replace<NoOp>(saveLayerIndex); // SaveLayer
112 record->replace<NoOp>(saveLayerIndex+2); // Restore
113 return true;
114 }
115
116 static bool HasAnyEffect(const SkPaint& paint) {
117 return paint.getPathEffect() ||
118 paint.getShader() ||
119 paint.getXfermode() ||
120 paint.getMaskFilter() ||
121 paint.getColorFilter() ||
122 paint.getRasterizer() ||
123 paint.getLooper() ||
124 paint.getImageFilter();
125 }
126
127 static bool IsOpaque(SkColor color) {
128 return SkColorGetA(color) == SK_AlphaOPAQUE;
129 }
130 static bool IsOnlyAlpha(SkColor color) {
131 return SK_ColorTRANSPARENT == SkColorSetA(color, SK_AlphaTRANSPARENT);
132 }
133 };
134 void SkRecordNoopSaveLayerDrawRestores(SkRecord* record) {
135 SaveLayerDrawRestoreNooper pass;
136 apply(&pass, record);
137 }
138
139
72 // Replaces DrawPosText with DrawPosTextH when all Y coordinates are equal. 140 // Replaces DrawPosText with DrawPosTextH when all Y coordinates are equal.
73 struct StrengthReducer { 141 struct StrengthReducer {
74 typedef Pattern1<Is<DrawPosText> > Pattern; 142 typedef Pattern1<Is<DrawPosText> > Pattern;
75 143
76 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) { 144 bool onMatch(SkRecord* record, Pattern* pattern, unsigned begin, unsigned en d) {
77 SkASSERT(end == begin + 1); 145 SkASSERT(end == begin + 1);
78 DrawPosText* draw = pattern->first<DrawPosText>(); 146 DrawPosText* draw = pattern->first<DrawPosText>();
79 147
80 const unsigned points = draw->paint.countText(draw->text, draw->byteLeng th); 148 const unsigned points = draw->paint.countText(draw->text, draw->byteLeng th);
81 if (points == 0) { 149 if (points == 0) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 }; 259 };
192 260
193 SkTDArray<Pair> fPushStack; 261 SkTDArray<Pair> fPushStack;
194 SkRecord* fRecord; 262 SkRecord* fRecord;
195 unsigned fIndex; 263 unsigned fIndex;
196 }; 264 };
197 void SkRecordAnnotateCullingPairs(SkRecord* record) { 265 void SkRecordAnnotateCullingPairs(SkRecord* record) {
198 CullAnnotator pass; 266 CullAnnotator pass;
199 pass.apply(record); 267 pass.apply(record);
200 } 268 }
OLDNEW
« no previous file with comments | « src/record/SkRecordOpts.h ('k') | tests/RecordOptsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698