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

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

Issue 12388095: cc: Merge GatherPixelRefs and AnalyzeInRect (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: junov's review Created 7 years, 9 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
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 "skia/ext/analysis_canvas.h" 6 #include "skia/ext/analysis_canvas.h"
7 #include "third_party/skia/include/core/SkDevice.h" 7 #include "third_party/skia/include/core/SkDevice.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/src/core/SkRasterClip.h" 11 #include "third_party/skia/src/core/SkRasterClip.h"
11 #include "ui/gfx/rect_conversions.h" 12 #include "ui/gfx/rect_conversions.h"
12 13
13 namespace { 14 namespace {
14 15
15 // FIXME: Arbitrary number. Requires tuning & experimentation. 16 // FIXME: Arbitrary number. Requires tuning & experimentation.
16 // Probably requires per-platform tuning; N10 average draw call takes 17 // Probably requires per-platform tuning; N10 average draw call takes
17 // 25x as long as Z620. 18 // 25x as long as Z620.
18 const int gPictureCostThreshold = 1000; 19 const int gPictureCostThreshold = 1000;
19 20
21 // URI label for a lazily decoded SkPixelRef.
22 const char labelLazyDecoded[] = "lazy";
Sami 2013/03/18 12:14:33 const char kLabelLazyDecoded[] = ...
23
20 static bool isSolidColorPaint(const SkPaint& paint) { 24 static bool isSolidColorPaint(const SkPaint& paint) {
21 SkXfermode::Mode xferMode; 25 SkXfermode::Mode xferMode;
22 26
23 // getXfermode can return a NULL, but that is handled 27 // getXfermode can return a NULL, but that is handled
24 // gracefully by AsMode (NULL turns into kSrcOver mode). 28 // gracefully by AsMode (NULL turns into kSrcOver mode).
25 SkXfermode::AsMode(paint.getXfermode(), &xferMode); 29 SkXfermode::AsMode(paint.getXfermode(), &xferMode);
26 30
27 // Paint is solid color if the following holds: 31 // Paint is solid color if the following holds:
28 // - Alpha is 1.0, style is fill, and there are no special effects 32 // - Alpha is 1.0, style is fill, and there are no special effects
29 // - Xfer mode is either kSrc or kSrcOver (kSrcOver is equivalent 33 // - Xfer mode is either kSrc or kSrcOver (kSrcOver is equivalent
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 if (isForcedNotSolid_) 108 if (isForcedNotSolid_)
105 isSolidColor_ = false; 109 isSolidColor_ = false;
106 } 110 }
107 111
108 void AnalysisDevice::setForceNotTransparent(bool flag) { 112 void AnalysisDevice::setForceNotTransparent(bool flag) {
109 isForcedNotTransparent_ = flag; 113 isForcedNotTransparent_ = flag;
110 if (isForcedNotTransparent_) 114 if (isForcedNotTransparent_)
111 isTransparent_ = false; 115 isTransparent_ = false;
112 } 116 }
113 117
118 void AnalysisDevice::addPixelRefIfLazy(SkPixelRef* pixelRef) {
119 if (!pixelRef)
120 return;
121
122 uint32_t genID = pixelRef->getGenerationID();
123
124 // If this ID exists (whether it is lazy pixel ref or not),
125 // we can return early.
126 std::pair<base::hash_set<uint32_t>::iterator, bool> insertionResult =
127 existingPixelRefIDs_.insert(genID);
128 if (!insertionResult.second)
129 return;
130
131 if (pixelRef->getURI() &&
132 !strncmp(pixelRef->getURI(), labelLazyDecoded, 4)) {
Sami 2013/03/18 12:14:33 Use a named constant instead of 4.
133 lazyPixelRefs_.push_back(static_cast<skia::LazyPixelRef*>(pixelRef));
134 }
135 }
136
137 void AnalysisDevice::addBitmap(const SkBitmap& bitmap) {
138 addPixelRefIfLazy(bitmap.pixelRef());
139 }
140
141 void AnalysisDevice::addBitmapFromPaint(const SkPaint& paint) {
142 SkShader* shader = paint.getShader();
143 if (shader) {
144 SkBitmap bitmap;
145 // Check whether the shader is a gradient in order to short-circuit
146 // call to asABitmap to prevent generation of bitmaps from
147 // gradient shaders, which implement asABitmap.
148 if (SkShader::kNone_GradientType == shader->asAGradient(NULL) &&
149 SkShader::kNone_BitmapType != shader->asABitmap(&bitmap, NULL, NULL)) {
150 addPixelRefIfLazy(bitmap.pixelRef());
151 }
152 }
153 }
154
155 void AnalysisDevice::consumeLazyPixelRefs(std::list<LazyPixelRef*>& pixelRefs) {
156 DCHECK(pixelRefs.empty());
157 lazyPixelRefs_.swap(pixelRefs);
158 existingPixelRefIDs_.clear();
159 }
160
114 void AnalysisDevice::clear(SkColor color) { 161 void AnalysisDevice::clear(SkColor color) {
115 ++estimatedCost_; 162 ++estimatedCost_;
116 163
117 isTransparent_ = (!isForcedNotTransparent_ && SkColorGetA(color) == 0); 164 isTransparent_ = (!isForcedNotTransparent_ && SkColorGetA(color) == 0);
118 165
119 if (!isForcedNotSolid_ && SkColorGetA(color) == 255) { 166 if (!isForcedNotSolid_ && SkColorGetA(color) == 255) {
120 isSolidColor_ = true; 167 isSolidColor_ = true;
121 color_ = color; 168 color_ = color;
122 } 169 }
123 else { 170 else {
124 isSolidColor_ = false; 171 isSolidColor_ = false;
125 } 172 }
126 } 173 }
127 174
128 void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) { 175 void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) {
129 ++estimatedCost_; 176 ++estimatedCost_;
130 isSolidColor_ = false; 177 isSolidColor_ = false;
131 isTransparent_ = false; 178 isTransparent_ = false;
179 addBitmapFromPaint(paint);
Tom Hudson 2013/03/18 11:52:39 Hmm, idiomatically this isn't how I expected drawP
132 } 180 }
133 181
134 void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode, 182 void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode,
135 size_t count, const SkPoint[], 183 size_t count, const SkPoint[],
136 const SkPaint& paint) { 184 const SkPaint& paint) {
137 ++estimatedCost_; 185 ++estimatedCost_;
138 isSolidColor_ = false; 186 isSolidColor_ = false;
139 isTransparent_ = false; 187 isTransparent_ = false;
188 addBitmapFromPaint(paint);
140 } 189 }
141 190
142 void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect, 191 void AnalysisDevice::drawRect(const SkDraw& draw, const SkRect& rect,
143 const SkPaint& paint) { 192 const SkPaint& paint) {
144 193
145 // FIXME: if there's a pending image decode & resize, more expensive 194 // FIXME: if there's a pending image decode & resize, more expensive
146 if (paint.getMaskFilter()) { 195 if (paint.getMaskFilter()) {
147 estimatedCost_ += 300; 196 estimatedCost_ += 300;
148 } 197 }
149 ++estimatedCost_; 198 ++estimatedCost_;
150 199 addBitmapFromPaint(paint);
151 bool doesCoverCanvas = isFullQuad(draw, 200 bool doesCoverCanvas = isFullQuad(draw,
152 SkRect::MakeWH(width(), height()), 201 SkRect::MakeWH(width(), height()),
153 rect); 202 rect);
154 203
155 SkXfermode::Mode xferMode; 204 SkXfermode::Mode xferMode;
156 SkXfermode::AsMode(paint.getXfermode(), &xferMode); 205 SkXfermode::AsMode(paint.getXfermode(), &xferMode);
157 206
158 // This canvas will become transparent if the following holds: 207 // This canvas will become transparent if the following holds:
159 // - The quad is a full tile quad 208 // - The quad is a full tile quad
160 // - We're not in "forced not transparent" mode 209 // - We're not in "forced not transparent" mode
(...skipping 27 matching lines...) Expand all
188 else { 237 else {
189 isSolidColor_ = false; 238 isSolidColor_ = false;
190 } 239 }
191 } 240 }
192 241
193 void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval, 242 void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval,
194 const SkPaint& paint) { 243 const SkPaint& paint) {
195 ++estimatedCost_; 244 ++estimatedCost_;
196 isSolidColor_ = false; 245 isSolidColor_ = false;
197 isTransparent_ = false; 246 isTransparent_ = false;
247 addBitmapFromPaint(paint);
198 } 248 }
199 249
200 void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path, 250 void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path,
201 const SkPaint& paint, 251 const SkPaint& paint,
202 const SkMatrix* prePathMatrix , 252 const SkMatrix* prePathMatrix ,
203 bool pathIsMutable ) { 253 bool pathIsMutable ) {
204 // On Z620, every antialiased path costs us about 300us. 254 // On Z620, every antialiased path costs us about 300us.
205 // We've only seen this in practice on filled paths, but 255 // We've only seen this in practice on filled paths, but
206 // we expect it to apply to all path stroking modes. 256 // we expect it to apply to all path stroking modes.
207 if (paint.getMaskFilter()) { 257 if (paint.getMaskFilter()) {
208 estimatedCost_ += 300; 258 estimatedCost_ += 300;
209 } 259 }
210 ++estimatedCost_; 260 ++estimatedCost_;
211 isSolidColor_ = false; 261 isSolidColor_ = false;
212 isTransparent_ = false; 262 isTransparent_ = false;
263 addBitmapFromPaint(paint);
213 } 264 }
214 265
215 void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap, 266 void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap,
216 const SkIRect* srcRectOrNull, 267 const SkIRect* srcRectOrNull,
217 const SkMatrix& matrix, const SkPaint& paint) { 268 const SkMatrix& matrix, const SkPaint& paint) {
218 ++estimatedCost_; 269 ++estimatedCost_;
219 isSolidColor_ = false; 270 isSolidColor_ = false;
220 isTransparent_ = false; 271 isTransparent_ = false;
272 addBitmap(bitmap);
221 } 273 }
222 274
223 void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap, 275 void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
224 int x, int y, const SkPaint& paint) { 276 int x, int y, const SkPaint& paint) {
225 ++estimatedCost_; 277 ++estimatedCost_;
226 isSolidColor_ = false; 278 isSolidColor_ = false;
227 isTransparent_ = false; 279 isTransparent_ = false;
280 addBitmap(bitmap);
228 } 281 }
229 282
230 void AnalysisDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap&, 283 void AnalysisDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
231 const SkRect* srcOrNull, const SkRect& dst, 284 const SkRect* srcOrNull, const SkRect& dst,
232 const SkPaint& paint) { 285 const SkPaint& paint) {
233 ++estimatedCost_; 286 ++estimatedCost_;
234 287
235 // Call drawRect to determine transparency, 288 // Call drawRect to determine transparency,
236 // but reset solid color to false. 289 // but reset solid color to false.
237 drawRect(draw, dst, paint); 290 drawRect(draw, dst, paint);
238 isSolidColor_ = false; 291 isSolidColor_ = false;
292 addBitmap(bitmap);
239 } 293 }
240 294
241 295
242 void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len, 296 void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len,
243 SkScalar x, SkScalar y, const SkPaint& paint) { 297 SkScalar x, SkScalar y, const SkPaint& paint) {
244 ++estimatedCost_; 298 ++estimatedCost_;
245 isSolidColor_ = false; 299 isSolidColor_ = false;
246 isTransparent_ = false; 300 isTransparent_ = false;
301 addBitmapFromPaint(paint);
247 } 302 }
248 303
249 void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t le n, 304 void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t le n,
250 const SkScalar pos[], SkScalar constY, 305 const SkScalar pos[], SkScalar constY,
251 int scalarsPerPos, const SkPaint& paint) { 306 int scalarsPerPos, const SkPaint& paint) {
252 // FIXME: On Z620, every glyph cache miss costs us about 10us. 307 // FIXME: On Z620, every glyph cache miss costs us about 10us.
253 // We don't have a good mechanism for predicting glyph cache misses. 308 // We don't have a good mechanism for predicting glyph cache misses.
254 ++estimatedCost_; 309 ++estimatedCost_;
255 isSolidColor_ = false; 310 isSolidColor_ = false;
256 isTransparent_ = false; 311 isTransparent_ = false;
312 addBitmapFromPaint(paint);
257 } 313 }
258 314
259 void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, 315 void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len,
260 const SkPath& path, const SkMatrix* matrix, 316 const SkPath& path, const SkMatrix* matrix,
261 const SkPaint& paint) { 317 const SkPaint& paint) {
262 ++estimatedCost_; 318 ++estimatedCost_;
263 isSolidColor_ = false; 319 isSolidColor_ = false;
264 isTransparent_ = false; 320 isTransparent_ = false;
321 addBitmapFromPaint(paint);
265 } 322 }
266 323
267 #ifdef SK_BUILD_FOR_ANDROID 324 #ifdef SK_BUILD_FOR_ANDROID
268 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, 325 void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text,
269 size_t len, 326 size_t len,
270 const SkPoint pos[], const SkPaint& paint, 327 const SkPoint pos[], const SkPaint& paint,
271 const SkPath& path, const SkMatrix* matrix) { 328 const SkPath& path, const SkMatrix* matrix) {
272 ++estimatedCost_; 329 ++estimatedCost_;
273 isSolidColor_ = false; 330 isSolidColor_ = false;
274 isTransparent_ = false; 331 isTransparent_ = false;
332 addBitmapFromPaint(paint);
275 } 333 }
276 #endif 334 #endif
277 335
278 void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, 336 void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
279 int vertexCount, 337 int vertexCount,
280 const SkPoint verts[], const SkPoint texs[], 338 const SkPoint verts[], const SkPoint texs[],
281 const SkColor colors[], SkXfermode* xmode, 339 const SkColor colors[], SkXfermode* xmode,
282 const uint16_t indices[], int indexCount, 340 const uint16_t indices[], int indexCount,
283 const SkPaint& paint) { 341 const SkPaint& paint) {
284 ++estimatedCost_; 342 ++estimatedCost_;
285 isSolidColor_ = false; 343 isSolidColor_ = false;
286 isTransparent_ = false; 344 isTransparent_ = false;
345 addBitmapFromPaint(paint);
287 } 346 }
288 347
289 void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y, 348 void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y,
290 const SkPaint&) { 349 const SkPaint&) {
291 ++estimatedCost_; 350 ++estimatedCost_;
292 isSolidColor_ = false; 351 isSolidColor_ = false;
293 isTransparent_ = false; 352 isTransparent_ = false;
294 } 353 }
295 354
296 355
(...skipping 19 matching lines...) Expand all
316 } 375 }
317 376
318 bool AnalysisCanvas::isTransparent() const { 377 bool AnalysisCanvas::isTransparent() const {
319 return (static_cast<AnalysisDevice*>(getDevice()))->isTransparent(); 378 return (static_cast<AnalysisDevice*>(getDevice()))->isTransparent();
320 } 379 }
321 380
322 int AnalysisCanvas::getEstimatedCost() const { 381 int AnalysisCanvas::getEstimatedCost() const {
323 return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost(); 382 return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost();
324 } 383 }
325 384
385 void AnalysisCanvas::consumeLazyPixelRefs(std::list<LazyPixelRef*>& pixelRefs) {
386 static_cast<AnalysisDevice*>(getDevice())->consumeLazyPixelRefs(pixelRefs);
387 }
388
326 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, 389 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op,
327 bool doAA) { 390 bool doAA) {
328 return INHERITED::clipRect(rect, op, doAA); 391 return INHERITED::clipRect(rect, op, doAA);
329 } 392 }
330 393
331 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, 394 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op,
332 bool doAA) { 395 bool doAA) {
333 // clipPaths can make our calls to isFullQuad invalid (ie have false 396 // clipPaths can make our calls to isFullQuad invalid (ie have false
334 // positives). As a precaution, force the setting to be non-solid 397 // positives). As a precaution, force the setting to be non-solid
335 // and non-transparent until we pop this 398 // and non-transparent until we pop this
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 if (savedStackSize_ < forceNotTransparentStackLevel_) { 481 if (savedStackSize_ < forceNotTransparentStackLevel_) {
419 (static_cast<AnalysisDevice*>(getDevice()))->setForceNotTransparent(false) ; 482 (static_cast<AnalysisDevice*>(getDevice()))->setForceNotTransparent(false) ;
420 forceNotTransparentStackLevel_ = kNoLayer; 483 forceNotTransparentStackLevel_ = kNoLayer;
421 } 484 }
422 } 485 }
423 } 486 }
424 487
425 } // namespace skia 488 } // namespace skia
426 489
427 490
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698