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