1 // Copyright 2015 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.
5 #include "skia/ext/discardable_image_utils.h"
9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "third_party/skia/include/core/SkImage.h"
11 #include "third_party/skia/include/utils/SkNWayCanvas.h"
17 class DiscardableImageSet
{
19 DiscardableImageSet(std::vector
<DiscardableImageUtils::PositionImage
>* images
)
22 void Add(const SkImage
* image
,
24 const SkMatrix
& matrix
,
25 SkFilterQuality filter_quality
) {
26 // We should only be saving discardable pixel refs.
27 SkASSERT(image
->isLazyGenerated());
29 DiscardableImageUtils::PositionImage position_image
;
30 position_image
.image
= image
;
31 position_image
.image_rect
= rect
;
32 position_image
.matrix
= matrix
;
33 position_image
.filter_quality
= filter_quality
;
34 images_
->push_back(position_image
);
38 std::vector
<DiscardableImageUtils::PositionImage
>* images_
;
41 SkRect
MapRect(const SkMatrix
& matrix
, const SkRect
& src
) {
43 matrix
.mapRect(&dst
, src
);
47 class GatherDiscardableImageCanvas
: public SkNWayCanvas
{
49 GatherDiscardableImageCanvas(int width
,
51 DiscardableImageSet
* image_set
)
52 : SkNWayCanvas(width
, height
),
53 image_set_(image_set
),
54 canvas_bounds_(SkRect::MakeIWH(width
, height
)) {}
57 // we need to "undo" the behavio of SkNWayCanvas, which will try to forward
59 void onDrawPicture(const SkPicture
* picture
,
60 const SkMatrix
* matrix
,
61 const SkPaint
* paint
) override
{
62 SkCanvas::onDrawPicture(picture
, matrix
, paint
);
65 void onDrawImage(const SkImage
* image
,
68 const SkPaint
* paint
) override
{
69 const SkMatrix
& ctm
= this->getTotalMatrix();
70 AddImage(image
, MapRect(ctm
, SkRect::MakeXYWH(x
, y
, image
->width(),
75 void onDrawImageRect(const SkImage
* image
,
79 SrcRectConstraint
) override
{
80 const SkMatrix
& ctm
= this->getTotalMatrix();
83 src_storage
= SkRect::MakeIWH(image
->width(), image
->height());
87 matrix
.setRectToRect(*src
, dst
, SkMatrix::kFill_ScaleToFit
);
88 matrix
.postConcat(ctm
);
89 AddImage(image
, MapRect(ctm
, dst
), matrix
, paint
);
92 void onDrawImageNine(const SkImage
* image
,
93 const SkIRect
& center
,
95 const SkPaint
* paint
) override
{
96 AddImage(image
, dst
, this->getTotalMatrix(), paint
);
100 DiscardableImageSet
* image_set_
;
101 const SkRect canvas_bounds_
;
103 void AddImage(const SkImage
* image
,
105 const SkMatrix
& matrix
,
106 const SkPaint
* paint
) {
107 if (rect
.intersects(canvas_bounds_
) && image
->isLazyGenerated()) {
108 SkFilterQuality filter_quality
= kNone_SkFilterQuality
;
110 filter_quality
= paint
->getFilterQuality();
112 image_set_
->Add(image
, rect
, matrix
, filter_quality
);
119 void DiscardableImageUtils::GatherDiscardableImages(
121 std::vector
<PositionImage
>* images
) {
123 DiscardableImageSet
image_set(images
);
125 SkIRect picture_ibounds
= picture
->cullRect().roundOut();
126 // Use right/bottom as the size so that we don't need a translate and, as a
127 // result, the information is returned relative to the picture's origin.
128 GatherDiscardableImageCanvas
canvas(picture_ibounds
.right(),
129 picture_ibounds
.bottom(), &image_set
);
131 canvas
.drawPicture(picture
);