• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 SkImage_Base_DEFINED
9 #define SkImage_Base_DEFINED
10 
11 #include "include/core/SkData.h"
12 #include "include/core/SkImage.h"
13 #include "include/core/SkRefCnt.h"
14 #include "include/core/SkSamplingOptions.h"
15 #include "include/core/SkTypes.h"
16 #include "src/core/SkMipmap.h"
17 
18 #include <atomic>
19 #include <cstddef>
20 #include <cstdint>
21 #include <memory>
22 #include <string_view>
23 #include <tuple>
24 
25 #if defined(SK_GANESH)
26 #include "include/gpu/GrTypes.h"
27 #include "src/gpu/ganesh/SkGr.h"
28 #endif
29 
30 #if defined(SK_GRAPHITE)
31 namespace skgpu {
32 namespace graphite {
33 class TextureProxyView;
34 }
35 }
36 #endif
37 
38 class GrBackendTexture;
39 class GrDirectContext;
40 class GrFragmentProcessor;
41 class GrImageContext;
42 class GrRecordingContext;
43 class GrSurfaceProxyView;
44 class SkBitmap;
45 class SkColorSpace;
46 class SkMatrix;
47 class SkPixmap;
48 enum SkAlphaType : int;
49 enum SkColorType : int;
50 enum SkYUVColorSpace : int;
51 enum class GrColorType;
52 enum class SkTileMode;
53 struct SkIRect;
54 struct SkISize;
55 struct SkImageInfo;
56 struct SkRect;
57 
58 enum {
59     kNeedNewImageUniqueID = 0
60 };
61 
62 class SkImage_Base : public SkImage {
63 public:
64     ~SkImage_Base() override;
65 
onPeekPixels(SkPixmap *)66     virtual bool onPeekPixels(SkPixmap*) const { return false; }
67 
onPeekBitmap()68     virtual const SkBitmap* onPeekBitmap() const { return nullptr; }
69 
70     virtual bool onReadPixels(GrDirectContext*,
71                               const SkImageInfo& dstInfo,
72                               void* dstPixels,
73                               size_t dstRowBytes,
74                               int srcX,
75                               int srcY,
76                               CachingHint) const = 0;
77 
78     virtual bool onHasMipmaps() const = 0;
79 
onPeekMips()80     virtual SkMipmap* onPeekMips() const { return nullptr; }
81 
refMips()82     sk_sp<SkMipmap> refMips() const {
83         return sk_ref_sp(this->onPeekMips());
84     }
85 
86     /**
87      * Default implementation does a rescale/read and then calls the callback.
88      */
89     virtual void onAsyncRescaleAndReadPixels(const SkImageInfo&,
90                                              SkIRect srcRect,
91                                              RescaleGamma,
92                                              RescaleMode,
93                                              ReadPixelsCallback,
94                                              ReadPixelsContext) const;
95     /**
96      * Default implementation does a rescale/read/yuv conversion and then calls the callback.
97      */
98     virtual void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
99                                                    sk_sp<SkColorSpace> dstColorSpace,
100                                                    SkIRect srcRect,
101                                                    SkISize dstSize,
102                                                    RescaleGamma,
103                                                    RescaleMode,
104                                                    ReadPixelsCallback,
105                                                    ReadPixelsContext) const;
106 
context()107     virtual GrImageContext* context() const { return nullptr; }
108 
109     /** this->context() try-casted to GrDirectContext. Useful for migrations – avoid otherwise! */
110     GrDirectContext* directContext() const;
111 
112 #if defined(SK_GANESH)
onFlush(GrDirectContext *,const GrFlushInfo &)113     virtual GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) const {
114         return GrSemaphoresSubmitted::kNo;
115     }
116 
117     // Returns a GrSurfaceProxyView representation of the image, if possible. This also returns
118     // a color type. This may be different than the image's color type when the image is not
119     // texture-backed and the capabilities of the GPU require a data type conversion to put
120     // the data in a texture.
121     std::tuple<GrSurfaceProxyView, GrColorType> asView(
122             GrRecordingContext* context,
123             GrMipmapped mipmapped,
124             GrImageTexGenPolicy policy = GrImageTexGenPolicy::kDraw) const;
125 
126     /**
127      * Returns a GrFragmentProcessor that can be used with the passed GrRecordingContext to
128      * draw the image. SkSamplingOptions indicates the filter and SkTileMode[] indicates the x and
129      * y tile modes. The passed matrix is applied to the coordinates before sampling the image.
130      * Optional 'subset' indicates whether the tile modes should be applied to a subset of the image
131      * Optional 'domain' is a bound on the coordinates of the image that will be required and can be
132      * used to optimize the shader if 'subset' is also specified.
133      */
134     std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
135                                                              SkSamplingOptions,
136                                                              const SkTileMode[2],
137                                                              const SkMatrix&,
138                                                              const SkRect* subset = nullptr,
139                                                              const SkRect* domain = nullptr) const;
140 
141     // If this image is the current cached image snapshot of a surface then this is called when the
142     // surface is destroyed to indicate no further writes may happen to surface backing store.
generatingSurfaceIsDeleted()143     virtual void generatingSurfaceIsDeleted() {}
144 
145     virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
146                                                  GrSurfaceOrigin* origin) const;
147 #endif
148 #if defined(SK_GRAPHITE)
149     // Returns a TextureProxyView representation of the image, if possible. This also returns
150     // a color type. This may be different than the image's color type when the image is not
151     // texture-backed and the capabilities of the GPU require a data type conversion to put
152     // the data in a texture.
153     std::tuple<skgpu::graphite::TextureProxyView, SkColorType> asView(
154             skgpu::graphite::Recorder*,
155             skgpu::Mipmapped) const;
156 
157 #endif
158 #if defined(SK_GANESH) || defined(SK_GRAPHITE)
isYUVA()159     virtual bool isYUVA() const { return false; }
160 #endif
161 
onPinAsTexture(GrRecordingContext *)162     virtual bool onPinAsTexture(GrRecordingContext*) const { return false; }
onUnpinAsTexture(GrRecordingContext *)163     virtual void onUnpinAsTexture(GrRecordingContext*) const {}
isPinnedOnContext(GrRecordingContext *)164     virtual bool isPinnedOnContext(GrRecordingContext*) const { return false; }
165 
166     // return a read-only copy of the pixels. We promise to not modify them,
167     // but only inspect them (or encode them).
168     virtual bool getROPixels(GrDirectContext*, SkBitmap*,
169                              CachingHint = kAllow_CachingHint) const = 0;
170 
171     virtual sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const = 0;
172 
onRefEncoded()173     virtual sk_sp<SkData> onRefEncoded() const { return nullptr; }
174 
175     virtual bool onAsLegacyBitmap(GrDirectContext*, SkBitmap*) const;
176 
177     // True for picture-backed and codec-backed
onIsLazyGenerated()178     virtual bool onIsLazyGenerated() const { return false; }
179 
180     // True for images instantiated by Ganesh in GPU memory
isGaneshBacked()181     virtual bool isGaneshBacked() const { return false; }
182 
183     // True for images instantiated by Graphite in GPU memory
isGraphiteBacked()184     virtual bool isGraphiteBacked() const { return false; }
185 
186     // Amount of texture memory used by texture-backed images.
onTextureSize()187     virtual size_t onTextureSize() const { return 0; }
188 
189     // Call when this image is part of the key to a resourcecache entry. This allows the cache
190     // to know automatically those entries can be purged when this SkImage deleted.
notifyAddedToRasterCache()191     virtual void notifyAddedToRasterCache() const {
192         fAddedToRasterCache.store(true);
193     }
194 
195     virtual bool onIsValid(GrRecordingContext*) const = 0;
196 
197     virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>,
198                                                         GrDirectContext*) const = 0;
199 
200     virtual sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const = 0;
201 
202     // on failure, returns nullptr
onMakeWithMipmaps(sk_sp<SkMipmap>)203     virtual sk_sp<SkImage> onMakeWithMipmaps(sk_sp<SkMipmap>) const {
204         return nullptr;
205     }
206 
207 #if defined(SK_GRAPHITE)
208     virtual sk_sp<SkImage> onMakeTextureImage(skgpu::graphite::Recorder*,
209                                               RequiredImageProperties) const = 0;
210     virtual sk_sp<SkImage> onMakeSubset(const SkIRect&,
211                                         skgpu::graphite::Recorder*,
212                                         RequiredImageProperties) const = 0;
213     virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType,
214                                                         sk_sp<SkColorSpace>,
215                                                         skgpu::graphite::Recorder*,
216                                                         RequiredImageProperties) const = 0;
217 #endif
218 
219 protected:
220     SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);
221 
222 #if defined(SK_GANESH)
223     // Utility for making a copy of an existing view when the GrImageTexGenPolicy is not kDraw.
224     static GrSurfaceProxyView CopyView(GrRecordingContext*,
225                                        GrSurfaceProxyView src,
226                                        GrMipmapped,
227                                        GrImageTexGenPolicy,
228                                        std::string_view label);
229 
230     static std::unique_ptr<GrFragmentProcessor> MakeFragmentProcessorFromView(GrRecordingContext*,
231                                                                               GrSurfaceProxyView,
232                                                                               SkAlphaType,
233                                                                               SkSamplingOptions,
234                                                                               const SkTileMode[2],
235                                                                               const SkMatrix&,
236                                                                               const SkRect* subset,
237                                                                               const SkRect* domain);
238 
239     /**
240      * Returns input view if it is already mipmapped. Otherwise, attempts to make a mipmapped view
241      * with the same contents. If the mipmapped copy is successfully created it will be cached
242      * using the image unique ID. A subsequent call with the same unique ID will return the cached
243      * view if it has not been purged. The view is cached with a key domain specific to this
244      * function.
245      */
246     static GrSurfaceProxyView FindOrMakeCachedMipmappedView(GrRecordingContext*,
247                                                             GrSurfaceProxyView,
248                                                             uint32_t imageUniqueID);
249 #endif
250 
251 private:
252 #if defined(SK_GANESH)
253     virtual std::tuple<GrSurfaceProxyView, GrColorType> onAsView(
254             GrRecordingContext*,
255             GrMipmapped,
256             GrImageTexGenPolicy policy) const = 0;
257 
258     virtual std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(
259             GrRecordingContext*,
260             SkSamplingOptions,
261             const SkTileMode[2],
262             const SkMatrix&,
263             const SkRect* subset,
264             const SkRect* domain) const = 0;
265 #endif
266 
267     // Set true by caches when they cache content that's derived from the current pixels.
268     mutable std::atomic<bool> fAddedToRasterCache;
269 };
270 
as_IB(SkImage * image)271 static inline SkImage_Base* as_IB(SkImage* image) {
272     return static_cast<SkImage_Base*>(image);
273 }
274 
as_IB(const sk_sp<SkImage> & image)275 static inline SkImage_Base* as_IB(const sk_sp<SkImage>& image) {
276     return static_cast<SkImage_Base*>(image.get());
277 }
278 
as_IB(const SkImage * image)279 static inline const SkImage_Base* as_IB(const SkImage* image) {
280     return static_cast<const SkImage_Base*>(image);
281 }
282 
283 #endif
284