OLD | NEW |
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/SkDevice.h" | 8 #include "third_party/skia/include/core/SkDevice.h" |
9 #include "third_party/skia/include/core/SkDraw.h" | 9 #include "third_party/skia/include/core/SkDraw.h" |
10 #include "third_party/skia/include/core/SkRRect.h" | 10 #include "third_party/skia/include/core/SkRRect.h" |
11 #include "third_party/skia/include/core/SkShader.h" | 11 #include "third_party/skia/include/core/SkShader.h" |
12 #include "third_party/skia/src/core/SkRasterClip.h" | 12 #include "third_party/skia/src/core/SkRasterClip.h" |
13 #include "ui/gfx/rect_conversions.h" | |
14 | 13 |
15 namespace { | 14 namespace { |
16 | 15 |
17 const int kNoLayer = -1; | 16 const int kNoLayer = -1; |
18 | 17 |
19 bool IsSolidColorPaint(const SkPaint& paint) { | 18 bool IsSolidColorPaint(const SkPaint& paint) { |
20 SkXfermode::Mode xfermode; | 19 SkXfermode::Mode xfermode; |
21 | 20 |
22 // getXfermode can return a NULL, but that is handled | 21 // getXfermode can return a NULL, but that is handled |
23 // gracefully by AsMode (NULL turns into kSrcOver mode). | 22 // gracefully by AsMode (NULL turns into kSrcOver mode). |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 return draw.fRC->isRect() && | 62 return draw.fRC->isRect() && |
64 device_rect.contains(clip_rect) && | 63 device_rect.contains(clip_rect) && |
65 clip_rect.contains(canvas_rect) && | 64 clip_rect.contains(canvas_rect) && |
66 draw_bitmap_rect.contains(canvas_rect); | 65 draw_bitmap_rect.contains(canvas_rect); |
67 } | 66 } |
68 | 67 |
69 } // namespace | 68 } // namespace |
70 | 69 |
71 namespace skia { | 70 namespace skia { |
72 | 71 |
73 AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap) | 72 AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap, SkRect analysis_rect) |
74 : INHERITED(bitmap), | 73 : INHERITED(bitmap), |
| 74 analysis_rect_(analysis_rect), |
75 is_forced_not_solid_(false), | 75 is_forced_not_solid_(false), |
76 is_forced_not_transparent_(false), | 76 is_forced_not_transparent_(false), |
77 is_solid_color_(true), | 77 is_solid_color_(true), |
| 78 is_transparent_(true), |
| 79 has_text_(false) {} |
| 80 |
| 81 AnalysisDevice::AnalysisDevice(const SkBitmap& bitmap) |
| 82 : INHERITED(bitmap), |
| 83 analysis_rect_(SkRect::MakeWH(bitmap.width(), bitmap.height())), |
| 84 is_forced_not_solid_(false), |
| 85 is_forced_not_transparent_(false), |
| 86 is_solid_color_(true), |
78 is_transparent_(true), | 87 is_transparent_(true), |
79 has_text_(false) {} | 88 has_text_(false) {} |
80 | 89 |
81 AnalysisDevice::~AnalysisDevice() {} | 90 AnalysisDevice::~AnalysisDevice() {} |
82 | 91 |
83 bool AnalysisDevice::GetColorIfSolid(SkColor* color) const { | 92 bool AnalysisDevice::GetColorIfSolid(SkColor* color) const { |
84 if (is_transparent_) { | 93 if (is_transparent_) { |
85 *color = SK_ColorTRANSPARENT; | 94 *color = SK_ColorTRANSPARENT; |
86 return true; | 95 return true; |
87 } | 96 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 size_t count, | 139 size_t count, |
131 const SkPoint points[], | 140 const SkPoint points[], |
132 const SkPaint& paint) { | 141 const SkPaint& paint) { |
133 is_solid_color_ = false; | 142 is_solid_color_ = false; |
134 is_transparent_ = false; | 143 is_transparent_ = false; |
135 } | 144 } |
136 | 145 |
137 void AnalysisDevice::drawRect(const SkDraw& draw, | 146 void AnalysisDevice::drawRect(const SkDraw& draw, |
138 const SkRect& rect, | 147 const SkRect& rect, |
139 const SkPaint& paint) { | 148 const SkPaint& paint) { |
| 149 // Early out of work where possible. It could be the case that a picture |
| 150 // draws text and then clears, but this is unlikely. |
| 151 if (has_text_ && !is_solid_color_) |
| 152 return; |
| 153 |
140 bool does_cover_canvas = | 154 bool does_cover_canvas = |
141 IsFullQuad(draw, SkRect::MakeWH(width(), height()), rect); | 155 IsFullQuad(draw, analysis_rect_, rect); |
142 | 156 |
143 SkXfermode::Mode xfermode; | 157 SkXfermode::Mode xfermode; |
144 SkXfermode::AsMode(paint.getXfermode(), &xfermode); | 158 SkXfermode::AsMode(paint.getXfermode(), &xfermode); |
145 | 159 |
146 // This canvas will become transparent if the following holds: | 160 // This canvas will become transparent if the following holds: |
147 // - The quad is a full tile quad | 161 // - The quad is a full tile quad |
148 // - We're not in "forced not transparent" mode | 162 // - We're not in "forced not transparent" mode |
149 // - Transfer mode is clear (0 color, 0 alpha) | 163 // - Transfer mode is clear (0 color, 0 alpha) |
150 // | 164 // |
151 // If the paint alpha is not 0, or if the transfrer mode is | 165 // If the paint alpha is not 0, or if the transfrer mode is |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 const SkPaint& paint, | 286 const SkPaint& paint, |
273 const SkPath& path, | 287 const SkPath& path, |
274 const SkMatrix* matrix) { | 288 const SkMatrix* matrix) { |
275 is_solid_color_ = false; | 289 is_solid_color_ = false; |
276 is_transparent_ = false; | 290 is_transparent_ = false; |
277 has_text_ = true; | 291 has_text_ = true; |
278 } | 292 } |
279 #endif | 293 #endif |
280 | 294 |
281 void AnalysisDevice::drawVertices(const SkDraw& draw, | 295 void AnalysisDevice::drawVertices(const SkDraw& draw, |
282 SkCanvas::VertexMode, | 296 SkCanvas::VertexMode mode, |
283 int vertex_count, | 297 int vertex_count, |
284 const SkPoint verts[], | 298 const SkPoint verts[], |
285 const SkPoint texs[], | 299 const SkPoint texs[], |
286 const SkColor colors[], | 300 const SkColor colors[], |
287 SkXfermode* xmode, | 301 SkXfermode* xmode, |
288 const uint16_t indices[], | 302 const uint16_t indices[], |
289 int index_count, | 303 int index_count, |
290 const SkPaint& paint) { | 304 const SkPaint& paint) { |
291 is_solid_color_ = false; | 305 is_solid_color_ = false; |
292 is_transparent_ = false; | 306 is_transparent_ = false; |
(...skipping 17 matching lines...) Expand all Loading... |
310 AnalysisCanvas::~AnalysisCanvas() {} | 324 AnalysisCanvas::~AnalysisCanvas() {} |
311 | 325 |
312 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { | 326 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { |
313 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); | 327 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); |
314 } | 328 } |
315 | 329 |
316 bool AnalysisCanvas::HasText() const { | 330 bool AnalysisCanvas::HasText() const { |
317 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); | 331 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); |
318 } | 332 } |
319 | 333 |
320 bool AnalysisCanvas::abortDrawing() { | |
321 // Early out as soon as we have detected that the tile has text. | |
322 return HasText(); | |
323 } | |
324 | |
325 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { | 334 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { |
326 return INHERITED::clipRect(rect, op, do_aa); | 335 return INHERITED::clipRect(rect, op, do_aa); |
327 } | 336 } |
328 | 337 |
329 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { | 338 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { |
330 // clipPaths can make our calls to IsFullQuad invalid (ie have false | 339 // clipPaths can make our calls to IsFullQuad invalid (ie have false |
331 // positives). As a precaution, force the setting to be non-solid | 340 // positives). As a precaution, force the setting to be non-solid |
332 // and non-transparent until we pop this | 341 // and non-transparent until we pop this |
333 if (force_not_solid_stack_level_ == kNoLayer) { | 342 if (force_not_solid_stack_level_ == kNoLayer) { |
334 force_not_solid_stack_level_ = saved_stack_size_; | 343 force_not_solid_stack_level_ = saved_stack_size_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 } | 375 } |
367 | 376 |
368 int AnalysisCanvas::saveLayer(const SkRect* bounds, | 377 int AnalysisCanvas::saveLayer(const SkRect* bounds, |
369 const SkPaint* paint, | 378 const SkPaint* paint, |
370 SkCanvas::SaveFlags flags) { | 379 SkCanvas::SaveFlags flags) { |
371 ++saved_stack_size_; | 380 ++saved_stack_size_; |
372 | 381 |
373 // If after we draw to the saved layer, we have to blend with the current | 382 // If after we draw to the saved layer, we have to blend with the current |
374 // layer, then we can conservatively say that the canvas will not be of | 383 // layer, then we can conservatively say that the canvas will not be of |
375 // solid color. | 384 // solid color. |
| 385 SkRect analysis_rect = |
| 386 static_cast<AnalysisDevice*>(getDevice())->AnalysisRect(); |
376 if ((paint && !IsSolidColorPaint(*paint)) || | 387 if ((paint && !IsSolidColorPaint(*paint)) || |
377 (bounds && !bounds->contains(SkRect::MakeWH(getDevice()->width(), | 388 (bounds && !bounds->contains(analysis_rect))) { |
378 getDevice()->height())))) { | |
379 if (force_not_solid_stack_level_ == kNoLayer) { | 389 if (force_not_solid_stack_level_ == kNoLayer) { |
380 force_not_solid_stack_level_ = saved_stack_size_; | 390 force_not_solid_stack_level_ = saved_stack_size_; |
381 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); | 391 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); |
382 } | 392 } |
383 } | 393 } |
384 | 394 |
385 // If after we draw to the save layer, we have to blend with the current | 395 // If after we draw to the save layer, we have to blend with the current |
386 // layer using any part of the current layer's alpha, then we can | 396 // layer using any part of the current layer's alpha, then we can |
387 // conservatively say that the canvas will not be transparent. | 397 // conservatively say that the canvas will not be transparent. |
388 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; | 398 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; |
(...skipping 29 matching lines...) Expand all Loading... |
418 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( | 428 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( |
419 false); | 429 false); |
420 force_not_transparent_stack_level_ = kNoLayer; | 430 force_not_transparent_stack_level_ = kNoLayer; |
421 } | 431 } |
422 } | 432 } |
423 } | 433 } |
424 | 434 |
425 } // namespace skia | 435 } // namespace skia |
426 | 436 |
427 | 437 |
OLD | NEW |