/src/skia/src/core/SkSpecialImage.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2016 Google Inc. |
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 | | #ifndef SkSpecialImage_DEFINED |
9 | | #define SkSpecialImage_DEFINED |
10 | | |
11 | | #include "include/core/SkImageInfo.h" |
12 | | #include "include/core/SkRect.h" |
13 | | #include "include/core/SkRefCnt.h" |
14 | | #include "include/core/SkSamplingOptions.h" |
15 | | #include "include/core/SkScalar.h" |
16 | | #include "include/core/SkSize.h" |
17 | | #include "include/core/SkSurfaceProps.h" |
18 | | |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | |
22 | | class GrRecordingContext; |
23 | | class SkBitmap; |
24 | | class SkCanvas; |
25 | | class SkColorSpace; |
26 | | class SkImage; |
27 | | class SkMatrix; |
28 | | class SkPaint; |
29 | | class SkShader; |
30 | | enum SkAlphaType : int; |
31 | | enum SkColorType : int; |
32 | | enum class SkTileMode; |
33 | | |
34 | | enum { |
35 | | kNeedNewImageUniqueID_SpecialImage = 0 |
36 | | }; |
37 | | |
38 | | /** |
39 | | * This is a restricted form of SkImage solely intended for internal use. It |
40 | | * differs from SkImage in that: |
41 | | * - it can only be backed by raster or gpu (no generators) |
42 | | * - it can be backed by a GrTextureProxy larger than its nominal bounds |
43 | | * - it can't be drawn tiled |
44 | | * - it can't be drawn with MIPMAPs |
45 | | * It is similar to SkImage in that it abstracts how the pixels are stored/represented. |
46 | | * |
47 | | * Note: the contents of the backing storage outside of the subset rect are undefined. |
48 | | */ |
49 | | class SkSpecialImage : public SkRefCnt { |
50 | | public: |
51 | | typedef void* ReleaseContext; |
52 | | typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext); |
53 | | |
54 | 224k | const SkSurfaceProps& props() const { return fProps; } |
55 | | |
56 | 746k | int width() const { return fSubset.width(); } |
57 | 746k | int height() const { return fSubset.height(); } |
58 | 658k | SkISize dimensions() const { return { this->width(), this->height() }; } |
59 | 1.02M | const SkIRect& subset() const { return fSubset; } |
60 | | |
61 | 337k | uint32_t uniqueID() const { return fUniqueID; } |
62 | | |
63 | | virtual SkISize backingStoreDimensions() const = 0; |
64 | | |
65 | | virtual size_t getSize() const = 0; |
66 | | |
67 | 0 | bool isExactFit() const { return fSubset == SkIRect::MakeSize(this->backingStoreDimensions()); } |
68 | | |
69 | 220k | const SkColorInfo& colorInfo() const { return fColorInfo; } |
70 | 0 | SkAlphaType alphaType() const { return fColorInfo.alphaType(); } |
71 | 6.54k | SkColorType colorType() const { return fColorInfo.colorType(); } |
72 | 19.7k | SkColorSpace* getColorSpace() const { return fColorInfo.colorSpace(); } |
73 | | |
74 | | /** |
75 | | * Draw this SpecialImage into the canvas, automatically taking into account the image's subset |
76 | | */ |
77 | | void draw(SkCanvas* canvas, |
78 | | SkScalar x, SkScalar y, |
79 | | const SkSamplingOptions& sampling, |
80 | | const SkPaint* paint, |
81 | | bool strict = true) const; |
82 | 0 | void draw(SkCanvas* canvas, SkScalar x, SkScalar y) const { |
83 | 0 | this->draw(canvas, x, y, SkSamplingOptions(), nullptr); |
84 | 0 | } |
85 | | |
86 | | /** |
87 | | * Extract a subset of this special image and return it as a special image. |
88 | | * It may or may not point to the same backing memory. The input 'subset' is relative to the |
89 | | * special image's content rect. |
90 | | */ |
91 | 122k | sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const { |
92 | 122k | SkIRect absolute = subset.makeOffset(this->subset().topLeft()); |
93 | 122k | return this->onMakeBackingStoreSubset(absolute); |
94 | 122k | } |
95 | | |
96 | | /** |
97 | | * Return a special image with a 1px larger subset in the backing store compared to this image. |
98 | | * This should only be used when it's externally known that those outer pixels are valid. |
99 | | */ |
100 | 101k | sk_sp<SkSpecialImage> makePixelOutset() const { |
101 | 101k | return this->onMakeBackingStoreSubset(this->subset().makeOutset(1, 1)); |
102 | 101k | } |
103 | | |
104 | | /** |
105 | | * Create an SkImage view of the contents of this special image, pointing to the same |
106 | | * underlying memory. |
107 | | * |
108 | | * TODO: If SkImages::MakeFiltered were to return an SkShader that accounted for the subset |
109 | | * constraint and offset, then this could move to a private virtual for use in draw() and |
110 | | * asShader(). |
111 | | */ |
112 | | virtual sk_sp<SkImage> asImage() const = 0; |
113 | | |
114 | | /** |
115 | | * Create an SkShader that samples the contents of this special image, applying tile mode for |
116 | | * any sample that falls outside its internal subset. |
117 | | * |
118 | | * 'strict' defaults to true and applies shader-based tiling to the subset. If the subset is |
119 | | * the same as the backing store dimensions, it is automatically degraded to non-strict |
120 | | * (HW tiling and sampling). 'strict' can be set to false if it's known that the subset |
121 | | * boundaries aren't visible AND the texel data in adjacent rows/cols is valid to be included |
122 | | * by the given sampling options. |
123 | | */ |
124 | | virtual sk_sp<SkShader> asShader(SkTileMode, |
125 | | const SkSamplingOptions&, |
126 | | const SkMatrix& lm, |
127 | | bool strict=true) const; |
128 | | |
129 | | /** |
130 | | * If the SpecialImage is backed by a gpu texture, return true. |
131 | | */ |
132 | 98.9k | virtual bool isGaneshBacked() const { return false; } |
133 | 98.9k | virtual bool isGraphiteBacked() const { return false; } |
134 | | |
135 | | /** |
136 | | * Return the GrRecordingContext if the SkSpecialImage is GrTexture-backed |
137 | | */ |
138 | 0 | virtual GrRecordingContext* getContext() const { return nullptr; } |
139 | | |
140 | | protected: |
141 | | SkSpecialImage(const SkIRect& subset, |
142 | | uint32_t uniqueID, |
143 | | const SkColorInfo&, |
144 | | const SkSurfaceProps&); |
145 | | |
146 | | // This subset is relative to the backing store's coordinate frame, it has already been mapped |
147 | | // from the content rect by the non-virtual makeSubset(). The provided 'subset' is not |
148 | | // necessarily contained within this special image's subset. |
149 | | virtual sk_sp<SkSpecialImage> onMakeBackingStoreSubset(const SkIRect& subset) const = 0; |
150 | | |
151 | | private: |
152 | | const SkIRect fSubset; |
153 | | const uint32_t fUniqueID; |
154 | | const SkColorInfo fColorInfo; |
155 | | const SkSurfaceProps fProps; |
156 | | }; |
157 | | |
158 | | namespace SkSpecialImages { |
159 | | |
160 | | sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, sk_sp<SkImage>, const SkSurfaceProps&); |
161 | | sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset, const SkBitmap&, const SkSurfaceProps&); |
162 | | sk_sp<SkSpecialImage> CopyFromRaster(const SkIRect& subset, const SkBitmap&, const SkSurfaceProps&); |
163 | | |
164 | | bool AsBitmap(const SkSpecialImage* img, SkBitmap*); |
165 | | |
166 | | } // namespace SkSpecialImages |
167 | | |
168 | | #endif // SkSpecialImage_DEFINED |