Flutter Engine
The Flutter Engine
Recorder.h
Go to the documentation of this file.
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
12#include "include/core/SkSize.h"
17
18#include <chrono>
19
20struct AHardwareBuffer;
21class SkCanvas;
22struct SkImageInfo;
23class SkPixmap;
25
26namespace skgpu {
27class RefCntedCallback;
28class TokenTracker;
29}
30
31namespace sktext::gpu {
32class StrikeCache;
34}
35
36namespace skgpu::graphite {
37
38class AtlasProvider;
39class BackendTexture;
40class Caps;
41class Context;
42class Device;
43class DrawBufferManager;
44class GlobalCache;
45class ImageProvider;
46class ProxyCache;
47class ProxyReadCountMap;
48class RecorderPriv;
50class RuntimeEffectDictionary;
51class SharedContext;
52class Task;
53class TaskList;
54class TextureDataBlock;
55class TextureInfo;
56class UniformDataBlock;
57class UploadBufferManager;
58
59template<typename T> class PipelineDataCache;
62
63struct SK_API RecorderOptions final {
67
69
70 static constexpr size_t kDefaultRecorderBudget = 256 * (1 << 20);
71 // What is the budget for GPU resources allocated and held by this Recorder.
72 size_t fGpuBudgetInBytes = kDefaultRecorderBudget;
73};
74
75class SK_API Recorder final {
76public:
77 Recorder(const Recorder&) = delete;
78 Recorder(Recorder&&) = delete;
79 Recorder& operator=(const Recorder&) = delete;
81
82 ~Recorder();
83
84 BackendApi backend() const;
85
86 std::unique_ptr<Recording> snap();
87
88 ImageProvider* clientImageProvider() { return fClientImageProvider.get(); }
89 const ImageProvider* clientImageProvider() const { return fClientImageProvider.get(); }
90
91 /**
92 * Creates a new backend gpu texture matching the dimensions and TextureInfo. If an invalid
93 * TextureInfo or a TextureInfo Skia can't support is passed in, this will return an invalid
94 * BackendTexture. Thus the client should check isValid on the returned BackendTexture to know
95 * if it succeeded or not.
96 *
97 * If this does return a valid BackendTexture, the caller is required to use
98 * Recorder::deleteBackendTexture or Context::deleteBackendTexture to delete the texture. It is
99 * safe to use the Context that created this Recorder or any other Recorder created from the
100 * same Context to call deleteBackendTexture.
101 */
102 BackendTexture createBackendTexture(SkISize dimensions, const TextureInfo&);
103
104#ifdef SK_BUILD_FOR_ANDROID
105 BackendTexture createBackendTexture(AHardwareBuffer*,
106 bool isRenderable,
107 bool isProtectedContent,
108 SkISize dimensions,
109 bool fromAndroidWindow = false) const;
110#endif
111
112 /**
113 * If possible, updates a backend texture with the provided pixmap data. The client
114 * should check the return value to see if the update was successful. The client is required
115 * to insert a Recording into the Context and call `submit` to send the upload work to the gpu.
116 * The backend texture must be compatible with the provided pixmap(s). Compatible, in this case,
117 * means that the backend format is compatible with the base pixmap's colortype. The src data
118 * can be deleted when this call returns.
119 * If the backend texture is mip mapped, the data for all the mipmap levels must be provided.
120 * In the mipmapped case all the colortypes of the provided pixmaps must be the same.
121 * Additionally, all the miplevels must be sized correctly (please see
122 * SkMipmap::ComputeLevelSize and ComputeLevelCount).
123 * Note: the pixmap's alphatypes and colorspaces are ignored.
124 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
125 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
126 */
127 bool updateBackendTexture(const BackendTexture&,
128 const SkPixmap srcData[],
129 int numLevels);
130
131 /**
132 * If possible, updates a compressed backend texture filled with the provided raw data. The
133 * client should check the return value to see if the update was successful. The client is
134 * required to insert a Recording into the Context and call `submit` to send the upload work to
135 * the gpu.
136 * If the backend texture is mip mapped, the data for all the mipmap levels must be provided.
137 * Additionally, all the miplevels must be sized correctly (please see
138 * SkMipMap::ComputeLevelSize and ComputeLevelCount).
139 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
140 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
141 */
142 bool updateCompressedBackendTexture(const BackendTexture&,
143 const void* data,
144 size_t dataSize);
145
146 /**
147 * Called to delete the passed in BackendTexture. This should only be called if the
148 * BackendTexture was created by calling Recorder::createBackendTexture on a Recorder that is
149 * associated with the same Context. If the BackendTexture is not valid or does not match the
150 * BackendApi of the Recorder then nothing happens.
151 *
152 * Otherwise this will delete/release the backend object that is wrapped in the BackendTexture.
153 * The BackendTexture will be reset to an invalid state and should not be used again.
154 */
155 void deleteBackendTexture(const BackendTexture&);
156
157 // Adds a proc that will be moved to the Recording upon snap, subsequently attached to the
158 // CommandBuffer when the Recording is added, and called when that CommandBuffer is submitted
159 // and finishes. If the Recorder or Recording is deleted before the proc is added to the
160 // CommandBuffer, it will be called with result Failure.
161 void addFinishInfo(const InsertFinishInfo&);
162
163 // Returns a canvas that will record to a proxy surface, which must be instantiated on replay.
164 // This can only be called once per Recording; subsequent calls will return null until a
165 // Recording is snapped. Additionally, the returned SkCanvas is only valid until the next
166 // Recording snap, at which point it is deleted.
167 SkCanvas* makeDeferredCanvas(const SkImageInfo&, const TextureInfo&);
168
169 /**
170 * Frees GPU resources created and held by the Recorder. Can be called to reduce GPU memory
171 * pressure. Any resources that are still in use (e.g. being used by work submitted to the GPU)
172 * will not be deleted by this call. If the caller wants to make sure all resources are freed,
173 * then they should first make sure to submit and wait on any outstanding work.
174 */
175 void freeGpuResources();
176
177 /**
178 * Purge GPU resources on the Recorder that haven't been used in the past 'msNotUsed'
179 * milliseconds or are otherwise marked for deletion, regardless of whether the context is under
180 * budget.
181 */
182 void performDeferredCleanup(std::chrono::milliseconds msNotUsed);
183
184 /**
185 * Returns the number of bytes of the Recorder's gpu memory cache budget that are currently in
186 * use.
187 */
188 size_t currentBudgetedBytes() const;
189
190 /**
191 * Returns the size of Recorder's gpu memory cache budget in bytes.
192 */
193 size_t maxBudgetedBytes() const;
194
195 /**
196 * Enumerates all cached GPU resources owned by the Recorder and dumps their memory to
197 * traceMemoryDump.
198 */
199 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
200
201 // Provides access to functions that aren't part of the public API.
203 const RecorderPriv priv() const; // NOLINT(readability-const-return-type)
204
205private:
206 friend class Context; // For ctor
207 friend class Device; // For registering and deregistering Devices;
208 friend class RecorderPriv; // for ctor and hidden methods
209
210 // If Context is non-null, the Recorder will use the Context's resource provider
211 // instead of creating its own.
213
214 SingleOwner* singleOwner() const { return &fSingleOwner; }
215
216 // We keep track of all Devices that are connected to a Recorder. This allows the client to
217 // safely delete an SkSurface or a Recorder in any order. If the client deletes the Recorder
218 // we need to notify all Devices that the Recorder is no longer valid. If we delete the
219 // SkSurface/Device first we will flush all the Device's into the Recorder before deregistering
220 // it from the Recorder.
221 //
222 // We take a ref on the Device so that ~Device() does not have to deregister the recorder
223 // (which can happen on any thread if the Device outlives the Surface via an Image view).
224 // Recorder::flushTrackedDevices() cleans up uniquely held and immutable Devices on the recorder
225 // thread so this extra ref is not significantly increasing the Device lifetime.
226 //
227 // Note: We could probably get by with only registering Devices directly connected to
228 // SkSurfaces. All other one off Devices will be created in a controlled scope where the
229 // Recorder should still be valid by the time they need to flush their work when the Device is
230 // deleted. We would have to make sure we safely handle cases where a client calls saveLayer
231 // then either deletes the SkSurface or Recorder before calling restore. For simplicity we just
232 // register every device for now, but if we see extra overhead in pushing back the extra
233 // pointers, we can look into only registering SkSurface Devices.
234 void registerDevice(sk_sp<Device>);
235 void deregisterDevice(const Device*);
236
237 sk_sp<SharedContext> fSharedContext;
238 ResourceProvider* fResourceProvider; // May point to the Context's resource provider
239 std::unique_ptr<ResourceProvider> fOwnedResourceProvider; // May be null
240 std::unique_ptr<RuntimeEffectDictionary> fRuntimeEffectDict;
241
242 // NOTE: These are stored by pointer to allow them to be forward declared.
243 std::unique_ptr<TaskList> fRootTaskList;
244 std::unique_ptr<UniformDataCache> fUniformDataCache;
245 std::unique_ptr<TextureDataCache> fTextureDataCache;
246 std::unique_ptr<DrawBufferManager> fDrawBufferManager;
247 std::unique_ptr<UploadBufferManager> fUploadBufferManager;
248 std::unique_ptr<ProxyReadCountMap> fProxyReadCounts;
249
250 // Iterating over tracked devices in flushTrackedDevices() needs to be re-entrant and support
251 // additions to fTrackedDevices if registerDevice() is triggered by a temporary device during
252 // flushing. Removals are handled by setting elements to null; final clean up is handled at the
253 // end of the initial call to flushTrackedDevices().
254 skia_private::TArray<sk_sp<Device>> fTrackedDevices;
255 int fFlushingDevicesIndex = -1;
256
257 uint32_t fUniqueID; // Needed for MessageBox handling for text
258 uint32_t fNextRecordingID = 1;
259 std::unique_ptr<AtlasProvider> fAtlasProvider;
260 std::unique_ptr<TokenTracker> fTokenTracker;
261 std::unique_ptr<sktext::gpu::StrikeCache> fStrikeCache;
262 std::unique_ptr<sktext::gpu::TextBlobRedrawCoordinator> fTextBlobCache;
263 sk_sp<ImageProvider> fClientImageProvider;
264
265 // In debug builds we guard against improper thread handling
266 // This guard is passed to the ResourceCache.
267 // TODO: Should we also pass this to Device, DrawContext, and similar classes?
268 mutable SingleOwner fSingleOwner;
269
270 sk_sp<Device> fTargetProxyDevice;
271 std::unique_ptr<SkCanvas> fTargetProxyCanvas;
272 std::unique_ptr<Recording::LazyProxyData> fTargetProxyData;
273
275
276#if defined(GRAPHITE_TEST_UTILS)
277 // For testing use only -- the Context used to create this Recorder
278 Context* fContext = nullptr;
279#endif
280};
281
282} // namespace skgpu::graphite
283
284#endif // skgpu_graphite_Recorder_DEFINED
const char * backend
struct AHardwareBuffer AHardwareBuffer
#define SK_API
Definition: SkAPI.h:35
const Context & fContext
Recorder(Recorder &&)=delete
Recorder & operator=(Recorder &&)=delete
const ImageProvider * clientImageProvider() const
Definition: Recorder.h:89
ImageProvider * clientImageProvider()
Definition: Recorder.h:88
Recorder(const Recorder &)=delete
Recorder & operator=(const Recorder &)=delete
FlPixelBufferTexturePrivate * priv
Definition: GpuTools.h:21
BackendApi
Definition: GpuTypes.h:22
Definition: SkSize.h:16
Definition: DM.cpp:1161
RecorderOptions(const RecorderOptions &)
sk_sp< ImageProvider > fImageProvider
Definition: Recorder.h:68
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
skgpu::graphite::Recorder Recorder