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