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

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: Created 5 years, 2 months 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..af9d030e7837053ed502048f15c25148f4a7ec55 100644
--- a/cc/playback/display_list_raster_source.cc
+++ b/cc/playback/display_list_raster_source.cc
@@ -8,13 +8,190 @@
#include "cc/base/region.h"
#include "cc/debug/debug_colors.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 {
+
+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());
+ if (matrix.getType() & SkMatrix::kAffine_Mask) {
+ if (!matrix.decomposeScale(&scale))
+ scale.set(1, 1);
+ }
+ return scale;
+}
+
+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();
+ if (!canvas_bounds_.intersects(MapRect(
+ ctm, SkRect::MakeXYWH(x, y, image->width(), image->height())))) {
+ return;
+ }
+
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image,
+ ExtractScale(ctm), paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ SkNWayCanvas::save();
enne (OOO) 2015/10/29 22:59:45 Is it worth conditionalizing this save and restore
+ 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);
+ 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();
+ if (!canvas_bounds_.intersects(MapRect(ctm, dst)))
+ 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);
+
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image,
+ ExtractScale(matrix), paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ 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,
+ 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;
+ }
+
+ if (!canvas_bounds_.intersects(dst))
+ return;
+
+ SkMatrix ctm = this->getTotalMatrix();
+ ScopedDecodedImageLock scoped_lock(image_decode_controller_, image,
+ ExtractScale(ctm), paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ const SkPaint* decoded_paint = scoped_lock.decoded_paint();
+
+ 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,
+ decoded_paint);
+ }
+
+ private:
+ class ScopedDecodedImageLock {
+ public:
+ ScopedDecodedImageLock(ImageDecodeController* image_decode_controller,
+ const SkImage* image,
+ const SkSize& scale,
+ const SkPaint* paint)
+ : image_decode_controller_(image_decode_controller),
+ paint_(paint),
+ draw_image_(
+ image,
+ scale,
+ paint ? paint->getFilterQuality() : kNone_SkFilterQuality),
+ decoded_draw_image_(
+ image_decode_controller_->GetDecodedImageAndRef(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_);
+ }
+
+ 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 +215,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,7 +234,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() {
}
@@ -173,24 +352,29 @@ void DisplayListRasterSource::PrepareForPlaybackToCanvas(
}
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);
}
}
@@ -300,4 +484,12 @@ DisplayListRasterSource::CreateCloneWithoutLCDText() const {
new DisplayListRasterSource(this, can_use_lcd_text));
}
+void DisplayListRasterSource::SetImageDecodeController(
+ ImageDecodeController* image_decode_controller) {
+ // This should only be set once.
+ DCHECK(image_decode_controller);
+ DCHECK(!image_decode_controller_);
+ image_decode_controller_ = image_decode_controller;
+}
+
} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698