Chromium Code Reviews| Index: cc/playback/discardable_image_map.cc |
| diff --git a/cc/playback/discardable_image_map.cc b/cc/playback/discardable_image_map.cc |
| index e109e2be37599fbda7dd7a48553e2a8cb0ebab4b..f3c38c830adfc0b92f334f33d7e3e89adad3a645 100644 |
| --- a/cc/playback/discardable_image_map.cc |
| +++ b/cc/playback/discardable_image_map.cc |
| @@ -7,6 +7,7 @@ |
| #include <algorithm> |
| #include <limits> |
| +#include "base/containers/adapters.h" |
| #include "cc/base/math_util.h" |
| #include "cc/playback/display_item_list.h" |
| #include "third_party/skia/include/utils/SkNWayCanvas.h" |
| @@ -15,23 +16,47 @@ |
| namespace cc { |
| -namespace { |
| - |
| SkRect MapRect(const SkMatrix& matrix, const SkRect& src) { |
| SkRect dst; |
| matrix.mapRect(&dst, src); |
| return dst; |
| } |
| -SkSize ExtractScale(const SkMatrix& matrix) { |
| - SkSize scale = SkSize::Make(matrix.getScaleX(), matrix.getScaleY()); |
| +bool ExtractScale(const SkMatrix& matrix, SkSize* scale) { |
| + *scale = SkSize::Make(matrix.getScaleX(), matrix.getScaleY()); |
| if (matrix.getType() & SkMatrix::kAffine_Mask) { |
| - if (!matrix.decomposeScale(&scale)) |
| - scale.set(1, 1); |
| + if (!matrix.decomposeScale(scale)) { |
| + scale->set(1, 1); |
| + return false; |
| + } |
| } |
| - return scale; |
| + return true; |
| } |
| +bool ComputeRectBoundsFromPaint(const SkRect& rect, |
| + const SkPaint* current_paint, |
| + const std::vector<const SkPaint*>& saved_paints, |
| + SkRect* paint_bounds) { |
| + *paint_bounds = rect; |
| + if (current_paint) { |
| + if (!current_paint->canComputeFastBounds()) |
| + return false; |
| + *paint_bounds = |
| + current_paint->computeFastBounds(*paint_bounds, paint_bounds); |
| + } |
| + |
| + for (const auto* paint : base::Reversed(saved_paints)) { |
| + if (!paint) |
| + continue; |
| + if (!paint->canComputeFastBounds()) |
| + return false; |
| + *paint_bounds = paint->computeFastBounds(*paint_bounds, paint_bounds); |
| + } |
| + return true; |
| +} |
| + |
| +namespace { |
| + |
| // We're using an NWay canvas with no added canvases, so in effect |
| // non-overridden functions are no-ops. |
| class DiscardableImagesMetadataCanvas : public SkNWayCanvas { |
| @@ -57,10 +82,11 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { |
| SkScalar x, |
| SkScalar y, |
| const SkPaint* paint) override { |
| - const SkMatrix& ctm = this->getTotalMatrix(); |
| - AddImage(image, MapRect(ctm, SkRect::MakeXYWH(x, y, image->width(), |
| - image->height())), |
| - ctm, paint); |
| + const SkMatrix& ctm = getTotalMatrix(); |
| + AddImage( |
| + image, SkRect::MakeIWH(image->width(), image->height()), |
| + MapRect(ctm, SkRect::MakeXYWH(x, y, image->width(), image->height())), |
| + ctm, paint); |
| } |
| void onDrawImageRect(const SkImage* image, |
| @@ -68,7 +94,7 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { |
| const SkRect& dst, |
| const SkPaint* paint, |
| SrcRectConstraint) override { |
| - const SkMatrix& ctm = this->getTotalMatrix(); |
| + const SkMatrix& ctm = getTotalMatrix(); |
| SkRect src_storage; |
| if (!src) { |
| src_storage = SkRect::MakeIWH(image->width(), image->height()); |
| @@ -77,34 +103,78 @@ class DiscardableImagesMetadataCanvas : public SkNWayCanvas { |
| SkMatrix matrix; |
| matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit); |
| matrix.postConcat(ctm); |
| - AddImage(image, MapRect(ctm, dst), matrix, paint); |
| + AddImage(image, *src, MapRect(ctm, dst), matrix, paint); |
| } |
| void onDrawImageNine(const SkImage* image, |
| const SkIRect& center, |
| const SkRect& dst, |
| const SkPaint* paint) override { |
| - AddImage(image, dst, this->getTotalMatrix(), paint); |
| + // Blink doesn't issue image nine calls. |
|
enne (OOO)
2015/12/10 00:07:16
Blink doesn't issue => no cc embedder issues
...h
vmpstr
2015/12/10 00:47:03
Done.
|
| + NOTREACHED(); |
| + } |
| + |
| + SaveLayerStrategy willSaveLayer(const SkRect* rect, |
| + const SkPaint* paint, |
| + SaveFlags save_flags) override { |
| + saved_paints_.push_back(paint); |
| + return SkNWayCanvas::willSaveLayer(rect, paint, save_flags); |
| + } |
| + |
| + void willSave() override { |
| + saved_paints_.push_back(nullptr); |
| + return SkNWayCanvas::willSave(); |
| + } |
| + |
| + void willRestore() override { |
| + DCHECK_GT(saved_paints_.size(), 0u); |
| + saved_paints_.pop_back(); |
| + SkNWayCanvas::willRestore(); |
| } |
| private: |
| void AddImage(const SkImage* image, |
| + const SkRect& src_rect, |
| const SkRect& rect, |
| const SkMatrix& matrix, |
| const SkPaint* paint) { |
| - if (rect.intersects(canvas_bounds_) && image->isLazyGenerated()) { |
| - SkFilterQuality filter_quality = kNone_SkFilterQuality; |
| - if (paint) { |
| - filter_quality = paint->getFilterQuality(); |
| - } |
| - image_set_->push_back( |
| - std::make_pair(DrawImage(image, ExtractScale(matrix), filter_quality), |
| - gfx::ToEnclosingRect(gfx::SkRectToRectF(rect)))); |
| + if (!image->isLazyGenerated()) |
| + return; |
| + |
| + SkRect paint_rect; |
| + bool computed_paint_bounds = ComputePaintBounds(rect, paint, &paint_rect); |
| + if (!computed_paint_bounds) { |
| + // TODO(vmpstr): UMA this case. |
| + paint_rect = canvas_bounds_; |
| } |
| + |
| + if (!paint_rect.intersects(canvas_bounds_)) |
| + return; |
| + |
| + SkFilterQuality filter_quality = kNone_SkFilterQuality; |
| + if (paint) { |
| + filter_quality = paint->getFilterQuality(); |
| + } |
| + |
| + SkIRect src_irect; |
| + src_rect.roundOut(&src_irect); |
| + SkSize scale; |
| + bool is_decomposable = ExtractScale(matrix, &scale); |
| + image_set_->push_back( |
| + std::make_pair(DrawImage(image, src_irect, scale, filter_quality, |
| + matrix.hasPerspective(), is_decomposable), |
| + gfx::ToEnclosingRect(gfx::SkRectToRectF(paint_rect)))); |
| + } |
| + |
| + bool ComputePaintBounds(const SkRect& rect, |
| + const SkPaint* paint, |
| + SkRect* paint_bounds) { |
| + return ComputeRectBoundsFromPaint(rect, paint, saved_paints_, paint_bounds); |
| } |
| std::vector<std::pair<DrawImage, gfx::Rect>>* image_set_; |
| const SkRect canvas_bounds_; |
| + std::vector<const SkPaint*> saved_paints_; |
| }; |
| } // namespace |