| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "cc/playback/image_hijack_canvas.h" |
| 6 |
| 7 #include "cc/playback/discardable_image_map.h" |
| 8 #include "cc/tiles/image_decode_controller.h" |
| 9 #include "third_party/skia/include/core/SkTLazy.h" |
| 10 |
| 11 namespace cc { |
| 12 namespace { |
| 13 |
| 14 SkIRect RoundOutRect(const SkRect& rect) { |
| 15 SkIRect result; |
| 16 rect.roundOut(&result); |
| 17 return result; |
| 18 } |
| 19 |
| 20 class ScopedDecodedImageLock { |
| 21 public: |
| 22 ScopedDecodedImageLock(ImageDecodeController* image_decode_controller, |
| 23 const SkImage* image, |
| 24 const SkRect& src_rect, |
| 25 const SkSize& scale, |
| 26 bool is_decomposable, |
| 27 bool has_perspective, |
| 28 const SkPaint* paint) |
| 29 : image_decode_controller_(image_decode_controller), |
| 30 draw_image_(image, |
| 31 RoundOutRect(src_rect), |
| 32 scale, |
| 33 paint ? paint->getFilterQuality() : kNone_SkFilterQuality, |
| 34 has_perspective, |
| 35 is_decomposable), |
| 36 decoded_draw_image_( |
| 37 image_decode_controller_->GetDecodedImageForDraw(draw_image_)) { |
| 38 DCHECK(image->isLazyGenerated()); |
| 39 if (paint) |
| 40 decoded_paint_.set(*paint)->setFilterQuality( |
| 41 decoded_draw_image_.filter_quality()); |
| 42 } |
| 43 |
| 44 ~ScopedDecodedImageLock() { |
| 45 image_decode_controller_->DrawWithImageFinished(draw_image_, |
| 46 decoded_draw_image_); |
| 47 } |
| 48 |
| 49 const DecodedDrawImage& decoded_image() const { return decoded_draw_image_; } |
| 50 const SkPaint* decoded_paint() const { return decoded_paint_.getMaybeNull(); } |
| 51 |
| 52 private: |
| 53 ImageDecodeController* image_decode_controller_; |
| 54 DrawImage draw_image_; |
| 55 DecodedDrawImage decoded_draw_image_; |
| 56 // TODO(fmalita): use base::Optional when it becomes available |
| 57 SkTLazy<SkPaint> decoded_paint_; |
| 58 }; |
| 59 |
| 60 } // namespace |
| 61 |
| 62 ImageHijackCanvas::ImageHijackCanvas( |
| 63 int width, |
| 64 int height, |
| 65 ImageDecodeController* image_decode_controller) |
| 66 : SkNWayCanvas(width, height), |
| 67 image_decode_controller_(image_decode_controller) {} |
| 68 |
| 69 void ImageHijackCanvas::onDrawPicture(const SkPicture* picture, |
| 70 const SkMatrix* matrix, |
| 71 const SkPaint* paint) { |
| 72 // Ensure that pictures are unpacked by this canvas, instead of being |
| 73 // forwarded to the raster canvas. |
| 74 SkCanvas::onDrawPicture(picture, matrix, paint); |
| 75 } |
| 76 |
| 77 void ImageHijackCanvas::onDrawImage(const SkImage* image, |
| 78 SkScalar x, |
| 79 SkScalar y, |
| 80 const SkPaint* paint) { |
| 81 if (!image->isLazyGenerated()) { |
| 82 SkNWayCanvas::onDrawImage(image, x, y, paint); |
| 83 return; |
| 84 } |
| 85 |
| 86 SkMatrix ctm = getTotalMatrix(); |
| 87 |
| 88 SkSize scale; |
| 89 bool is_decomposable = ExtractScale(ctm, &scale); |
| 90 ScopedDecodedImageLock scoped_lock( |
| 91 image_decode_controller_, image, |
| 92 SkRect::MakeIWH(image->width(), image->height()), scale, is_decomposable, |
| 93 ctm.hasPerspective(), paint); |
| 94 const DecodedDrawImage& decoded_image = scoped_lock.decoded_image(); |
| 95 if (!decoded_image.image()) |
| 96 return; |
| 97 |
| 98 DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().width())); |
| 99 DCHECK_EQ(0, static_cast<int>(decoded_image.src_rect_offset().height())); |
| 100 const SkPaint* decoded_paint = scoped_lock.decoded_paint(); |
| 101 |
| 102 bool need_scale = !decoded_image.is_scale_adjustment_identity(); |
| 103 if (need_scale) { |
| 104 SkNWayCanvas::save(); |
| 105 SkNWayCanvas::scale(1.f / (decoded_image.scale_adjustment().width()), |
| 106 1.f / (decoded_image.scale_adjustment().height())); |
| 107 } |
| 108 SkNWayCanvas::onDrawImage(decoded_image.image(), x, y, decoded_paint); |
| 109 if (need_scale) |
| 110 SkNWayCanvas::restore(); |
| 111 } |
| 112 |
| 113 void ImageHijackCanvas::onDrawImageRect(const SkImage* image, |
| 114 const SkRect* src, |
| 115 const SkRect& dst, |
| 116 const SkPaint* paint, |
| 117 SrcRectConstraint constraint) { |
| 118 if (!image->isLazyGenerated()) { |
| 119 SkNWayCanvas::onDrawImageRect(image, src, dst, paint, constraint); |
| 120 return; |
| 121 } |
| 122 |
| 123 SkRect src_storage; |
| 124 if (!src) { |
| 125 src_storage = SkRect::MakeIWH(image->width(), image->height()); |
| 126 src = &src_storage; |
| 127 } |
| 128 SkMatrix matrix; |
| 129 matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit); |
| 130 matrix.postConcat(getTotalMatrix()); |
| 131 |
| 132 SkSize scale; |
| 133 bool is_decomposable = ExtractScale(matrix, &scale); |
| 134 ScopedDecodedImageLock scoped_lock(image_decode_controller_, image, *src, |
| 135 scale, is_decomposable, |
| 136 matrix.hasPerspective(), paint); |
| 137 const DecodedDrawImage& decoded_image = scoped_lock.decoded_image(); |
| 138 if (!decoded_image.image()) |
| 139 return; |
| 140 |
| 141 const SkPaint* decoded_paint = scoped_lock.decoded_paint(); |
| 142 |
| 143 SkRect adjusted_src = |
| 144 src->makeOffset(decoded_image.src_rect_offset().width(), |
| 145 decoded_image.src_rect_offset().height()); |
| 146 if (!decoded_image.is_scale_adjustment_identity()) { |
| 147 float x_scale = decoded_image.scale_adjustment().width(); |
| 148 float y_scale = decoded_image.scale_adjustment().height(); |
| 149 adjusted_src = SkRect::MakeXYWH( |
| 150 adjusted_src.x() * x_scale, adjusted_src.y() * y_scale, |
| 151 adjusted_src.width() * x_scale, adjusted_src.height() * y_scale); |
| 152 } |
| 153 SkNWayCanvas::onDrawImageRect(decoded_image.image(), &adjusted_src, dst, |
| 154 decoded_paint, constraint); |
| 155 } |
| 156 |
| 157 void ImageHijackCanvas::onDrawImageNine(const SkImage* image, |
| 158 const SkIRect& center, |
| 159 const SkRect& dst, |
| 160 const SkPaint* paint) { |
| 161 // No cc embedder issues image nine calls. |
| 162 NOTREACHED(); |
| 163 } |
| 164 |
| 165 } // namespace cc |
| OLD | NEW |