1 /* 2 * Copyright 2021 Google LLC 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 skgpu_graphite_Recorder_DEFINED 9 #define skgpu_graphite_Recorder_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkSize.h" 13 #include "include/gpu/graphite/GraphiteTypes.h" 14 #include "include/gpu/graphite/Recording.h" 15 #include "include/private/base/SingleOwner.h" 16 17 #include <vector> 18 19 class SkCanvas; 20 struct SkImageInfo; 21 class SkPixmap; 22 23 namespace skgpu { 24 class TokenTracker; 25 } 26 27 namespace sktext::gpu { 28 class StrikeCache; 29 class TextBlobRedrawCoordinator; 30 } 31 32 namespace skgpu::graphite { 33 34 class AtlasManager; 35 class BackendTexture; 36 class Caps; 37 class Context; 38 class Device; 39 class DrawBufferManager; 40 class GlobalCache; 41 class ImageProvider; 42 class RecorderPriv; 43 class ResourceProvider; 44 class RuntimeEffectDictionary; 45 class SharedContext; 46 class Task; 47 class TaskGraph; 48 class TextureDataBlock; 49 class TextureInfo; 50 class UniformDataBlock; 51 class UploadBufferManager; 52 53 template<typename T> class PipelineDataCache; 54 using UniformDataCache = PipelineDataCache<UniformDataBlock>; 55 using TextureDataCache = PipelineDataCache<TextureDataBlock>; 56 57 struct SK_API RecorderOptions final { 58 RecorderOptions(); 59 RecorderOptions(const RecorderOptions&); 60 ~RecorderOptions(); 61 62 sk_sp<ImageProvider> fImageProvider; 63 }; 64 65 class SK_API Recorder final { 66 public: 67 Recorder(const Recorder&) = delete; 68 Recorder(Recorder&&) = delete; 69 Recorder& operator=(const Recorder&) = delete; 70 Recorder& operator=(Recorder&&) = delete; 71 72 ~Recorder(); 73 74 std::unique_ptr<Recording> snap(); 75 clientImageProvider()76 ImageProvider* clientImageProvider() { return fClientImageProvider.get(); } clientImageProvider()77 const ImageProvider* clientImageProvider() const { return fClientImageProvider.get(); } 78 79 /** 80 * Creates a new backend gpu texture matching the dimensions and TextureInfo. If an invalid 81 * TextureInfo or a TextureInfo Skia can't support is passed in, this will return an invalid 82 * BackendTexture. Thus the client should check isValid on the returned BackendTexture to know 83 * if it succeeded or not. 84 * 85 * If this does return a valid BackendTexture, the caller is required to use 86 * Recorder::deleteBackendTexture or Context::deleteBackendTexture to delete the texture. It is 87 * safe to use the Context that created this Recorder or any other Recorder created from the 88 * same Context to call deleteBackendTexture. 89 */ 90 BackendTexture createBackendTexture(SkISize dimensions, const TextureInfo&); 91 92 /** 93 * If possible, updates a backend texture with the provided pixmap data. The client 94 * should check the return value to see if the update was successful. The client is required 95 * to insert a Recording into the Context and call `submit` to send the upload work to the gpu. 96 * The backend texture must be compatible with the provided pixmap(s). Compatible, in this case, 97 * means that the backend format is compatible with the base pixmap's colortype. The src data 98 * can be deleted when this call returns. 99 * If the backend texture is mip mapped, the data for all the mipmap levels must be provided. 100 * In the mipmapped case all the colortypes of the provided pixmaps must be the same. 101 * Additionally, all the miplevels must be sized correctly (please see 102 * SkMipmap::ComputeLevelSize and ComputeLevelCount). 103 * Note: the pixmap's alphatypes and colorspaces are ignored. 104 * For the Vulkan backend after a successful update the layout of the created VkImage will be: 105 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL 106 */ 107 bool updateBackendTexture(const BackendTexture&, 108 const SkPixmap srcData[], 109 int numLevels); 110 111 /** 112 * Called to delete the passed in BackendTexture. This should only be called if the 113 * BackendTexture was created by calling Recorder::createBackendTexture on a Recorder that is 114 * associated with the same Context. If the BackendTexture is not valid or does not match the 115 * BackendApi of the Recorder then nothing happens. 116 * 117 * Otherwise this will delete/release the backend object that is wrapped in the BackendTexture. 118 * The BackendTexture will be reset to an invalid state and should not be used again. 119 */ 120 void deleteBackendTexture(BackendTexture&); 121 122 // Returns a canvas that will record to a proxy surface, which must be instantiated on replay. 123 // This can only be called once per Recording; subsequent calls will return null until a 124 // Recording is snapped. Additionally, the returned SkCanvas is only valid until the next 125 // Recording snap, at which point it is deleted. 126 SkCanvas* makeDeferredCanvas(const SkImageInfo&, const TextureInfo&); 127 128 // Provides access to functions that aren't part of the public API. 129 RecorderPriv priv(); 130 const RecorderPriv priv() const; // NOLINT(readability-const-return-type) 131 132 #if GR_TEST_UTILS 133 bool deviceIsRegistered(Device*); 134 #endif 135 136 private: 137 friend class Context; // For ctor 138 friend class Device; // For registering and deregistering Devices; 139 friend class RecorderPriv; // for ctor and hidden methods 140 141 Recorder(sk_sp<SharedContext>, const RecorderOptions&); 142 singleOwner()143 SingleOwner* singleOwner() const { return &fSingleOwner; } 144 145 BackendApi backend() const; 146 147 // We keep track of all Devices that are connected to a Recorder. This allows the client to 148 // safely delete an SkSurface or a Recorder in any order. If the client deletes the Recorder 149 // we need to notify all Devices that the Recorder is no longer valid. If we delete the 150 // SkSurface/Device first we will flush all the Device's into the Recorder before deregistering 151 // it from the Recorder. 152 // 153 // We do not need to take a ref on the Device since the Device will flush and deregister itself 154 // in its dtor. There is no other need for the Recorder to know about the Device after this 155 // point. 156 // 157 // Note: We could probably get by with only registering Devices directly connected to 158 // SkSurfaces. All other one off Devices will be created in a controlled scope where the 159 // Recorder should still be valid by the time they need to flush their work when the Device is 160 // deleted. We would have to make sure we safely handle cases where a client calls saveLayer 161 // then either deletes the SkSurface or Recorder before calling restore. For simplicity we just 162 // register every device for now, but if we see extra overhead in pushing back the extra 163 // pointers, we can look into only registering SkSurface Devices. 164 void registerDevice(Device*); 165 void deregisterDevice(const Device*); 166 167 sk_sp<SharedContext> fSharedContext; 168 std::unique_ptr<ResourceProvider> fResourceProvider; 169 std::unique_ptr<RuntimeEffectDictionary> fRuntimeEffectDict; 170 171 std::unique_ptr<TaskGraph> fGraph; 172 std::unique_ptr<UniformDataCache> fUniformDataCache; 173 std::unique_ptr<TextureDataCache> fTextureDataCache; 174 std::unique_ptr<DrawBufferManager> fDrawBufferManager; 175 std::unique_ptr<UploadBufferManager> fUploadBufferManager; 176 std::vector<Device*> fTrackedDevices; 177 178 uint32_t fRecorderID; // Needed for MessageBox handling for text 179 std::unique_ptr<AtlasManager> fAtlasManager; 180 std::unique_ptr<TokenTracker> fTokenTracker; 181 std::unique_ptr<sktext::gpu::StrikeCache> fStrikeCache; 182 std::unique_ptr<sktext::gpu::TextBlobRedrawCoordinator> fTextBlobCache; 183 sk_sp<ImageProvider> fClientImageProvider; 184 185 // In debug builds we guard against improper thread handling 186 // This guard is passed to the ResourceCache. 187 // TODO: Should we also pass this to Device, DrawContext, and similar classes? 188 mutable SingleOwner fSingleOwner; 189 190 sk_sp<Device> fTargetProxyDevice; 191 std::unique_ptr<SkCanvas> fTargetProxyCanvas; 192 std::unique_ptr<Recording::LazyProxyData> fTargetProxyData; 193 194 #if GRAPHITE_TEST_UTILS 195 // For testing use only -- the Context used to create this Recorder 196 Context* fContext = nullptr; 197 #endif 198 }; 199 200 } // namespace skgpu::graphite 201 202 #endif // skgpu_graphite_Recorder_DEFINED 203