| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) { |
| 140 bool does_cover_canvas = | 149 bool does_cover_canvas = |
| 141 IsFullQuad(draw, SkRect::MakeWH(width(), height()), rect); | 150 IsFullQuad(draw, analysis_rect_, rect); |
| 142 | 151 |
| 143 SkXfermode::Mode xfermode; | 152 SkXfermode::Mode xfermode; |
| 144 SkXfermode::AsMode(paint.getXfermode(), &xfermode); | 153 SkXfermode::AsMode(paint.getXfermode(), &xfermode); |
| 145 | 154 |
| 146 // This canvas will become transparent if the following holds: | 155 // This canvas will become transparent if the following holds: |
| 147 // - The quad is a full tile quad | 156 // - The quad is a full tile quad |
| 148 // - We're not in "forced not transparent" mode | 157 // - We're not in "forced not transparent" mode |
| 149 // - Transfer mode is clear (0 color, 0 alpha) | 158 // - Transfer mode is clear (0 color, 0 alpha) |
| 150 // | 159 // |
| 151 // If the paint alpha is not 0, or if the transfrer mode is | 160 // If the paint alpha is not 0, or if the transfrer mode is |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 const SkPaint& paint, | 271 const SkPaint& paint, |
| 263 const SkPath& path, | 272 const SkPath& path, |
| 264 const SkMatrix* matrix) { | 273 const SkMatrix* matrix) { |
| 265 is_solid_color_ = false; | 274 is_solid_color_ = false; |
| 266 is_transparent_ = false; | 275 is_transparent_ = false; |
| 267 has_text_ = true; | 276 has_text_ = true; |
| 268 } | 277 } |
| 269 #endif | 278 #endif |
| 270 | 279 |
| 271 void AnalysisDevice::drawVertices(const SkDraw& draw, | 280 void AnalysisDevice::drawVertices(const SkDraw& draw, |
| 272 SkCanvas::VertexMode, | 281 SkCanvas::VertexMode mode, |
| 273 int vertex_count, | 282 int vertex_count, |
| 274 const SkPoint verts[], | 283 const SkPoint verts[], |
| 275 const SkPoint texs[], | 284 const SkPoint texs[], |
| 276 const SkColor colors[], | 285 const SkColor colors[], |
| 277 SkXfermode* xmode, | 286 SkXfermode* xmode, |
| 278 const uint16_t indices[], | 287 const uint16_t indices[], |
| 279 int index_count, | 288 int index_count, |
| 280 const SkPaint& paint) { | 289 const SkPaint& paint) { |
| 281 is_solid_color_ = false; | 290 is_solid_color_ = false; |
| 282 is_transparent_ = false; | 291 is_transparent_ = false; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 300 AnalysisCanvas::~AnalysisCanvas() {} | 309 AnalysisCanvas::~AnalysisCanvas() {} |
| 301 | 310 |
| 302 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { | 311 bool AnalysisCanvas::GetColorIfSolid(SkColor* color) const { |
| 303 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); | 312 return (static_cast<AnalysisDevice*>(getDevice()))->GetColorIfSolid(color); |
| 304 } | 313 } |
| 305 | 314 |
| 306 bool AnalysisCanvas::HasText() const { | 315 bool AnalysisCanvas::HasText() const { |
| 307 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); | 316 return (static_cast<AnalysisDevice*>(getDevice()))->HasText(); |
| 308 } | 317 } |
| 309 | 318 |
| 310 bool AnalysisCanvas::abortDrawing() { | |
| 311 // Early out as soon as we have detected that the tile has text. | |
| 312 return HasText(); | |
| 313 } | |
| 314 | |
| 315 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { | 319 bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool do_aa) { |
| 316 return INHERITED::clipRect(rect, op, do_aa); | 320 return INHERITED::clipRect(rect, op, do_aa); |
| 317 } | 321 } |
| 318 | 322 |
| 319 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { | 323 bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool do_aa) { |
| 320 // clipPaths can make our calls to IsFullQuad invalid (ie have false | 324 // clipPaths can make our calls to IsFullQuad invalid (ie have false |
| 321 // positives). As a precaution, force the setting to be non-solid | 325 // positives). As a precaution, force the setting to be non-solid |
| 322 // and non-transparent until we pop this | 326 // and non-transparent until we pop this |
| 323 if (force_not_solid_stack_level_ == kNoLayer) { | 327 if (force_not_solid_stack_level_ == kNoLayer) { |
| 324 force_not_solid_stack_level_ = saved_stack_size_; | 328 force_not_solid_stack_level_ = saved_stack_size_; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 } | 360 } |
| 357 | 361 |
| 358 int AnalysisCanvas::saveLayer(const SkRect* bounds, | 362 int AnalysisCanvas::saveLayer(const SkRect* bounds, |
| 359 const SkPaint* paint, | 363 const SkPaint* paint, |
| 360 SkCanvas::SaveFlags flags) { | 364 SkCanvas::SaveFlags flags) { |
| 361 ++saved_stack_size_; | 365 ++saved_stack_size_; |
| 362 | 366 |
| 363 // If after we draw to the saved layer, we have to blend with the current | 367 // If after we draw to the saved layer, we have to blend with the current |
| 364 // layer, then we can conservatively say that the canvas will not be of | 368 // layer, then we can conservatively say that the canvas will not be of |
| 365 // solid color. | 369 // solid color. |
| 370 SkRect analysis_rect = |
| 371 static_cast<AnalysisDevice*>(getDevice())->AnalysisRect(); |
| 366 if ((paint && !IsSolidColorPaint(*paint)) || | 372 if ((paint && !IsSolidColorPaint(*paint)) || |
| 367 (bounds && !bounds->contains(SkRect::MakeWH(getDevice()->width(), | 373 (bounds && !bounds->contains(analysis_rect))) { |
| 368 getDevice()->height())))) { | |
| 369 if (force_not_solid_stack_level_ == kNoLayer) { | 374 if (force_not_solid_stack_level_ == kNoLayer) { |
| 370 force_not_solid_stack_level_ = saved_stack_size_; | 375 force_not_solid_stack_level_ = saved_stack_size_; |
| 371 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); | 376 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotSolid(true); |
| 372 } | 377 } |
| 373 } | 378 } |
| 374 | 379 |
| 375 // If after we draw to the save layer, we have to blend with the current | 380 // If after we draw to the save layer, we have to blend with the current |
| 376 // layer using any part of the current layer's alpha, then we can | 381 // layer using any part of the current layer's alpha, then we can |
| 377 // conservatively say that the canvas will not be transparent. | 382 // conservatively say that the canvas will not be transparent. |
| 378 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; | 383 SkXfermode::Mode xfermode = SkXfermode::kSrc_Mode; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 408 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( | 413 (static_cast<AnalysisDevice*>(getDevice()))->SetForceNotTransparent( |
| 409 false); | 414 false); |
| 410 force_not_transparent_stack_level_ = kNoLayer; | 415 force_not_transparent_stack_level_ = kNoLayer; |
| 411 } | 416 } |
| 412 } | 417 } |
| 413 } | 418 } |
| 414 | 419 |
| 415 } // namespace skia | 420 } // namespace skia |
| 416 | 421 |
| 417 | 422 |
| OLD | NEW |