xref: /aosp_15_r20/external/skia/src/image/SkTiledImageUtils.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkTiledImageUtils.h"
9 
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPixelRef.h"
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/base/SkTFitsIn.h"
15 #include "src/core/SkCanvasPriv.h"
16 #include "src/core/SkDevice.h"
17 #include "src/image/SkImage_Base.h"
18 #include "src/image/SkImage_Picture.h"
19 
20 #include <string.h>
21 
22 namespace SkTiledImageUtils {
23 
DrawImageRect(SkCanvas * canvas,const SkImage * image,const SkRect & src,const SkRect & dst,const SkSamplingOptions & sampling,const SkPaint * paint,SkCanvas::SrcRectConstraint constraint)24 void DrawImageRect(SkCanvas* canvas,
25                    const SkImage* image,
26                    const SkRect& src,
27                    const SkRect& dst,
28                    const SkSamplingOptions& sampling,
29                    const SkPaint* paint,
30                    SkCanvas::SrcRectConstraint constraint) {
31     if (!image || !canvas) {
32         return;
33     }
34 
35     SkPaint p;
36     if (paint) {
37         p = *paint;
38     }
39     if (!SkCanvasPriv::TopDevice(canvas)->drawAsTiledImageRect(
40                 canvas, image, &src, dst, sampling, p, constraint)) {
41         // Either the image didn't require tiling or this is a raster-backed
42         // canvas. In either case fall back to a default draw.
43         canvas->drawImageRect(image, src, dst, sampling, paint, constraint);
44     }
45 }
46 
GetImageKeyValues(const SkImage * image,uint32_t keyValues[kNumImageKeyValues])47 void GetImageKeyValues(const SkImage* image, uint32_t keyValues[kNumImageKeyValues]) {
48     if (!image || !keyValues) {
49         if (keyValues) {
50             memset(keyValues, 0, kNumImageKeyValues * sizeof(uint32_t));
51         }
52         return;
53     }
54 
55     const SkImage_Base* imageBase = as_IB(image);
56     if (const SkBitmap* bm = imageBase->onPeekBitmap()) {
57         keyValues[0] = bm->pixelRef()->getGenerationID();
58         SkIRect subset = image->bounds();
59         subset.offset(bm->pixelRefOrigin());
60 
61         SkASSERT(SkTFitsIn<uint32_t>(subset.fLeft));
62         SkASSERT(SkTFitsIn<uint32_t>(subset.fTop));
63         SkASSERT(SkTFitsIn<uint32_t>(subset.fRight));
64         SkASSERT(SkTFitsIn<uint32_t>(subset.fBottom));
65 
66         keyValues[1] = 0;              // This empty slot is to disambiguate picture IDs
67         keyValues[2] = subset.fLeft;
68         keyValues[3] = subset.fTop;
69         keyValues[4] = subset.fRight;
70         keyValues[5] = subset.fBottom;
71         return;
72     }
73 
74     if (imageBase->type() == SkImage_Base::Type::kLazyPicture) {
75         const SkImage_Picture* pictureImage = static_cast<const SkImage_Picture*>(imageBase);
76         if (pictureImage->getImageKeyValues(keyValues)) {
77             return;
78         }
79     }
80 
81     keyValues[0] = image->uniqueID();
82     memset(&keyValues[1], 0, (kNumImageKeyValues-1) * sizeof(uint32_t));
83 }
84 
85 } // namespace SkTiledImageUtils
86