• 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     /**
62         Create a new SkImage that is very similar to an SkImage created by MakeFromTexture. The main
63         difference is that the client doesn't have the backend texture on the gpu yet but they know
64         all the properties of the texture. So instead of passing in a GrBackendTexture the client
65         supplies a GrBackendFormat, width, height, and GrMipMapped state.
66 
67         When we actually send the draw calls to the GPU, we will call the textureFulfillProc and
68         the client will return a GrBackendTexture to us. The properties of the GrBackendTexture must
69         match those set during the SkImage creation, and it must have a valid backend gpu texture.
70         The gpu texture supplied by the client must stay valid until we call the textureReleaseProc.
71 
72         When all the following are true:
73             * the promise image is deleted,
74             * any SkDeferredDisplayLists that recorded draws referencing the image are deleted,
75             * and the texture is safe to delete in the underlying API with respect to drawn
76               SkDeferredDisplayLists that reference the image
77         the textureReleaseProc and then textureDoneProc are called. The texture can be deleted
78         by the client as soon as textureReleaseProc is called. There is at most one call to each of
79         textureFulfillProc, textureReleaseProc, and textureDoneProc. textureDoneProc is always
80         called even if image creation fails or if the image is never fulfilled (e.g. it is never
81         drawn). If textureFulfillProc is called then textureReleaseProc will always be called even
82         if textureFulfillProc fails.
83 
84 
85         This call is only valid if the SkDeferredDisplayListRecorder is backed by a gpu context.
86 
87         @param backendFormat       format of promised gpu texture
88         @param width               width of promised gpu texture
89         @param height              height of promised gpu texture
90         @param mipMapped           mip mapped state of promised gpu texture
91         @param origin              one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
92         @param colorType           one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
93                                    kRGB_565_SkColorType, kARGB_4444_SkColorType,
94                                    kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
95                                    kGray_8_SkColorType, kRGBA_F16_SkColorType
96         @param alphaType           one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType,
97                                    kPremul_SkAlphaType, kUnpremul_SkAlphaType
98         @param colorSpace          range of colors; may be nullptr
99         @param textureFulfillProc  function called to get actual gpu texture
100         @param textureReleaseProc  function called when texture can be released
101         @param promiseDoneProc     function called when we will no longer call textureFulfillProc
102         @param textureContext      state passed to textureFulfillProc and textureReleaseProc
103         @return                    created SkImage, or nullptr
104      */
105     sk_sp<SkImage> makePromiseTexture(const GrBackendFormat& backendFormat,
106                                       int width,
107                                       int height,
108                                       GrMipMapped mipMapped,
109                                       GrSurfaceOrigin origin,
110                                       SkColorType colorType,
111                                       SkAlphaType alphaType,
112                                       sk_sp<SkColorSpace> colorSpace,
113                                       PromiseImageTextureFulfillProc textureFulfillProc,
114                                       PromiseImageTextureReleaseProc textureReleaseProc,
115                                       PromiseImageTextureDoneProc textureDoneProc,
116                                       PromiseImageTextureContext textureContext);
117 
118     /**
119         This entry point operates the same as 'makePromiseTexture' except that its
120         textureFulfillProc can be called up to four times to fetch the required YUVA
121         planes (passing a different textureContext to each call). So, if the 'yuvaIndices'
122         indicate that only the first two backend textures are used, 'textureFulfillProc' will
123         be called with the first two 'textureContexts'.
124      */
125     sk_sp<SkImage> makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,
126                                           const GrBackendFormat yuvaFormats[],
127                                           const SkISize yuvaSizes[],
128                                           const SkYUVAIndex yuvaIndices[4],
129                                           int imageWidth,
130                                           int imageHeight,
131                                           GrSurfaceOrigin imageOrigin,
132                                           sk_sp<SkColorSpace> imageColorSpace,
133                                           PromiseImageTextureFulfillProc textureFulfillProc,
134                                           PromiseImageTextureReleaseProc textureReleaseProc,
135                                           PromiseImageTextureDoneProc textureDoneProc,
136                                           PromiseImageTextureContext textureContexts[]);
137 
138 private:
139     bool init();
140 
141     const SkSurfaceCharacterization             fCharacterization;
142 
143 #if SK_SUPPORT_GPU
144     sk_sp<GrContext>                            fContext;
145     sk_sp<SkDeferredDisplayList::LazyProxyData> fLazyProxyData;
146     sk_sp<SkSurface>                            fSurface;
147 #endif
148 };
149 
150 #endif
151