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