• 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/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