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 SK_API 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 // tell skia try to cache gpu resource when texture resource create.
hintCacheGpuResource()122 virtual void hintCacheGpuResource() {}
123
124 virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
125 GrSurfaceOrigin* origin) const;
126 #endif
127
onPinAsTexture(GrRecordingContext *)128 virtual bool onPinAsTexture(GrRecordingContext*) const { return false; }
onUnpinAsTexture(GrRecordingContext *)129 virtual void onUnpinAsTexture(GrRecordingContext*) const {}
isPinnedOnContext(GrRecordingContext *)130 virtual bool isPinnedOnContext(GrRecordingContext*) const { return false; }
131
132 // return a read-only copy of the pixels. We promise to not modify them,
133 // but only inspect them (or encode them).
134 virtual bool getROPixels(GrDirectContext*, SkBitmap*,
135 CachingHint = kAllow_CachingHint) const = 0;
136
137 virtual sk_sp<SkImage> onMakeSubset(const SkIRect&, GrDirectContext*) const = 0;
138
onRefEncoded()139 virtual sk_sp<SkData> onRefEncoded() const { return nullptr; }
140
141 virtual bool onAsLegacyBitmap(GrDirectContext*, SkBitmap*) const;
142
143 // True for picture-backed and codec-backed
onIsLazyGenerated()144 virtual bool onIsLazyGenerated() const { return false; }
145
146 // True for images instantiated in GPU memory
onIsTextureBacked()147 virtual bool onIsTextureBacked() const { return false; }
148
149 // Amount of texture memory used by texture-backed images.
onTextureSize()150 virtual size_t onTextureSize() const { return 0; }
151
152 // Call when this image is part of the key to a resourcecache entry. This allows the cache
153 // to know automatically those entries can be purged when this SkImage deleted.
notifyAddedToRasterCache()154 virtual void notifyAddedToRasterCache() const {
155 fAddedToRasterCache.store(true);
156 }
157
158 virtual bool onIsValid(GrRecordingContext*) const = 0;
159
160 virtual sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, sk_sp<SkColorSpace>,
161 GrDirectContext*) const = 0;
162
163 virtual sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const = 0;
164
165 // on failure, returns nullptr
onMakeWithMipmaps(sk_sp<SkMipmap>)166 virtual sk_sp<SkImage> onMakeWithMipmaps(sk_sp<SkMipmap>) const {
167 return nullptr;
168 }
169
170 protected:
171 SkImage_Base(const SkImageInfo& info, uint32_t uniqueID);
172
173 #if SK_SUPPORT_GPU
174 // Utility for making a copy of an existing view when the GrImageTexGenPolicy is not kDraw.
175 static GrSurfaceProxyView CopyView(GrRecordingContext*,
176 GrSurfaceProxyView src,
177 GrMipmapped,
178 GrImageTexGenPolicy);
179
180 static std::unique_ptr<GrFragmentProcessor> MakeFragmentProcessorFromView(GrRecordingContext*,
181 GrSurfaceProxyView,
182 SkAlphaType,
183 SkSamplingOptions,
184 const SkTileMode[2],
185 const SkMatrix&,
186 const SkRect* subset,
187 const SkRect* domain);
188
189 /**
190 * Returns input view if it is already mipmapped. Otherwise, attempts to make a mipmapped view
191 * with the same contents. If the mipmapped copy is successfully created it will be cached
192 * using the image unique ID. A subsequent call with the same unique ID will return the cached
193 * view if it has not been purged. The view is cached with a key domain specific to this
194 * function.
195 */
196 static GrSurfaceProxyView FindOrMakeCachedMipmappedView(GrRecordingContext*,
197 GrSurfaceProxyView,
198 uint32_t imageUniqueID);
199 #endif
200
201 private:
202 #if SK_SUPPORT_GPU
203 virtual std::tuple<GrSurfaceProxyView, GrColorType> onAsView(
204 GrRecordingContext*,
205 GrMipmapped,
206 GrImageTexGenPolicy policy) const = 0;
207
208 virtual std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(
209 GrRecordingContext*,
210 SkSamplingOptions,
211 const SkTileMode[2],
212 const SkMatrix&,
213 const SkRect* subset,
214 const SkRect* domain) const = 0;
215 #endif
216 // Set true by caches when they cache content that's derived from the current pixels.
217 mutable std::atomic<bool> fAddedToRasterCache;
218
219 using INHERITED = SkImage;
220 };
221
as_IB(SkImage * image)222 static inline SkImage_Base* as_IB(SkImage* image) {
223 return static_cast<SkImage_Base*>(image);
224 }
225
as_IB(const sk_sp<SkImage> & image)226 static inline SkImage_Base* as_IB(const sk_sp<SkImage>& image) {
227 return static_cast<SkImage_Base*>(image.get());
228 }
229
as_IB(const SkImage * image)230 static inline const SkImage_Base* as_IB(const SkImage* image) {
231 return static_cast<const SkImage_Base*>(image);
232 }
233
234 #if SK_SUPPORT_GPU
CopyView(GrRecordingContext * context,GrSurfaceProxyView src,GrMipmapped mipmapped,GrImageTexGenPolicy policy)235 inline GrSurfaceProxyView SkImage_Base::CopyView(GrRecordingContext* context,
236 GrSurfaceProxyView src,
237 GrMipmapped mipmapped,
238 GrImageTexGenPolicy policy) {
239 SkBudgeted budgeted = policy == GrImageTexGenPolicy::kNew_Uncached_Budgeted
240 ? SkBudgeted::kYes
241 : SkBudgeted::kNo;
242 return GrSurfaceProxyView::Copy(context,
243 std::move(src),
244 mipmapped,
245 SkBackingFit::kExact,
246 budgeted);
247 }
248 #endif
249
250 #endif
251