Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5598)

Unified Diff: cc/playback/display_list_raster_source.cc

Issue 1418573002: cc: Add image decode control in the compositor. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 cc4f7a7807d4b95b21a292c48d7440b560fbc222..7e883086d9710b384f14616753f546d475856d2e 100644
--- a/cc/playback/display_list_raster_source.cc
+++ b/cc/playback/display_list_raster_source.cc
@@ -7,14 +7,222 @@
#include "base/trace_event/trace_event.h"
#include "cc/base/region.h"
#include "cc/debug/debug_colors.h"
+#include "cc/playback/discardable_image_map.h"
#include "cc/playback/display_item_list.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 {
+
+bool ComputePaintBounds(const SkRect& rect,
+ const SkPaint* paint,
+ SkRect* paint_bounds) {
+ return false;
vmpstr 2015/12/04 01:05:54 This is debug code :D
+ if (!paint) {
+ *paint_bounds = rect;
+ return true;
+ }
+
+ bool can_compute_bounds = paint->canComputeFastBounds();
+ if (can_compute_bounds)
+ *paint_bounds = paint->computeFastBounds(rect, paint_bounds);
+ return can_compute_bounds;
+}
+
+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 {
+ if (!image->isLazyGenerated()) {
+ SkNWayCanvas::onDrawImage(image, x, y, paint);
+ return;
+ }
+
+ SkMatrix ctm = this->getTotalMatrix();
ericrk 2015/12/04 00:50:46 why this? skia leaking in?
+ SkRect paint_bounds;
+ bool computed_paint_bounds = ComputePaintBounds(
+ SkRect::MakeXYWH(x, y, image->width(), image->height()), paint,
+ &paint_bounds);
+ if (computed_paint_bounds && !canvas_bounds_.intersects(paint_bounds))
+ return;
+
+ SkSize scale;
+ bool is_decomposable = ExtractScale(ctm, &scale);
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, scale,
+ is_decomposable, ctm.hasPerspective(),
+ paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ bool need_scale = !decoded_image.is_scale_adjustment_identity();
+ if (need_scale) {
+ SkNWayCanvas::save();
+ SkNWayCanvas::scale(1.f / (decoded_image.scale_adjustment().width()),
+ 1.f / (decoded_image.scale_adjustment().height()));
+ }
+ SkNWayCanvas::onDrawImage(decoded_image.image(), x, y, decoded_paint);
+ if (need_scale)
+ SkNWayCanvas::restore();
+ }
+
+ void onDrawImageRect(const SkImage* image,
+ const SkRect* src,
+ const SkRect& dst,
+ const SkPaint* paint,
+ SrcRectConstraint constraint) override {
+ if (!image->isLazyGenerated()) {
+ SkNWayCanvas::onDrawImageRect(image, src, dst, paint, constraint);
+ return;
+ }
+
+ SkMatrix ctm = this->getTotalMatrix();
+ SkRect paint_bounds;
+ bool computed_paint_bounds =
+ ComputePaintBounds(MapRect(ctm, dst), paint, &paint_bounds);
+ if (computed_paint_bounds && !canvas_bounds_.intersects(paint_bounds))
+ return;
+
+ 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);
+
+ SkSize scale;
+ bool is_decomposable = ExtractScale(matrix, &scale);
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, scale,
+ is_decomposable, matrix.hasPerspective(),
+ paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ SkRect adjusted_src = *src;
+ if (!decoded_image.is_scale_adjustment_identity()) {
+ float x_scale = decoded_image.scale_adjustment().width();
+ float y_scale = decoded_image.scale_adjustment().height();
+ 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,
+ decoded_paint, constraint);
+ }
+
+ void onDrawImageNine(const SkImage* image,
+ const SkIRect& center,
+ const SkRect& dst,
+ const SkPaint* paint) override {
+ if (!image->isLazyGenerated()) {
+ SkNWayCanvas::onDrawImageNine(image, center, dst, paint);
+ return;
+ }
+
+ SkRect paint_bounds;
+ bool computed_paint_bounds = ComputePaintBounds(dst, paint, &paint_bounds);
+ if (computed_paint_bounds && !canvas_bounds_.intersects(paint_bounds))
+ return;
+
+ SkMatrix ctm = this->getTotalMatrix();
+ SkSize scale;
+ bool is_decomposable = ExtractScale(ctm, &scale);
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, scale,
+ is_decomposable, ctm.hasPerspective(),
+ paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ SkIRect adjusted_center = center;
+ if (!decoded_image.is_scale_adjustment_identity()) {
+ float x_scale = decoded_image.scale_adjustment().width();
+ float y_scale = decoded_image.scale_adjustment().height();
+ 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,
+ decoded_paint);
+ }
+
+ private:
+ class ScopedDecodedImageLock {
+ public:
+ ScopedDecodedImageLock(ImageDecodeController* image_decode_controller,
+ const SkImage* image,
+ const SkSize& scale,
+ bool is_decomposable,
+ bool has_perspective,
+ const SkPaint* paint)
+ : image_decode_controller_(image_decode_controller),
+ paint_(paint),
+ draw_image_(image,
+ scale,
+ paint ? paint->getFilterQuality() : kNone_SkFilterQuality,
+ has_perspective,
+ is_decomposable),
+ decoded_draw_image_(
+ image_decode_controller_->GetDecodedImageForDraw(draw_image_)) {
+ DCHECK(image->isLazyGenerated());
+ if (paint) {
+ decoded_paint_ = *paint;
+ decoded_paint_.setFilterQuality(decoded_draw_image_.filter_quality());
+ }
+ }
+
+ ~ScopedDecodedImageLock() {
+ image_decode_controller_->DrawWithImageFinished(draw_image_,
+ decoded_draw_image_);
+ }
+
+ const DecodedDrawImage& decoded_image() const {
+ return decoded_draw_image_;
+ }
+ const SkPaint* decoded_paint() const {
+ return paint_ ? &decoded_paint_ : nullptr;
+ }
+
+ private:
+ ImageDecodeController* image_decode_controller_;
+ const SkPaint* paint_;
+ DrawImage draw_image_;
+ DecodedDrawImage decoded_draw_image_;
+ SkPaint decoded_paint_;
+ };
+
+ ImageDecodeController* image_decode_controller_;
+ const SkRect canvas_bounds_;
+};
+
+} // namespace
+
scoped_refptr<DisplayListRasterSource>
DisplayListRasterSource::CreateFromDisplayListRecordingSource(
const DisplayListRecordingSource* other,
@@ -38,7 +246,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,
@@ -56,16 +265,22 @@ 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() {
}
void DisplayListRasterSource::PlaybackToSharedCanvas(
- SkCanvas* canvas,
+ SkCanvas* raster_canvas,
const gfx::Rect& canvas_rect,
float contents_scale) const {
- RasterCommon(canvas, NULL, canvas_rect, canvas_rect, contents_scale);
+ SkImageInfo info = raster_canvas->imageInfo();
+ ImageHijackCanvas canvas(info.width(), info.height(),
+ image_decode_controller_);
+ canvas.addCanvas(raster_canvas);
+
+ RasterCommon(&canvas, NULL, canvas_rect, canvas_rect, contents_scale);
}
void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas,
@@ -75,13 +290,18 @@ void DisplayListRasterSource::RasterForAnalysis(skia::AnalysisCanvas* canvas,
}
void DisplayListRasterSource::PlaybackToCanvas(
- SkCanvas* canvas,
+ SkCanvas* raster_canvas,
const gfx::Rect& canvas_bitmap_rect,
const gfx::Rect& canvas_playback_rect,
float contents_scale) const {
- PrepareForPlaybackToCanvas(canvas, canvas_bitmap_rect, canvas_playback_rect,
- contents_scale);
- RasterCommon(canvas, NULL, canvas_bitmap_rect, canvas_playback_rect,
+ PrepareForPlaybackToCanvas(raster_canvas, canvas_bitmap_rect,
+ canvas_playback_rect, contents_scale);
+
+ SkImageInfo info = raster_canvas->imageInfo();
+ ImageHijackCanvas canvas(info.width(), info.height(),
+ image_decode_controller_);
+ canvas.addCanvas(raster_canvas);
+ RasterCommon(&canvas, NULL, canvas_bitmap_rect, canvas_playback_rect,
contents_scale);
}
@@ -300,4 +520,14 @@ DisplayListRasterSource::CreateCloneWithoutLCDText() const {
new DisplayListRasterSource(this, can_use_lcd_text));
}
+void DisplayListRasterSource::SetImageDecodeController(
+ ImageDecodeController* image_decode_controller) {
+ DCHECK(image_decode_controller);
+ // Note that although this function should only be called once, tests tend to
+ // call it several times using the same controller.
+ DCHECK(!image_decode_controller_ ||
+ image_decode_controller_ == image_decode_controller);
+ image_decode_controller_ = image_decode_controller;
+}
+
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698