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