| Index: cc/playback/display_list_raster_source.cc
|
| diff --git a/cc/playback/display_list_raster_source.cc b/cc/playback/display_list_raster_source.cc
|
| index 215f7d75a534ce0a56ffc04eb02908fa76119642..c515b36b882b054c0b8d0fe5e835ea923a28bedc 100644
|
| --- a/cc/playback/display_list_raster_source.cc
|
| +++ b/cc/playback/display_list_raster_source.cc
|
| @@ -9,13 +9,140 @@
|
| #include "cc/debug/debug_colors.h"
|
| #include "cc/playback/display_item_list.h"
|
| #include "cc/playback/raster_source_helper.h"
|
| +#include "cc/tiles/image_decode_controller.h"
|
| #include "skia/ext/analysis_canvas.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| #include "third_party/skia/include/core/SkPictureRecorder.h"
|
| +#include "third_party/skia/include/utils/SkNWayCanvas.h"
|
| #include "ui/gfx/geometry/rect_conversions.h"
|
|
|
| namespace cc {
|
|
|
| +namespace {
|
| +
|
| +SkRect MapRect(const SkMatrix& matrix, const SkRect& src) {
|
| + SkRect dst;
|
| + matrix.mapRect(&dst, src);
|
| + return dst;
|
| +}
|
| +
|
| +class ImageHijackCanvas : public SkNWayCanvas {
|
| + public:
|
| + ImageHijackCanvas(int width,
|
| + int height,
|
| + ImageDecodeController* image_decode_controller)
|
| + : SkNWayCanvas(width, height),
|
| + image_decode_controller_(image_decode_controller),
|
| + canvas_bounds_(SkRect::MakeIWH(width, height)) {}
|
| +
|
| + protected:
|
| + // Ensure that pictures are unpacked by this canvas, instead of being
|
| + // forwarded to the raster canvas.
|
| + void onDrawPicture(const SkPicture* picture,
|
| + const SkMatrix* matrix,
|
| + const SkPaint* paint) override {
|
| + SkCanvas::onDrawPicture(picture, matrix, paint);
|
| + }
|
| +
|
| + void onDrawImage(const SkImage* image,
|
| + SkScalar x,
|
| + SkScalar y,
|
| + const SkPaint* paint) override {
|
| + SkMatrix ctm = this->getTotalMatrix();
|
| + DecodedPositionImage decoded_image = LookupImage(
|
| + image,
|
| + MapRect(ctm, SkRect::MakeXYWH(x, y, image->width(), image->height())),
|
| + ctm, paint);
|
| +
|
| + SkPaint decoded_paint;
|
| + if (paint) {
|
| + decoded_paint = *paint;
|
| + decoded_paint.setFilterQuality(decoded_image.filter_quality);
|
| + }
|
| +
|
| + SkNWayCanvas::save();
|
| + ctm.postScale(decoded_image.scale_adjustment.width(),
|
| + decoded_image.scale_adjustment.height());
|
| + SkNWayCanvas::setMatrix(ctm);
|
| + SkNWayCanvas::onDrawImage(decoded_image.image, x, y,
|
| + paint ? &decoded_paint : nullptr);
|
| + SkNWayCanvas::restore();
|
| + }
|
| +
|
| + void onDrawImageRect(const SkImage* image,
|
| + const SkRect* src,
|
| + const SkRect& dst,
|
| + const SkPaint* paint,
|
| + SrcRectConstraint constraint) override {
|
| + SkMatrix ctm = this->getTotalMatrix();
|
| + SkRect src_storage;
|
| + if (!src) {
|
| + src_storage = SkRect::MakeIWH(image->width(), image->height());
|
| + src = &src_storage;
|
| + }
|
| + SkMatrix matrix;
|
| + matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit);
|
| + matrix.postConcat(ctm);
|
| + DecodedPositionImage decoded_image =
|
| + LookupImage(image, MapRect(ctm, dst), matrix, paint);
|
| + SkPaint decoded_paint;
|
| + if (paint) {
|
| + decoded_paint = *paint;
|
| + decoded_paint.setFilterQuality(decoded_image.filter_quality);
|
| + }
|
| + float x_scale = decoded_image.scale_adjustment.width();
|
| + float y_scale = decoded_image.scale_adjustment.height();
|
| + SkRect adjusted_src =
|
| + SkRect::MakeXYWH(src->x() * x_scale, src->y() * y_scale,
|
| + src->width() * x_scale, src->height() * y_scale);
|
| + SkNWayCanvas::onDrawImageRect(decoded_image.image, &adjusted_src, dst,
|
| + paint ? &decoded_paint : nullptr, constraint);
|
| + }
|
| +
|
| + void onDrawImageNine(const SkImage* image,
|
| + const SkIRect& center,
|
| + const SkRect& dst,
|
| + const SkPaint* paint) override {
|
| + SkMatrix ctm = this->getTotalMatrix();
|
| + DecodedPositionImage decoded_image = LookupImage(image, dst, ctm, paint);
|
| + SkPaint decoded_paint;
|
| + if (paint) {
|
| + decoded_paint = *paint;
|
| + decoded_paint.setFilterQuality(decoded_image.filter_quality);
|
| + }
|
| + float x_scale = decoded_image.scale_adjustment.width();
|
| + float y_scale = decoded_image.scale_adjustment.height();
|
| + SkIRect adjusted_center = SkIRect::MakeXYWH(
|
| + static_cast<int>(std::floor(center.x() * x_scale)),
|
| + static_cast<int>(std::floor(center.y() * y_scale)),
|
| + static_cast<int>(std::ceil(center.width() * x_scale)),
|
| + static_cast<int>(std::ceil(center.height() * y_scale)));
|
| + SkNWayCanvas::onDrawImageNine(decoded_image.image, adjusted_center, dst,
|
| + paint ? &decoded_paint : paint);
|
| + }
|
| +
|
| + private:
|
| + DecodedPositionImage LookupImage(const SkImage* image,
|
| + const SkRect& rect,
|
| + const SkMatrix& matrix,
|
| + const SkPaint* paint) {
|
| + SkFilterQuality filter_quality = kNone_SkFilterQuality;
|
| + if (paint)
|
| + filter_quality = paint->getFilterQuality();
|
| +
|
| + if (rect.intersects(canvas_bounds_) && image->isLazyGenerated()) {
|
| + return image_decode_controller_->GetDecodedImage(
|
| + PositionImage(image, rect, matrix, filter_quality));
|
| + }
|
| + return DecodedPositionImage(image, SkSize::Make(1.f, 1.f), filter_quality);
|
| + }
|
| +
|
| + ImageDecodeController* image_decode_controller_;
|
| + const SkRect canvas_bounds_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| scoped_refptr<DisplayListRasterSource>
|
| DisplayListRasterSource::CreateFromDisplayListRecordingSource(
|
| const DisplayListRecordingSource* other,
|
| @@ -33,7 +160,8 @@ DisplayListRasterSource::DisplayListRasterSource()
|
| solid_color_(SK_ColorTRANSPARENT),
|
| clear_canvas_with_debug_color_(false),
|
| slow_down_raster_scale_factor_for_debug_(0),
|
| - should_attempt_to_use_distance_field_text_(false) {}
|
| + should_attempt_to_use_distance_field_text_(false),
|
| + image_decode_controller_(nullptr) {}
|
|
|
| DisplayListRasterSource::DisplayListRasterSource(
|
| const DisplayListRecordingSource* other,
|
| @@ -50,7 +178,8 @@ DisplayListRasterSource::DisplayListRasterSource(
|
| clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_),
|
| slow_down_raster_scale_factor_for_debug_(
|
| other->slow_down_raster_scale_factor_for_debug_),
|
| - should_attempt_to_use_distance_field_text_(false) {}
|
| + should_attempt_to_use_distance_field_text_(false),
|
| + image_decode_controller_(nullptr) {}
|
|
|
| DisplayListRasterSource::DisplayListRasterSource(
|
| const DisplayListRasterSource* other,
|
| @@ -68,7 +197,8 @@ DisplayListRasterSource::DisplayListRasterSource(
|
| slow_down_raster_scale_factor_for_debug_(
|
| other->slow_down_raster_scale_factor_for_debug_),
|
| should_attempt_to_use_distance_field_text_(
|
| - other->should_attempt_to_use_distance_field_text_) {}
|
| + other->should_attempt_to_use_distance_field_text_),
|
| + image_decode_controller_(other->image_decode_controller_) {}
|
|
|
| DisplayListRasterSource::~DisplayListRasterSource() {
|
| }
|
| @@ -101,24 +231,29 @@ void DisplayListRasterSource::PlaybackToCanvas(
|
| }
|
|
|
| void DisplayListRasterSource::RasterCommon(
|
| - SkCanvas* canvas,
|
| + SkCanvas* raster_canvas,
|
| SkPicture::AbortCallback* callback,
|
| const gfx::Rect& canvas_bitmap_rect,
|
| const gfx::Rect& canvas_playback_rect,
|
| float contents_scale) const {
|
| - canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
|
| + SkImageInfo info = raster_canvas->imageInfo();
|
| + ImageHijackCanvas canvas(info.width(), info.height(),
|
| + image_decode_controller_);
|
| + canvas.addCanvas(raster_canvas);
|
| +
|
| + canvas.translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y());
|
| gfx::Rect content_rect =
|
| gfx::ScaleToEnclosingRect(gfx::Rect(size_), contents_scale);
|
| content_rect.Intersect(canvas_playback_rect);
|
|
|
| - canvas->clipRect(gfx::RectToSkRect(content_rect), SkRegion::kIntersect_Op);
|
| + canvas.clipRect(gfx::RectToSkRect(content_rect), SkRegion::kIntersect_Op);
|
|
|
| DCHECK(display_list_.get());
|
| gfx::Rect canvas_target_playback_rect =
|
| canvas_playback_rect - canvas_bitmap_rect.OffsetFromOrigin();
|
| int repeat_count = std::max(1, slow_down_raster_scale_factor_for_debug_);
|
| for (int i = 0; i < repeat_count; ++i) {
|
| - display_list_->Raster(canvas, callback, canvas_target_playback_rect,
|
| + display_list_->Raster(&canvas, callback, canvas_target_playback_rect,
|
| contents_scale);
|
| }
|
| }
|
| @@ -227,4 +362,9 @@ scoped_refptr<RasterSource> DisplayListRasterSource::CreateCloneWithoutLCDText()
|
| new DisplayListRasterSource(this, can_use_lcd_text));
|
| }
|
|
|
| +void DisplayListRasterSource::SetImageDecodeController(
|
| + ImageDecodeController* image_decode_controller) {
|
| + image_decode_controller_ = image_decode_controller;
|
| +}
|
| +
|
| } // namespace cc
|
|
|