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

Unified Diff: cc/playback/image_hijack_canvas.cc

Issue 2514263002: Handle simple SkImageShaders (Closed)
Patch Set: rebase Created 4 years, 1 month 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
« no previous file with comments | « cc/playback/image_hijack_canvas.h ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/playback/image_hijack_canvas.cc
diff --git a/cc/playback/image_hijack_canvas.cc b/cc/playback/image_hijack_canvas.cc
index 15c42a7abefded627e0bbe9264bd88973273e14f..1baa114d5de39869a6398d9999812cec8624c26b 100644
--- a/cc/playback/image_hijack_canvas.cc
+++ b/cc/playback/image_hijack_canvas.cc
@@ -7,6 +7,7 @@
#include "base/optional.h"
#include "cc/playback/discardable_image_map.h"
#include "cc/tiles/image_decode_controller.h"
+#include "third_party/skia/include/core/SkPath.h"
namespace cc {
namespace {
@@ -38,9 +39,19 @@ class ScopedDecodedImageLock {
}
}
+ ScopedDecodedImageLock(ScopedDecodedImageLock&& from)
+ : image_decode_controller_(from.image_decode_controller_),
+ draw_image_(std::move(from.draw_image_)),
+ decoded_draw_image_(std::move(from.decoded_draw_image_)),
+ decoded_paint_(std::move(from.decoded_paint_)) {
+ from.image_decode_controller_ = nullptr;
+ }
+
~ScopedDecodedImageLock() {
- image_decode_controller_->DrawWithImageFinished(draw_image_,
- decoded_draw_image_);
+ if (image_decode_controller_) {
+ image_decode_controller_->DrawWithImageFinished(draw_image_,
+ decoded_draw_image_);
+ }
}
const DecodedDrawImage& decoded_image() const { return decoded_draw_image_; }
@@ -55,6 +66,55 @@ class ScopedDecodedImageLock {
base::Optional<SkPaint> decoded_paint_;
};
+// Encapsulates a ScopedDecodedImageLock and an SkPaint. Use of this class
+// ensures that the ScopedDecodedImageLock outlives the dependent SkPaint.
+class ScopedImagePaint {
+ public:
+ // Tries to create a ScopedImagePaint for the provided SkPaint. If a
+ // the SkPaint does not contain an image that we support replacing,
+ // an empty base::Optional will be returned.
+ static base::Optional<ScopedImagePaint> TryCreate(
+ ImageDecodeController* image_decode_controller,
+ const SkMatrix& ctm,
+ const SkPaint& paint) {
+ SkShader* shader = paint.getShader();
+ if (!shader)
+ return base::Optional<ScopedImagePaint>();
+
+ SkMatrix matrix;
+ SkShader::TileMode xy[2];
+ SkImage* image = shader->isAImage(&matrix, xy);
+ if (!image)
+ return base::Optional<ScopedImagePaint>();
+
+ ScopedDecodedImageLock scoped_lock(
+ image_decode_controller, sk_ref_sp(image),
+ SkRect::MakeIWH(image->width(), image->height()), ctm, &paint);
+ const DecodedDrawImage& decoded_image = scoped_lock.decoded_image();
+ if (!decoded_image.image())
+ return base::Optional<ScopedImagePaint>();
+
+ bool need_scale = !decoded_image.is_scale_adjustment_identity();
+ if (need_scale) {
+ matrix.preScale(1.f / (decoded_image.scale_adjustment().width()),
vmpstr 2016/11/29 01:00:03 nit: no need for brackets
ericrk 2016/11/29 21:46:05 Done.
+ 1.f / (decoded_image.scale_adjustment().height()));
+ }
+ SkPaint scratch_paint = paint;
+ scratch_paint.setShader(
+ decoded_image.image()->makeShader(xy[0], xy[1], &matrix));
+ return ScopedImagePaint(std::move(scoped_lock), std::move(scratch_paint));
+ }
+
+ const SkPaint& paint() { return paint_; }
+
+ private:
+ ScopedImagePaint(ScopedDecodedImageLock lock, SkPaint paint)
+ : lock_(std::move(lock)), paint_(std::move(paint)) {}
+
+ ScopedDecodedImageLock lock_;
+ SkPaint paint_;
+};
+
} // namespace
ImageHijackCanvas::ImageHijackCanvas(
@@ -146,6 +206,61 @@ void ImageHijackCanvas::onDrawImageRect(const SkImage* image,
decoded_paint, constraint);
}
+void ImageHijackCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
+ base::Optional<ScopedImagePaint> image_paint = ScopedImagePaint::TryCreate(
+ image_decode_controller_, getTotalMatrix(), paint);
+ if (!image_paint.has_value()) {
+ SkNWayCanvas::onDrawRect(r, paint);
+ return;
+ }
+ SkNWayCanvas::onDrawRect(r, image_paint.value().paint());
+}
+
+void ImageHijackCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
+ base::Optional<ScopedImagePaint> image_paint = ScopedImagePaint::TryCreate(
+ image_decode_controller_, getTotalMatrix(), paint);
+ if (!image_paint.has_value()) {
+ SkNWayCanvas::onDrawPath(path, paint);
+ return;
+ }
+ SkNWayCanvas::onDrawPath(path, image_paint.value().paint());
+}
+
+void ImageHijackCanvas::onDrawOval(const SkRect& r, const SkPaint& paint) {
+ base::Optional<ScopedImagePaint> image_paint = ScopedImagePaint::TryCreate(
+ image_decode_controller_, getTotalMatrix(), paint);
+ if (!image_paint.has_value()) {
+ SkNWayCanvas::onDrawOval(r, paint);
+ return;
+ }
+ SkNWayCanvas::onDrawOval(r, image_paint.value().paint());
+}
+
+void ImageHijackCanvas::onDrawArc(const SkRect& r,
+ SkScalar start_angle,
+ SkScalar sweep_angle,
+ bool use_center,
+ const SkPaint& paint) {
+ base::Optional<ScopedImagePaint> image_paint = ScopedImagePaint::TryCreate(
+ image_decode_controller_, getTotalMatrix(), paint);
+ if (!image_paint.has_value()) {
+ SkNWayCanvas::onDrawArc(r, start_angle, sweep_angle, use_center, paint);
+ return;
+ }
+ SkNWayCanvas::onDrawArc(r, start_angle, sweep_angle, use_center,
+ image_paint.value().paint());
+}
+
+void ImageHijackCanvas::onDrawRRect(const SkRRect& rr, const SkPaint& paint) {
+ base::Optional<ScopedImagePaint> image_paint = ScopedImagePaint::TryCreate(
+ image_decode_controller_, getTotalMatrix(), paint);
+ if (!image_paint.has_value()) {
+ SkNWayCanvas::onDrawRRect(rr, paint);
+ return;
+ }
+ SkNWayCanvas::onDrawRRect(rr, image_paint.value().paint());
+}
+
void ImageHijackCanvas::onDrawImageNine(const SkImage* image,
const SkIRect& center,
const SkRect& dst,
« no previous file with comments | « cc/playback/image_hijack_canvas.h ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698