• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 SkDeferredDisplayListRecorder_DEFINED
9 #define SkDeferredDisplayListRecorder_DEFINED
10 
11 #include "../private/SkDeferredDisplayList.h"
12 #include "SkImageInfo.h"
13 #include "SkRefCnt.h"
14 #include "SkSurfaceCharacterization.h"
15 #include "SkTypes.h"
16 
17 class GrBackendFormat;
18 class GrBackendTexture;
19 class GrContext;
20 class SkCanvas;
21 class SkImage;
22 class SkPromiseImageTexture;
23 class SkSurface;
24 struct SkYUVAIndex;
25 struct SkYUVASizeInfo;
26 
27 /*
28  * This class is intended to be used as:
29  *   Get an SkSurfaceCharacterization representing the intended gpu-backed destination SkSurface
30  *   Create one of these (an SkDDLMaker) on the stack
31  *   Get the canvas and render into it
32  *   Snap off and hold on to an SkDeferredDisplayList
33  *   Once your app actually needs the pixels, call SkSurface::draw(SkDeferredDisplayList*)
34  *
35  * This class never accesses the GPU but performs all the cpu work it can. It
36  * is thread-safe (i.e., one can break a scene into tiles and perform their cpu-side
37  * work in parallel ahead of time).
38  */
39 class SK_API SkDeferredDisplayListRecorder {
40 public:
41     SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&);
42     ~SkDeferredDisplayListRecorder();
43 
characterization()44     const SkSurfaceCharacterization& characterization() const {
45         return fCharacterization;
46     }
47 
48     // The backing canvas will become invalid (and this entry point will return
49     // null) once 'detach' is called.
50     // Note: ownership of the SkCanvas is not transferred via this call.
51     SkCanvas* getCanvas();
52 
53     std::unique_ptr<SkDeferredDisplayList> detach();
54 
55     using PromiseImageTextureContext = void*;
56     using PromiseImageTextureFulfillProc =
57             sk_sp<SkPromiseImageTexture> (*)(PromiseImageTextureContext);
58     using PromiseImageTextureReleaseProc = void (*)(PromiseImageTextureContext);
59     using PromiseImageTextureDoneProc = void (*)(PromiseImageTextureContext);
60 
61     // Deprecated types. To be removed.
62     using LegacyPromiseImageTextureFulfillProc = void (*)(PromiseImageTextureContext,
63                                                           GrBackendTexture*);
64     using TextureContext = PromiseImageTextureContext;
65 
66     enum class DelayReleaseCallback : bool { kNo = false, kYes = true };
67 
68     /**
69         Create a new SkImage that is very similar to an SkImage created by MakeFromTexture. The main
70         difference is that the client doesn't have the backend texture on the gpu yet but they know
71         all the properties of the texture. So instead of passing in a GrBackendTexture the client
72         supplies a GrBackendFormat, width, height, and GrMipMapped state.
73 
74         When we actually send the draw calls to the GPU, we will call the textureFulfillProc and
75         the client will return a GrBackendTexture to us. The properties of the GrBackendTexture must
76         match those set during the SkImage creation, and it must have a valid backend gpu texture.
77         The gpu texture supplied by the client must stay valid until we call the textureReleaseProc.
78 
79         The following applies when DelayReleaseCallback is kNo:
80             When we are done with the texture returned by the textureFulfillProc we will call the
81             textureReleaseProc passing in the textureContext. This is a signal to the client that
82             they are free to delete the underlying gpu texture. If future draws also use the same
83             promise image we will call the textureFulfillProc again if we've already called the
84             textureReleaseProc. We will always call textureFulfillProc and textureReleaseProc in
85             pairs. In other words we will never call textureFulfillProc or textureReleaseProc
86             multiple times for the same textureContext before calling the other.
87 
88             We call the textureDoneProc when we will no longer call the textureFulfillProc again. We
89             pass in the textureContext as a parameter to the textureDoneProc. We also guarantee that
90             there will be no outstanding textureReleaseProcs that still need to be called when we
91             call the textureDoneProc. Thus when the textureDoneProc gets called the client is able
92             to cleanup all GPU objects and meta data needed for the textureFulfill call.
93 
94         When delayReleaseCallback is kYes:
95             When all the following are true:
96                 * the promise image is deleted,
97                 * any SkDeferredDisplayLists that recorded draws referencing the image are deleted,
98                 * and the texture is safe to delete in the underlying API with respect to drawn
99                   SkDeferredDisplayLists that reference the image
100             the textureReleaseProc and then textureDoneProc are called. The texture can be deleted
101             by the client as soon as textureReleaseProc is called. In this mode there is only one
102             call to each of textureFulfillProc, textureReleaseProc, and textureDoneProc.
103 
104 
105         This call is only valid if the SkDeferredDisplayListRecorder is backed by a gpu context.
106 
107         @param backendFormat       format of promised gpu texture
108         @param width               width of promised gpu texture
109         @param height              height of promised gpu texture
110         @param mipMapped           mip mapped state of promised gpu texture
111         @param origin              one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
112         @param colorType           one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
113                                    kRGB_565_SkColorType, kARGB_4444_SkColorType,
114                                    kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
115                                    kGray_8_SkColorType, kRGBA_F16_SkColorType
116         @param alphaType           one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType,
117                                    kPremul_SkAlphaType, kUnpremul_SkAlphaType
118         @param colorSpace          range of colors; may be nullptr
119         @param textureFulfillProc  function called to get actual gpu texture
120         @param textureReleaseProc  function called when texture can be released
121         @param promiseDoneProc     function called when we will no longer call textureFulfillProc
122         @param textureContext      state passed to textureFulfillProc and textureReleaseProc
123         @return                    created SkImage, or nullptr
124      */
125     sk_sp<SkImage> makePromiseTexture(const GrBackendFormat& backendFormat,
126                                       int width,
127                                       int height,
128                                       GrMipMapped mipMapped,
129                                       GrSurfaceOrigin origin,
130                                       SkColorType colorType,
131                                       SkAlphaType alphaType,
132                                       sk_sp<SkColorSpace> colorSpace,
133                                       PromiseImageTextureFulfillProc textureFulfillProc,
134                                       PromiseImageTextureReleaseProc textureReleaseProc,
135                                       PromiseImageTextureDoneProc textureDoneProc,
136                                       PromiseImageTextureContext textureContext,
137                                       DelayReleaseCallback delayReleaseCallback);
138 
139     /** Deprecated version that assumes DelayReleaseCallback::kNo. */
makePromiseTexture(const GrBackendFormat & backendFormat,int width,int height,GrMipMapped mipMapped,GrSurfaceOrigin origin,SkColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,PromiseImageTextureFulfillProc textureFulfillProc,PromiseImageTextureReleaseProc textureReleaseProc,PromiseImageTextureDoneProc textureDoneProc,PromiseImageTextureContext textureContext)140     sk_sp<SkImage> makePromiseTexture(const GrBackendFormat& backendFormat,
141                                       int width,
142                                       int height,
143                                       GrMipMapped mipMapped,
144                                       GrSurfaceOrigin origin,
145                                       SkColorType colorType,
146                                       SkAlphaType alphaType,
147                                       sk_sp<SkColorSpace> colorSpace,
148                                       PromiseImageTextureFulfillProc textureFulfillProc,
149                                       PromiseImageTextureReleaseProc textureReleaseProc,
150                                       PromiseImageTextureDoneProc textureDoneProc,
151                                       PromiseImageTextureContext textureContext) {
152         return this->makePromiseTexture(backendFormat, width, height, mipMapped, origin, colorType,
153                                         alphaType, colorSpace, textureFulfillProc,
154                                         textureReleaseProc, textureDoneProc, textureContext,
155                                         DelayReleaseCallback::kNo);
156     }
157 
158     /**
159         This entry point operates the same as 'makePromiseTexture' except that its
160         textureFulfillProc can be called up to four times to fetch the required YUVA
161         planes (passing a different textureContext to each call). So, if the 'yuvaIndices'
162         indicate that only the first two backend textures are used, 'textureFulfillProc' will
163         be called with the first two 'textureContexts'.
164      */
165     sk_sp<SkImage> makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,
166                                           const GrBackendFormat yuvaFormats[],
167                                           const SkISize yuvaSizes[],
168                                           const SkYUVAIndex yuvaIndices[4],
169                                           int imageWidth,
170                                           int imageHeight,
171                                           GrSurfaceOrigin imageOrigin,
172                                           sk_sp<SkColorSpace> imageColorSpace,
173                                           PromiseImageTextureFulfillProc textureFulfillProc,
174                                           PromiseImageTextureReleaseProc textureReleaseProc,
175                                           PromiseImageTextureDoneProc textureDoneProc,
176                                           PromiseImageTextureContext textureContexts[],
177                                           DelayReleaseCallback delayReleaseCallback);
178 
179     /** Deprecated version that assumes DelayReleaseCallback::kNo. */
makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,const GrBackendFormat yuvaFormats[],const SkISize yuvaSizes[],const SkYUVAIndex yuvaIndices[4],int imageWidth,int imageHeight,GrSurfaceOrigin imageOrigin,sk_sp<SkColorSpace> imageColorSpace,PromiseImageTextureFulfillProc textureFulfillProc,PromiseImageTextureReleaseProc textureReleaseProc,PromiseImageTextureDoneProc textureDoneProc,PromiseImageTextureContext textureContexts[])180     sk_sp<SkImage> makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,
181                                           const GrBackendFormat yuvaFormats[],
182                                           const SkISize yuvaSizes[],
183                                           const SkYUVAIndex yuvaIndices[4],
184                                           int imageWidth,
185                                           int imageHeight,
186                                           GrSurfaceOrigin imageOrigin,
187                                           sk_sp<SkColorSpace> imageColorSpace,
188                                           PromiseImageTextureFulfillProc textureFulfillProc,
189                                           PromiseImageTextureReleaseProc textureReleaseProc,
190                                           PromiseImageTextureDoneProc textureDoneProc,
191                                           PromiseImageTextureContext textureContexts[]) {
192         return this->makeYUVAPromiseTexture(
193                 yuvColorSpace, yuvaFormats, yuvaSizes, yuvaIndices, imageWidth, imageHeight,
194                 imageOrigin, std::move(imageColorSpace), textureFulfillProc, textureReleaseProc,
195                 textureDoneProc, textureContexts, DelayReleaseCallback::kNo);
196     }
197 
198 private:
199     bool init();
200 
201     const SkSurfaceCharacterization             fCharacterization;
202 
203 #if SK_SUPPORT_GPU
204     sk_sp<GrContext>                            fContext;
205     sk_sp<SkDeferredDisplayList::LazyProxyData> fLazyProxyData;
206     sk_sp<SkSurface>                            fSurface;
207 #endif
208 };
209 
210 #endif
211