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