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

Side by Side Diff: skia/ext/analysis_canvas.cc

Issue 418093003: skia/ext: Early out from analysis when we have more than 1 draw op. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « skia/ext/analysis_canvas.h ('k') | skia/ext/analysis_canvas_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/debug/trace_event.h" 5 #include "base/debug/trace_event.h"
6 #include "base/logging.h" 6 #include "base/logging.h"
7 #include "skia/ext/analysis_canvas.h" 7 #include "skia/ext/analysis_canvas.h"
8 #include "third_party/skia/include/core/SkDraw.h" 8 #include "third_party/skia/include/core/SkDraw.h"
9 #include "third_party/skia/include/core/SkRRect.h" 9 #include "third_party/skia/include/core/SkRRect.h"
10 #include "third_party/skia/include/core/SkShader.h" 10 #include "third_party/skia/include/core/SkShader.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 } 73 }
74 74
75 void AnalysisCanvas::SetForceNotTransparent(bool flag) { 75 void AnalysisCanvas::SetForceNotTransparent(bool flag) {
76 is_forced_not_transparent_ = flag; 76 is_forced_not_transparent_ = flag;
77 if (is_forced_not_transparent_) 77 if (is_forced_not_transparent_)
78 is_transparent_ = false; 78 is_transparent_ = false;
79 } 79 }
80 80
81 void AnalysisCanvas::clear(SkColor color) { 81 void AnalysisCanvas::clear(SkColor color) {
82 is_transparent_ = (!is_forced_not_transparent_ && SkColorGetA(color) == 0); 82 is_transparent_ = (!is_forced_not_transparent_ && SkColorGetA(color) == 0);
83 has_text_ = false;
84 83
85 if (!is_forced_not_solid_ && SkColorGetA(color) == 255) { 84 if (!is_forced_not_solid_ && SkColorGetA(color) == 255) {
86 is_solid_color_ = true; 85 is_solid_color_ = true;
87 color_ = color; 86 color_ = color;
88 } else { 87 } else {
89 is_solid_color_ = false; 88 is_solid_color_ = false;
90 } 89 }
91 } 90 }
92 91
93 void AnalysisCanvas::drawPaint(const SkPaint& paint) { 92 void AnalysisCanvas::drawPaint(const SkPaint& paint) {
94 // This check is in SkCanvas::drawPaint(), and some of our unittests rely on 93 // This check is in SkCanvas::drawPaint(), and some of our unittests rely on
95 // on this, so we reproduce it here. 94 // on this, so we reproduce it here.
96 if (isClipEmpty()) 95 if (isClipEmpty())
97 return; 96 return;
98 97
99 is_solid_color_ = false; 98 is_solid_color_ = false;
100 is_transparent_ = false; 99 is_transparent_ = false;
100 ++draw_op_count_;
101 } 101 }
102 102
103 void AnalysisCanvas::drawPoints(SkCanvas::PointMode mode, 103 void AnalysisCanvas::drawPoints(SkCanvas::PointMode mode,
104 size_t count, 104 size_t count,
105 const SkPoint points[], 105 const SkPoint points[],
106 const SkPaint& paint) { 106 const SkPaint& paint) {
107 is_solid_color_ = false; 107 is_solid_color_ = false;
108 is_transparent_ = false; 108 is_transparent_ = false;
109 ++draw_op_count_;
109 } 110 }
110 111
111 void AnalysisCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { 112 void AnalysisCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
112 // This recreates the early-exit logic in SkCanvas.cpp, which aborts early 113 // This recreates the early-exit logic in SkCanvas.cpp, which aborts early
113 // if the paint will "draw nothing". 114 // if the paint will "draw nothing".
114 if (paint.nothingToDraw()) 115 if (paint.nothingToDraw())
115 return; 116 return;
116 117
117 bool does_cover_canvas = IsFullQuad(this, rect); 118 bool does_cover_canvas = IsFullQuad(this, rect);
118 119
119 SkXfermode::Mode xfermode; 120 SkXfermode::Mode xfermode;
120 SkXfermode::AsMode(paint.getXfermode(), &xfermode); 121 SkXfermode::AsMode(paint.getXfermode(), &xfermode);
121 122
122 // This canvas will become transparent if the following holds: 123 // This canvas will become transparent if the following holds:
123 // - The quad is a full tile quad 124 // - The quad is a full tile quad
124 // - We're not in "forced not transparent" mode 125 // - We're not in "forced not transparent" mode
125 // - Transfer mode is clear (0 color, 0 alpha) 126 // - Transfer mode is clear (0 color, 0 alpha)
126 // 127 //
127 // If the paint alpha is not 0, or if the transfrer mode is 128 // If the paint alpha is not 0, or if the transfrer mode is
128 // not src, then this canvas will not be transparent. 129 // not src, then this canvas will not be transparent.
129 // 130 //
130 // In all other cases, we keep the current transparent value 131 // In all other cases, we keep the current transparent value
131 if (does_cover_canvas && 132 if (does_cover_canvas &&
132 !is_forced_not_transparent_ && 133 !is_forced_not_transparent_ &&
133 xfermode == SkXfermode::kClear_Mode) { 134 xfermode == SkXfermode::kClear_Mode) {
134 is_transparent_ = true; 135 is_transparent_ = true;
135 has_text_ = false;
136 } else if (paint.getAlpha() != 0 || xfermode != SkXfermode::kSrc_Mode) { 136 } else if (paint.getAlpha() != 0 || xfermode != SkXfermode::kSrc_Mode) {
137 is_transparent_ = false; 137 is_transparent_ = false;
138 } 138 }
139 139
140 // This bitmap is solid if and only if the following holds. 140 // This bitmap is solid if and only if the following holds.
141 // Note that this might be overly conservative: 141 // Note that this might be overly conservative:
142 // - We're not in "forced not solid" mode 142 // - We're not in "forced not solid" mode
143 // - Paint is solid color 143 // - Paint is solid color
144 // - The quad is a full tile quad 144 // - The quad is a full tile quad
145 if (!is_forced_not_solid_ && IsSolidColorPaint(paint) && does_cover_canvas) { 145 if (!is_forced_not_solid_ && IsSolidColorPaint(paint) && does_cover_canvas) {
146 is_solid_color_ = true; 146 is_solid_color_ = true;
147 color_ = paint.getColor(); 147 color_ = paint.getColor();
148 has_text_ = false;
149 } else { 148 } else {
150 is_solid_color_ = false; 149 is_solid_color_ = false;
151 } 150 }
151 ++draw_op_count_;
152 } 152 }
153 153
154 void AnalysisCanvas::drawOval(const SkRect& oval, const SkPaint& paint) { 154 void AnalysisCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
155 is_solid_color_ = false; 155 is_solid_color_ = false;
156 is_transparent_ = false; 156 is_transparent_ = false;
157 ++draw_op_count_;
157 } 158 }
158 159
159 void AnalysisCanvas::drawRRect(const SkRRect& rr, const SkPaint& paint) { 160 void AnalysisCanvas::drawRRect(const SkRRect& rr, const SkPaint& paint) {
160 // This should add the SkRRect to an SkPath, and call 161 // This should add the SkRRect to an SkPath, and call
161 // drawPath, but since drawPath ignores the SkPath, just 162 // drawPath, but since drawPath ignores the SkPath, just
162 // do the same work here. 163 // do the same work here.
163 is_solid_color_ = false; 164 is_solid_color_ = false;
164 is_transparent_ = false; 165 is_transparent_ = false;
166 ++draw_op_count_;
165 } 167 }
166 168
167 void AnalysisCanvas::drawPath(const SkPath& path, const SkPaint& paint) { 169 void AnalysisCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
168 is_solid_color_ = false; 170 is_solid_color_ = false;
169 is_transparent_ = false; 171 is_transparent_ = false;
172 ++draw_op_count_;
170 } 173 }
171 174
172 void AnalysisCanvas::drawBitmap(const SkBitmap& bitmap, 175 void AnalysisCanvas::drawBitmap(const SkBitmap& bitmap,
173 SkScalar left, 176 SkScalar left,
174 SkScalar top, 177 SkScalar top,
175 const SkPaint*) { 178 const SkPaint*) {
176 is_solid_color_ = false; 179 is_solid_color_ = false;
177 is_transparent_ = false; 180 is_transparent_ = false;
181 ++draw_op_count_;
178 } 182 }
179 183
180 void AnalysisCanvas::drawBitmapRectToRect(const SkBitmap&, 184 void AnalysisCanvas::drawBitmapRectToRect(const SkBitmap&,
181 const SkRect* src, 185 const SkRect* src,
182 const SkRect& dst, 186 const SkRect& dst,
183 const SkPaint* paint, 187 const SkPaint* paint,
184 DrawBitmapRectFlags flags) { 188 DrawBitmapRectFlags flags) {
185 // Call drawRect to determine transparency, 189 // Call drawRect to determine transparency,
186 // but reset solid color to false. 190 // but reset solid color to false.
187 SkPaint tmpPaint; 191 SkPaint tmpPaint;
188 if (!paint) 192 if (!paint)
189 paint = &tmpPaint; 193 paint = &tmpPaint;
190 drawRect(dst, *paint); 194 drawRect(dst, *paint);
191 is_solid_color_ = false; 195 is_solid_color_ = false;
196 ++draw_op_count_;
192 } 197 }
193 198
194 void AnalysisCanvas::drawBitmapMatrix(const SkBitmap& bitmap, 199 void AnalysisCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
195 const SkMatrix& matrix, 200 const SkMatrix& matrix,
196 const SkPaint* paint) { 201 const SkPaint* paint) {
197 is_solid_color_ = false; 202 is_solid_color_ = false;
198 is_transparent_ = false; 203 is_transparent_ = false;
204 ++draw_op_count_;
199 } 205 }
200 206
201 void AnalysisCanvas::drawBitmapNine(const SkBitmap& bitmap, 207 void AnalysisCanvas::drawBitmapNine(const SkBitmap& bitmap,
202 const SkIRect& center, 208 const SkIRect& center,
203 const SkRect& dst, 209 const SkRect& dst,
204 const SkPaint* paint) { 210 const SkPaint* paint) {
205 is_solid_color_ = false; 211 is_solid_color_ = false;
206 is_transparent_ = false; 212 is_transparent_ = false;
213 ++draw_op_count_;
207 } 214 }
208 215
209 void AnalysisCanvas::drawSprite(const SkBitmap& bitmap, 216 void AnalysisCanvas::drawSprite(const SkBitmap& bitmap,
210 int left, 217 int left,
211 int top, 218 int top,
212 const SkPaint* paint) { 219 const SkPaint* paint) {
213 is_solid_color_ = false; 220 is_solid_color_ = false;
214 is_transparent_ = false; 221 is_transparent_ = false;
222 ++draw_op_count_;
215 } 223 }
216 224
217 void AnalysisCanvas::onDrawText(const void* text, 225 void AnalysisCanvas::onDrawText(const void* text,
218 size_t len, 226 size_t len,
219 SkScalar x, 227 SkScalar x,
220 SkScalar y, 228 SkScalar y,
221 const SkPaint& paint) { 229 const SkPaint& paint) {
222 is_solid_color_ = false; 230 is_solid_color_ = false;
223 is_transparent_ = false; 231 is_transparent_ = false;
224 has_text_ = true; 232 ++draw_op_count_;
225 } 233 }
226 234
227 void AnalysisCanvas::onDrawPosText(const void* text, 235 void AnalysisCanvas::onDrawPosText(const void* text,
228 size_t byteLength, 236 size_t byteLength,
229 const SkPoint pos[], 237 const SkPoint pos[],
230 const SkPaint& paint) { 238 const SkPaint& paint) {
231 is_solid_color_ = false; 239 is_solid_color_ = false;
232 is_transparent_ = false; 240 is_transparent_ = false;
233 has_text_ = true; 241 ++draw_op_count_;
234 } 242 }
235 243
236 void AnalysisCanvas::onDrawPosTextH(const void* text, 244 void AnalysisCanvas::onDrawPosTextH(const void* text,
237 size_t byteLength, 245 size_t byteLength,
238 const SkScalar xpos[], 246 const SkScalar xpos[],
239 SkScalar constY, 247 SkScalar constY,
240 const SkPaint& paint) { 248 const SkPaint& paint) {
241 is_solid_color_ = false; 249 is_solid_color_ = false;
242 is_transparent_ = false; 250 is_transparent_ = false;
243 has_text_ = true; 251 ++draw_op_count_;
244 } 252 }
245 253
246 void AnalysisCanvas::onDrawTextOnPath(const void* text, 254 void AnalysisCanvas::onDrawTextOnPath(const void* text,
247 size_t len, 255 size_t len,
248 const SkPath& path, 256 const SkPath& path,
249 const SkMatrix* matrix, 257 const SkMatrix* matrix,
250 const SkPaint& paint) { 258 const SkPaint& paint) {
251 is_solid_color_ = false; 259 is_solid_color_ = false;
252 is_transparent_ = false; 260 is_transparent_ = false;
253 has_text_ = true; 261 ++draw_op_count_;
254 } 262 }
255 263
256 void AnalysisCanvas::onDrawDRRect(const SkRRect& outer, 264 void AnalysisCanvas::onDrawDRRect(const SkRRect& outer,
257 const SkRRect& inner, 265 const SkRRect& inner,
258 const SkPaint& paint) { 266 const SkPaint& paint) {
259 is_solid_color_ = false; 267 is_solid_color_ = false;
260 is_transparent_ = false; 268 is_transparent_ = false;
269 ++draw_op_count_;
261 } 270 }
262 271
263 void AnalysisCanvas::drawVertices(SkCanvas::VertexMode, 272 void AnalysisCanvas::drawVertices(SkCanvas::VertexMode,
264 int vertex_count, 273 int vertex_count,
265 const SkPoint verts[], 274 const SkPoint verts[],
266 const SkPoint texs[], 275 const SkPoint texs[],
267 const SkColor colors[], 276 const SkColor colors[],
268 SkXfermode* xmode, 277 SkXfermode* xmode,
269 const uint16_t indices[], 278 const uint16_t indices[],
270 int index_count, 279 int index_count,
271 const SkPaint& paint) { 280 const SkPaint& paint) {
272 is_solid_color_ = false; 281 is_solid_color_ = false;
273 is_transparent_ = false; 282 is_transparent_ = false;
283 ++draw_op_count_;
274 } 284 }
275 285
276 // Needed for now, since SkCanvas requires a bitmap, even if it is not backed 286 // Needed for now, since SkCanvas requires a bitmap, even if it is not backed
277 // by any pixels 287 // by any pixels
278 static SkBitmap MakeEmptyBitmap(int width, int height) { 288 static SkBitmap MakeEmptyBitmap(int width, int height) {
279 SkBitmap bitmap; 289 SkBitmap bitmap;
280 bitmap.setInfo(SkImageInfo::MakeUnknown(width, height)); 290 bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
281 return bitmap; 291 return bitmap;
282 } 292 }
283 293
284 AnalysisCanvas::AnalysisCanvas(int width, int height) 294 AnalysisCanvas::AnalysisCanvas(int width, int height)
285 : INHERITED(MakeEmptyBitmap(width, height)), 295 : INHERITED(MakeEmptyBitmap(width, height)),
286 saved_stack_size_(0), 296 saved_stack_size_(0),
287 force_not_solid_stack_level_(kNoLayer), 297 force_not_solid_stack_level_(kNoLayer),
288 force_not_transparent_stack_level_(kNoLayer), 298 force_not_transparent_stack_level_(kNoLayer),
289 is_forced_not_solid_(false), 299 is_forced_not_solid_(false),
290 is_forced_not_transparent_(false), 300 is_forced_not_transparent_(false),
291 is_solid_color_(true), 301 is_solid_color_(true),
292 is_transparent_(true), 302 is_transparent_(true),
293 has_text_(false) {} 303 draw_op_count_(0) {}
294 304
295 AnalysisCanvas::~AnalysisCanvas() {} 305 AnalysisCanvas::~AnalysisCanvas() {}
296 306
297 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { 307 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const {
298 if (is_transparent_) { 308 if (is_transparent_) {
299 *color = SK_ColorTRANSPARENT; 309 *color = SK_ColorTRANSPARENT;
300 return true; 310 return true;
301 } 311 }
302 if (is_solid_color_) { 312 if (is_solid_color_) {
303 *color = color_; 313 *color = color_;
304 return true; 314 return true;
305 } 315 }
306 return false; 316 return false;
307 } 317 }
308 318
309 bool AnalysisCanvas::HasText() const { return has_text_; }
310
311 bool AnalysisCanvas::abortDrawing() { 319 bool AnalysisCanvas::abortDrawing() {
312 // Early out as soon as we have detected that the tile has text. 320 // Early out as soon as we have more than one draw op.
313 return HasText(); 321 return draw_op_count_ > 1;
enne (OOO) 2014/07/24 19:15:03 I think you could be less conservative than 1, but
vmpstr 2014/07/24 19:23:13 I think we should leave it at 1 for now, and then
314 } 322 }
315 323
316 void AnalysisCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, 324 void AnalysisCanvas::onClipRect(const SkRect& rect, SkRegion::Op op,
317 ClipEdgeStyle edge_style) { 325 ClipEdgeStyle edge_style) {
318 326
319 INHERITED::onClipRect(rect, op, edge_style); 327 INHERITED::onClipRect(rect, op, edge_style);
320 } 328 }
321 329
322 void AnalysisCanvas::onClipPath(const SkPath& path, SkRegion::Op op, 330 void AnalysisCanvas::onClipPath(const SkPath& path, SkRegion::Op op,
323 ClipEdgeStyle edge_style) { 331 ClipEdgeStyle edge_style) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 force_not_transparent_stack_level_ = kNoLayer; 421 force_not_transparent_stack_level_ = kNoLayer;
414 } 422 }
415 } 423 }
416 424
417 INHERITED::willRestore(); 425 INHERITED::willRestore();
418 } 426 }
419 427
420 } // namespace skia 428 } // namespace skia
421 429
422 430
OLDNEW
« no previous file with comments | « skia/ext/analysis_canvas.h ('k') | skia/ext/analysis_canvas_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698