Flutter Engine
The Flutter Engine
Context.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_Context_DEFINED
9#define skgpu_graphite_Context_DEFINED
10
18
19#include <chrono>
20#include <functional>
21#include <memory>
22
23class SkColorSpace;
24class SkRuntimeEffect;
26
27namespace skgpu::graphite {
28
29class BackendTexture;
30class Buffer;
31class ClientMappedBufferManager;
32class Context;
33class ContextPriv;
34class GlobalCache;
35class PaintOptions;
36class PlotUploadTracker;
37class QueueManager;
38class Recording;
40class SharedContext;
41class TextureProxy;
42
43class SK_API Context final {
44public:
45 Context(const Context&) = delete;
46 Context(Context&&) = delete;
47 Context& operator=(const Context&) = delete;
49
50 ~Context();
51
52 BackendApi backend() const;
53
54 std::unique_ptr<Recorder> makeRecorder(const RecorderOptions& = {});
55
56 bool insertRecording(const InsertRecordingInfo&);
57 bool submit(SyncToCpu = SyncToCpu::kNo);
58
59 /** Returns true if there is work that was submitted to the GPU that has not finished. */
60 bool hasUnfinishedGpuWork() const;
61
62 void asyncRescaleAndReadPixels(const SkImage* image,
63 const SkImageInfo& dstImageInfo,
64 const SkIRect& srcRect,
65 SkImage::RescaleGamma rescaleGamma,
66 SkImage::RescaleMode rescaleMode,
69
70 void asyncRescaleAndReadPixels(const SkSurface* surface,
71 const SkImageInfo& dstImageInfo,
72 const SkIRect& srcRect,
73 SkImage::RescaleGamma rescaleGamma,
74 SkImage::RescaleMode rescaleMode,
77
78 void asyncRescaleAndReadPixelsYUV420(const SkImage*,
79 SkYUVColorSpace yuvColorSpace,
80 sk_sp<SkColorSpace> dstColorSpace,
81 const SkIRect& srcRect,
82 const SkISize& dstSize,
83 SkImage::RescaleGamma rescaleGamma,
84 SkImage::RescaleMode rescaleMode,
87
88 void asyncRescaleAndReadPixelsYUV420(const SkSurface*,
89 SkYUVColorSpace yuvColorSpace,
90 sk_sp<SkColorSpace> dstColorSpace,
91 const SkIRect& srcRect,
92 const SkISize& dstSize,
93 SkImage::RescaleGamma rescaleGamma,
94 SkImage::RescaleMode rescaleMode,
97
98 void asyncRescaleAndReadPixelsYUVA420(const SkImage*,
99 SkYUVColorSpace yuvColorSpace,
100 sk_sp<SkColorSpace> dstColorSpace,
101 const SkIRect& srcRect,
102 const SkISize& dstSize,
103 SkImage::RescaleGamma rescaleGamma,
104 SkImage::RescaleMode rescaleMode,
107
108 void asyncRescaleAndReadPixelsYUVA420(const SkSurface*,
109 SkYUVColorSpace yuvColorSpace,
110 sk_sp<SkColorSpace> dstColorSpace,
111 const SkIRect& srcRect,
112 const SkISize& dstSize,
113 SkImage::RescaleGamma rescaleGamma,
114 SkImage::RescaleMode rescaleMode,
117
118 /**
119 * Checks whether any asynchronous work is complete and if so calls related callbacks.
120 */
121 void checkAsyncWorkCompletion();
122
123 /**
124 * Called to delete the passed in BackendTexture. This should only be called if the
125 * BackendTexture was created by calling Recorder::createBackendTexture on a Recorder created
126 * from this Context. If the BackendTexture is not valid or does not match the BackendApi of the
127 * Context then nothing happens.
128 *
129 * Otherwise this will delete/release the backend object that is wrapped in the BackendTexture.
130 * The BackendTexture will be reset to an invalid state and should not be used again.
131 */
132 void deleteBackendTexture(const BackendTexture&);
133
134 /**
135 * Frees GPU resources created and held by the Context. Can be called to reduce GPU memory
136 * pressure. Any resources that are still in use (e.g. being used by work submitted to the GPU)
137 * will not be deleted by this call. If the caller wants to make sure all resources are freed,
138 * then they should first make sure to submit and wait on any outstanding work.
139 */
140 void freeGpuResources();
141
142 /**
143 * Purge GPU resources on the Context that haven't been used in the past 'msNotUsed'
144 * milliseconds or are otherwise marked for deletion, regardless of whether the context is under
145 * budget.
146 */
147 void performDeferredCleanup(std::chrono::milliseconds msNotUsed);
148
149 /**
150 * Returns the number of bytes of the Context's gpu memory cache budget that are currently in
151 * use.
152 */
153 size_t currentBudgetedBytes() const;
154
155 /**
156 * Returns the size of Context's gpu memory cache budget in bytes.
157 */
158 size_t maxBudgetedBytes() const;
159
160 /**
161 * Enumerates all cached GPU resources owned by the Context and dumps their memory to
162 * traceMemoryDump.
163 */
164 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
165
166 /**
167 * Returns true if the backend-specific context has gotten into an unrecoverarble, lost state
168 * (e.g. if we've gotten a VK_ERROR_DEVICE_LOST in the Vulkan backend).
169 */
170 bool isDeviceLost() const;
171
172 /**
173 * Returns the maximum texture dimension supported by the underlying backend.
174 */
175 int maxTextureSize() const;
176
177 /*
178 * Does this context support protected content?
179 */
180 bool supportsProtectedContent() const;
181
182 // Provides access to functions that aren't part of the public API.
184 const ContextPriv priv() const; // NOLINT(readability-const-return-type)
185
186 class ContextID {
187 public:
188 static Context::ContextID Next();
189
191
192 bool operator==(const ContextID& that) const { return fID == that.fID; }
193 bool operator!=(const ContextID& that) const { return !(*this == that); }
194
196 bool isValid() const { return fID != SK_InvalidUniqueID; }
197
198 private:
199 constexpr ContextID(uint32_t id) : fID(id) {}
200 uint32_t fID;
201 };
202
203 ContextID contextID() const { return fContextID; }
204
205protected:
206 Context(sk_sp<SharedContext>, std::unique_ptr<QueueManager>, const ContextOptions&);
207
208private:
209 friend class ContextPriv;
211
212 struct PixelTransferResult {
213 using ConversionFn = void(void* dst, const void* mappedBuffer);
214 // If null then the transfer could not be performed. Otherwise this buffer will contain
215 // the pixel data when the transfer is complete.
216 sk_sp<Buffer> fTransferBuffer;
217 // Size of the read.
218 SkISize fSize;
219 // RowBytes for transfer buffer data
220 size_t fRowBytes;
221 // If this is null then the transfer buffer will contain the data in the requested
222 // color type. Otherwise, when the transfer is done this must be called to convert
223 // from the transfer buffer's color type to the requested color type.
224 std::function<ConversionFn> fPixelConverter;
225 };
226
227 SingleOwner* singleOwner() const { return &fSingleOwner; }
228
229 // Must be called in Make() to handle one-time GPU setup operations that can possibly fail and
230 // require Context::Make() to return a nullptr.
231 bool finishInitialization();
232
233 void checkForFinishedWork(SyncToCpu);
234
235 std::unique_ptr<Recorder> makeInternalRecorder() const;
236
237 template <typename SrcPixels> struct AsyncParams;
238
239 template <typename ReadFn, typename... ExtraArgs>
240 void asyncRescaleAndReadImpl(ReadFn Context::* asyncRead,
241 SkImage::RescaleGamma rescaleGamma,
242 SkImage::RescaleMode rescaleMode,
243 const AsyncParams<SkImage>&,
244 ExtraArgs...);
245
246 // Recorder is optional and will be used if drawing operations are required. If no Recorder is
247 // provided but drawing operations are needed, a new Recorder will be created automatically.
248 void asyncReadPixels(std::unique_ptr<Recorder>, const AsyncParams<SkImage>&);
249 void asyncReadPixelsYUV420(std::unique_ptr<Recorder>,
250 const AsyncParams<SkImage>&,
252
253 // Like asyncReadPixels() except it performs no fallbacks, and requires that the texture be
254 // readable. However, the texture does not need to be sampleable.
255 void asyncReadTexture(std::unique_ptr<Recorder>,
256 const AsyncParams<TextureProxy>&,
257 const SkColorInfo& srcColorInfo);
258
259 // Inserts a texture to buffer transfer task, used by asyncReadPixels methods. If the
260 // Recorder is non-null, tasks will be added to the Recorder's list; otherwise the transfer
261 // tasks will be added to the queue manager directly.
262 PixelTransferResult transferPixels(Recorder*,
263 const TextureProxy* srcProxy,
264 const SkColorInfo& srcColorInfo,
265 const SkColorInfo& dstColorInfo,
266 const SkIRect& srcRect);
267
268 // If the recorder is non-null, it will be snapped and inserted with the assumption that the
269 // copy tasks (and possibly preparatory draw tasks) have already been added to the Recording.
270 void finalizeAsyncReadPixels(std::unique_ptr<Recorder>,
273 SkImage::ReadPixelsContext callbackContext);
274
275 sk_sp<SharedContext> fSharedContext;
276 std::unique_ptr<ResourceProvider> fResourceProvider;
277 std::unique_ptr<QueueManager> fQueueManager;
278 std::unique_ptr<ClientMappedBufferManager> fMappedBufferManager;
279
280 // In debug builds we guard against improper thread handling. This guard is passed to the
281 // ResourceCache for the Context.
282 mutable SingleOwner fSingleOwner;
283
284#if defined(GRAPHITE_TEST_UTILS)
285 // In test builds a Recorder may track the Context that was used to create it.
286 bool fStoreContextRefInRecorder = false;
287 // If this tracking is on, to allow the client to safely delete this Context or its Recorders
288 // in any order we must also track the Recorders created here.
289 std::vector<Recorder*> fTrackedRecorders;
290#endif
291
292 // Needed for MessageBox handling
293 const ContextID fContextID;
294};
295
296} // namespace skgpu::graphite
297
298#endif // skgpu_graphite_Context_DEFINED
const char * backend
#define SK_API
Definition: SkAPI.h:35
SkYUVColorSpace
Definition: SkImageInfo.h:68
static constexpr uint32_t SK_InvalidUniqueID
Definition: SkTypes.h:196
void * ReadPixelsContext
Definition: SkImage.h:578
RescaleMode
Definition: SkImage.h:587
RescaleGamma
Definition: SkImage.h:585
void(ReadPixelsContext, std::unique_ptr< const AsyncReadResult >) ReadPixelsCallback
Definition: SkImage.h:583
bool operator!=(const ContextID &that) const
Definition: Context.h:193
bool operator==(const ContextID &that) const
Definition: Context.h:192
ContextID contextID() const
Definition: Context.h:203
Context & operator=(Context &&)=delete
Context(Context &&)=delete
Context & operator=(const Context &)=delete
Context(const Context &)=delete
VkSurfaceKHR surface
Definition: main.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlPixelBufferTexturePrivate * priv
sk_sp< const SkImage > image
Definition: SkRecords.h:269
dst
Definition: cp.py:12
BackendApi
Definition: GpuTypes.h:22
Definition: SkRect.h:32
Definition: SkSize.h:16
const uintptr_t id