• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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_Ganesh_DEFINED
9 #define SkImage_Ganesh_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkSamplingOptions.h"
13 #include "include/private/base/SkDebug.h"
14 #include "include/private/base/SkThreadAnnotations.h"
15 #include "src/base/SkSpinlock.h"
16 #include "src/gpu/Swizzle.h"
17 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
18 #include "src/gpu/ganesh/image/SkImage_GaneshBase.h"
19 #include "src/image/SkImage_Base.h"
20 
21 #include <cstddef>
22 #include <cstdint>
23 #include <memory>
24 #include <tuple>
25 
26 class GrBackendFormat;
27 class GrBackendTexture;
28 class GrDirectContext;
29 class GrFragmentProcessor;
30 class GrImageContext;
31 class GrRecordingContext;
32 class GrRenderTask;
33 class GrSurfaceProxy;
34 class SkColorInfo;
35 class SkColorSpace;
36 class SkImage;
37 class SkMatrix;
38 enum class GrColorType;
39 enum class GrImageTexGenPolicy : int;
40 enum class GrSemaphoresSubmitted : bool;
41 enum class SkTileMode;
42 enum GrSurfaceOrigin : int;
43 enum SkColorType : int;
44 enum SkYUVColorSpace : int;
45 struct GrFlushInfo;
46 struct SkIRect;
47 struct SkISize;
48 struct SkImageInfo;
49 struct SkRect;
50 
51 namespace skgpu {
52 enum class Mipmapped : bool;
53 enum class Protected : bool;
54 }
55 
56 class SkImage_Ganesh final : public SkImage_GaneshBase {
57 public:
58     SkImage_Ganesh(sk_sp<GrImageContext> context,
59                    uint32_t uniqueID,
60                    GrSurfaceProxyView view,
61                    SkColorInfo info);
62 
63     static sk_sp<SkImage> MakeWithVolatileSrc(sk_sp<GrRecordingContext> rContext,
64                                               GrSurfaceProxyView volatileSrc,
65                                               SkColorInfo colorInfo);
66 
67     ~SkImage_Ganesh() override;
68 
69     // From SkImage.h
70     size_t textureSize() const override;
71 
72     // From SkImage_Base.h
type()73     SkImage_Base::Type type() const override { return SkImage_Base::Type::kGanesh; }
74 
75     bool onHasMipmaps() const override;
76     bool onIsProtected() const override;
77 
78     using SkImage_GaneshBase::onMakeColorTypeAndColorSpace;
79     sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType,
80                                                 sk_sp<SkColorSpace>,
81                                                 GrDirectContext*) const final;
82 
83     sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final;
84 
85     void onAsyncRescaleAndReadPixels(const SkImageInfo&,
86                                      SkIRect srcRect,
87                                      RescaleGamma,
88                                      RescaleMode,
89                                      ReadPixelsCallback,
90                                      ReadPixelsContext) const override;
91 
92     void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace,
93                                            bool readAlpha,
94                                            sk_sp<SkColorSpace>,
95                                            SkIRect srcRect,
96                                            SkISize dstSize,
97                                            RescaleGamma,
98                                            RescaleMode,
99                                            ReadPixelsCallback,
100                                            ReadPixelsContext) const override;
101 
102     void generatingSurfaceIsDeleted() override;
103 
104     void hintCacheGpuResource() override;
105     // From SkImage_GaneshBase.h
106     GrSemaphoresSubmitted flush(GrDirectContext*, const GrFlushInfo&) const override;
107 
108     std::tuple<GrSurfaceProxyView, GrColorType> asView(GrRecordingContext*,
109                                                        skgpu::Mipmapped,
110                                                        GrImageTexGenPolicy) const override;
111 
112     std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext*,
113                                                              SkSamplingOptions,
114                                                              const SkTileMode[2],
115                                                              const SkMatrix&,
116                                                              const SkRect*,
117                                                              const SkRect*) const override;
118 
119     // If this is image is a cached SkSurface snapshot then this method is called by the SkSurface
120     // before a write to check if the surface must make a copy to avoid modifying the image's
121     // contents.
122     bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const;
123 
124     bool getExistingBackendTexture(GrBackendTexture* outTexture,
125                                    bool flushPendingGrContextIO,
126                                    GrSurfaceOrigin* origin) const;
127 
origin()128     GrSurfaceOrigin origin() const override { return fOrigin; }
129 
130 private:
131     SkImage_Ganesh(sk_sp<GrDirectContext>,
132                    GrSurfaceProxyView volatileSrc,
133                    sk_sp<GrSurfaceProxy> stableCopy,
134                    sk_sp<GrRenderTask> copyTask,
135                    int volatileSrcTargetCount,
136                    SkColorInfo);
137 
138     GrSurfaceProxyView makeView(GrRecordingContext*) const;
139 
140     // Thread-safe wrapper around the proxies backing this image. Handles dynamically switching
141     // from a "volatile" proxy that may be overwritten (by an SkSurface that this image was snapped
142     // from) to a "stable" proxy that is a copy of the volatile proxy. It allows the image to cancel
143     // the copy if the stable proxy is never required because the contents of the volatile proxy
144     // were never mutated by the SkSurface during the image lifetime.
145     class ProxyChooser {
146     public:
147         ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy,
148                      sk_sp<GrSurfaceProxy> volatileProxy,
149                      sk_sp<GrRenderTask> copyTask,
150                      int volatileProxyTargetCount);
151 
152         ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy);
153 
154         ~ProxyChooser();
155 
156         // Checks if there is a volatile proxy that is safe to use. If so returns it, otherwise
157         // returns the stable proxy (and drops the volatile one if it exists).
158         sk_sp<GrSurfaceProxy> chooseProxy(GrRecordingContext* context) SK_EXCLUDES(fLock);
159         // Call when it is known copy is necessary.
160         sk_sp<GrSurfaceProxy> switchToStableProxy() SK_EXCLUDES(fLock);
161         // Call when it is known for sure copy won't be necessary.
162         sk_sp<GrSurfaceProxy> makeVolatileProxyStable() SK_EXCLUDES(fLock);
163 
164         bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const SK_EXCLUDES(fLock);
165 
166         // Queries that should be independent of which proxy is in use.
167         size_t gpuMemorySize() const SK_EXCLUDES(fLock);
168         skgpu::Mipmapped mipmapped() const SK_EXCLUDES(fLock);
169         skgpu::Protected isProtected() const SK_EXCLUDES(fLock);
170 #ifdef SK_DEBUG
171         const GrBackendFormat& backendFormat() SK_EXCLUDES(fLock);
172 #endif
173 
174     private:
175         mutable SkSpinlock fLock;
176         sk_sp<GrSurfaceProxy> fStableProxy SK_GUARDED_BY(fLock);
177         sk_sp<GrSurfaceProxy> fVolatileProxy SK_GUARDED_BY(fLock);
178         sk_sp<GrRenderTask> fVolatileToStableCopyTask;
179         // The number of GrRenderTasks targeting the volatile proxy at creation time. If the
180         // proxy's target count increases it indicates additional writes and we must switch
181         // to using the stable copy.
182         const int fVolatileProxyTargetCount = 0;
183     };
184 
185     mutable ProxyChooser fChooser;
186     skgpu::Swizzle fSwizzle;
187     GrSurfaceOrigin fOrigin;
188 
189     using INHERITED = SkImage_GaneshBase;
190 };
191 
192 #endif
193