1/*
2 * Copyright 2010 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 GrContext_DEFINED
9#define GrContext_DEFINED
10
11#include "include/core/SkMatrix.h"
12#include "include/core/SkPathEffect.h"
13#include "include/core/SkTypes.h"
14#include "include/gpu/GrBackendSurface.h"
15#include "include/gpu/GrContextOptions.h"
16#include "include/gpu/GrRecordingContext.h"
17
18// We shouldn't need this but currently Android is relying on this being include transitively.
19#include "include/core/SkUnPreMultiply.h"
20
21class GrAtlasManager;
22class GrBackendSemaphore;
23class GrCaps;
24class GrClientMappedBufferManager;
25class GrContextPriv;
26class GrContextThreadSafeProxy;
27struct GrD3DBackendContext;
28class GrFragmentProcessor;
29struct GrGLInterface;
30class GrGpu;
31struct GrMockOptions;
32class GrPath;
33class GrRenderTargetContext;
34class GrResourceCache;
35class GrResourceProvider;
36class GrSmallPathAtlasMgr;
37class GrStrikeCache;
38class GrSurfaceProxy;
39class GrSwizzle;
40class GrTextureProxy;
41struct GrVkBackendContext;
42
43class SkImage;
44class SkString;
45class SkSurfaceCharacterization;
46class SkSurfaceProps;
47class SkTaskGroup;
48class SkTraceMemoryDump;
49
50class SK_API GrContext : public GrRecordingContext {
51public:
52#ifndef SK_DISABLE_LEGACY_CONTEXT_FACTORIES
53
54#ifdef SK_GL
55 /**
56 * Creates a GrContext for a backend context. If no GrGLInterface is provided then the result of
57 * GrGLMakeNativeInterface() is used if it succeeds.
58 */
59 static sk_sp<GrContext> MakeGL(sk_sp<const GrGLInterface>, const GrContextOptions&);
60 static sk_sp<GrContext> MakeGL(sk_sp<const GrGLInterface>);
61 static sk_sp<GrContext> MakeGL(const GrContextOptions&);
62 static sk_sp<GrContext> MakeGL();
63#endif
64
65#ifdef SK_VULKAN
66 /**
67 * The Vulkan context (VkQueue, VkDevice, VkInstance) must be kept alive until the returned
68 * GrContext is destroyed. This also means that any objects created with this GrContext (e.g.
69 * SkSurfaces, SkImages, etc.) must also be released as they may hold refs on the GrContext.
70 * Once all these objects and the GrContext are released, then it is safe to delete the vulkan
71 * objects.
72 */
73 static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext&, const GrContextOptions&);
74 static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext&);
75#endif
76
77#ifdef SK_METAL
78 /**
79 * Makes a GrContext which uses Metal as the backend. The device parameter is an MTLDevice
80 * and queue is an MTLCommandQueue which should be used by the backend. These objects must
81 * have a ref on them which can be transferred to Ganesh which will release the ref when the
82 * GrContext is destroyed.
83 */
84 static sk_sp<GrContext> MakeMetal(void* device, void* queue, const GrContextOptions& options);
85 static sk_sp<GrContext> MakeMetal(void* device, void* queue);
86#endif
87
88#ifdef SK_DIRECT3D
89 /**
90 * Makes a GrContext which uses Direct3D as the backend. The Direct3D context
91 * must be kept alive until the returned GrContext is first destroyed or abandoned.
92 */
93 static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&,
94 const GrContextOptions& options);
95 static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&);
96#endif
97
98#ifdef SK_DAWN
99 static sk_sp<GrContext> MakeDawn(const wgpu::Device& device, const GrContextOptions& options);
100 static sk_sp<GrContext> MakeDawn(const wgpu::Device& device);
101#endif
102
103 static sk_sp<GrContext> MakeMock(const GrMockOptions*, const GrContextOptions&);
104 static sk_sp<GrContext> MakeMock(const GrMockOptions*);
105
106#endif // SK_DISABLE_LEGACY_CONTEXT_FACTORIES
107
108 ~GrContext() override;
109
110 // TODO: Remove this from public after migrating Chrome.
111 sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
112
113 /**
114 * The GrContext normally assumes that no outsider is setting state
115 * within the underlying 3D API's context/device/whatever. This call informs
116 * the context that the state was modified and it should resend. Shouldn't
117 * be called frequently for good performance.
118 * The flag bits, state, is dpendent on which backend is used by the
119 * context, either GL or D3D (possible in future).
120 */
121 void resetContext(uint32_t state = kAll_GrBackendState);
122
123 /**
124 * If the backend is GrBackendApi::kOpenGL, then all texture unit/target combinations for which
125 * the GrContext has modified the bound texture will have texture id 0 bound. This does not
126 * flush the GrContext. Calling resetContext() does not change the set that will be bound
127 * to texture id 0 on the next call to resetGLTextureBindings(). After this is called
128 * all unit/target combinations are considered to have unmodified bindings until the GrContext
129 * subsequently modifies them (meaning if this is called twice in a row with no intervening
130 * GrContext usage then the second call is a no-op.)
131 */
132 void resetGLTextureBindings();
133
134 /**
135 * Abandons all GPU resources and assumes the underlying backend 3D API context is no longer
136 * usable. Call this if you have lost the associated GPU context, and thus internal texture,
137 * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the
138 * GrContext and any of its created resource objects will not make backend 3D API calls. Content
139 * rendered but not previously flushed may be lost. After this function is called all subsequent
140 * calls on the GrContext will fail or be no-ops.
141 *
142 * The typical use case for this function is that the underlying 3D context was lost and further
143 * API calls may crash.
144 *
145 * For Vulkan, even if the device becomes lost, the VkQueue, VkDevice, or VkInstance used to
146 * create the GrContext must be kept alive even after abandoning the context. Those objects must
147 * live for the lifetime of the GrContext object itself. The reason for this is so that
148 * we can continue to delete any outstanding GrBackendTextures/RenderTargets which must be
149 * cleaned up even in a device lost state.
150 */
151 void abandonContext() override;
152
153 /**
154 * Returns true if the context was abandoned or if the if the backend specific context has
155 * gotten into an unrecoverarble, lost state (e.g. in Vulkan backend if we've gotten a
156 * VK_ERROR_DEVICE_LOST). If the backend context is lost, this call will also abandon the
157 * GrContext.
158 */
159 bool abandoned() override;
160
161 /**
162 * Checks if the underlying 3D API reported an out-of-memory error. If this returns true it is
163 * reset and will return false until another out-of-memory error is reported by the 3D API. If
164 * the context is abandoned then this will report false.
165 *
166 * Currently this is implemented for:
167 *
168 * OpenGL [ES] - Note that client calls to glGetError() may swallow GL_OUT_OF_MEMORY errors and
169 * therefore hide the error from Skia. Also, it is not advised to use this in combination with
170 * enabling GrContextOptions::fSkipGLErrorChecks. That option may prevent GrContext from ever
171 * checking the GL context for OOM.
172 *
173 * Vulkan - Reports true if VK_ERROR_OUT_OF_HOST_MEMORY or VK_ERROR_OUT_OF_DEVICE_MEMORY has
174 * occurred.
175 */
176 bool oomed();
177
178 /**
179 * This is similar to abandonContext() however the underlying 3D context is not yet lost and
180 * the GrContext will cleanup all allocated resources before returning. After returning it will
181 * assume that the underlying context may no longer be valid.
182 *
183 * The typical use case for this function is that the client is going to destroy the 3D context
184 * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed
185 * elsewhere by either the client or Skia objects).
186 *
187 * For Vulkan, even if the device becomes lost, the VkQueue, VkDevice, or VkInstance used to
188 * create the GrContext must be alive before calling releaseResourcesAndAbandonContext.
189 */
190 virtual void releaseResourcesAndAbandonContext();
191
192 ///////////////////////////////////////////////////////////////////////////
193 // Resource Cache
194
195 /** DEPRECATED
196 * Return the current GPU resource cache limits.
197 *
198 * @param maxResources If non-null, will be set to -1.
199 * @param maxResourceBytes If non-null, returns maximum number of bytes of
200 * video memory that can be held in the cache.
201 */
202 void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const;
203
204 /**
205 * Return the current GPU resource cache limit in bytes.
206 */
207 size_t getResourceCacheLimit() const;
208
209 /**
210 * Gets the current GPU resource cache usage.
211 *
212 * @param resourceCount If non-null, returns the number of resources that are held in the
213 * cache.
214 * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held
215 * in the cache.
216 */
217 void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
218
219 /**
220 * Gets the number of bytes in the cache consumed by purgeable (e.g. unlocked) resources.
221 */
222 size_t getResourceCachePurgeableBytes() const;
223
224 /** DEPRECATED
225 * Specify the GPU resource cache limits. If the current cache exceeds the maxResourceBytes
226 * limit, it will be purged (LRU) to keep the cache within the limit.
227 *
228 * @param maxResources Unused.
229 * @param maxResourceBytes The maximum number of bytes of video memory
230 * that can be held in the cache.
231 */
232 void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
233
234 /**
235 * Specify the GPU resource cache limit. If the cache currently exceeds this limit,
236 * it will be purged (LRU) to keep the cache within the limit.
237 *
238 * @param maxResourceBytes The maximum number of bytes of video memory
239 * that can be held in the cache.
240 */
241 void setResourceCacheLimit(size_t maxResourceBytes);
242
243 /**
244 * Frees GPU created by the context. Can be called to reduce GPU memory
245 * pressure.
246 */
247 virtual void freeGpuResources();
248
249 /**
250 * Purge GPU resources that haven't been used in the past 'msNotUsed' milliseconds or are
251 * otherwise marked for deletion, regardless of whether the context is under budget.
252 */
253 void performDeferredCleanup(std::chrono::milliseconds msNotUsed);
254
255 // Temporary compatibility API for Android.
256 void purgeResourcesNotUsedInMs(std::chrono::milliseconds msNotUsed) {
257 this->performDeferredCleanup(msNotUsed);
258 }
259
260 /**
261 * Purge unlocked resources from the cache until the the provided byte count has been reached
262 * or we have purged all unlocked resources. The default policy is to purge in LRU order, but
263 * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other
264 * resource types.
265 *
266 * @param maxBytesToPurge the desired number of bytes to be purged.
267 * @param preferScratchResources If true scratch resources will be purged prior to other
268 * resource types.
269 */
270 void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources);
271
272 /**
273 * This entry point is intended for instances where an app has been backgrounded or
274 * suspended.
275 * If 'scratchResourcesOnly' is true all unlocked scratch resources will be purged but the
276 * unlocked resources with persistent data will remain. If 'scratchResourcesOnly' is false
277 * then all unlocked resources will be purged.
278 * In either case, after the unlocked resources are purged a separate pass will be made to
279 * ensure that resource usage is under budget (i.e., even if 'scratchResourcesOnly' is true
280 * some resources with persistent data may be purged to be under budget).
281 *
282 * @param scratchResourcesOnly If true only unlocked scratch resources will be purged prior
283 * enforcing the budget requirements.
284 */
285 void purgeUnlockedResources(bool scratchResourcesOnly);
286
287 /**
288 * Gets the maximum supported texture size.
289 */
290 int maxTextureSize() const;
291
292 /**
293 * Gets the maximum supported render target size.
294 */
295 int maxRenderTargetSize() const;
296
297 /**
298 * Can a SkImage be created with the given color type.
299 */
300 bool colorTypeSupportedAsImage(SkColorType) const;
301
302 /**
303 * Can a SkSurface be created with the given color type. To check whether MSAA is supported
304 * use maxSurfaceSampleCountForColorType().
305 */
306 using GrRecordingContext::colorTypeSupportedAsSurface;
307
308 /**
309 * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA
310 * rendering is supported for the color type. 0 is returned if rendering to this color type
311 * is not supported at all.
312 */
313 using GrRecordingContext::maxSurfaceSampleCountForColorType;
314
315 ///////////////////////////////////////////////////////////////////////////
316 // Misc.
317
318 /**
319 * Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
320 * executing any more commands on the GPU. If this call returns false, then the GPU back-end
321 * will not wait on any passed in semaphores, and the client will still own the semaphores,
322 * regardless of the value of deleteSemaphoresAfterWait.
323 *
324 * If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case
325 * it is the client's responsibility to not destroy or attempt to reuse the semaphores until it
326 * knows that Skia has finished waiting on them. This can be done by using finishedProcs on
327 * flush calls.
328 */
329 bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores,
330 bool deleteSemaphoresAfterWait = true);
331
332 /**
333 * Call to ensure all drawing to the context has been flushed and submitted to the underlying 3D
334 * API. This is equivalent to calling GrContext::flush with a default GrFlushInfo followed by
335 * GrContext::submit.
336 */
337 void flushAndSubmit() {
338 this->flush(GrFlushInfo());
339 this->submit();
340 }
341
342 /**
343 * Call to ensure all drawing to the context has been flushed to underlying 3D API specific
344 * objects. A call to GrContext::submit is always required to ensure work is actually sent to
345 * the gpu. Some specific API details:
346 * GL: Commands are actually sent to the driver, but glFlush is never called. Thus some
347 * sync objects from the flush will not be valid until a submission occurs.
348 *
349 * Vulkan/Metal/D3D/Dawn: Commands are recorded to the backend APIs corresponding command
350 * buffer or encoder objects. However, these objects are not sent to the gpu until a
351 * submission occurs.
352 *
353 * If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will be
354 * submitted to the gpu during the next submit call (it is possible Skia failed to create a
355 * subset of the semaphores). The client should not wait on these semaphores until after submit
356 * has been called, and must keep them alive until then. If this call returns
357 * GrSemaphoresSubmitted::kNo, the GPU backend will not submit any semaphores to be signaled on
358 * the GPU. Thus the client should not have the GPU wait on any of the semaphores passed in with
359 * the GrFlushInfo. Regardless of whether semaphores were submitted to the GPU or not, the
360 * client is still responsible for deleting any initialized semaphores.
361 * Regardleess of semaphore submission the context will still be flushed. It should be
362 * emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
363 * happen. It simply means there were no semaphores submitted to the GPU. A caller should only
364 * take this as a failure if they passed in semaphores to be submitted.
365 */
366 GrSemaphoresSubmitted flush(const GrFlushInfo& info);
367
368 void flush() { this->flush({}); }
369
370 /**
371 * Submit outstanding work to the gpu from all previously un-submitted flushes. The return
372 * value of the submit will indicate whether or not the submission to the GPU was successful.
373 *
374 * If the call returns true, all previously passed in semaphores in flush calls will have been
375 * submitted to the GPU and they can safely be waited on. The caller should wait on those
376 * semaphores or perform some other global synchronization before deleting the semaphores.
377 *
378 * If it returns false, then those same semaphores will not have been submitted and we will not
379 * try to submit them again. The caller is free to delete the semaphores at any time.
380 *
381 * If the syncCpu flag is true this function will return once the gpu has finished with all
382 * submitted work.
383 */
384 bool submit(bool syncCpu = false);
385
386 /**
387 * Checks whether any asynchronous work is complete and if so calls related callbacks.
388 */
389 void checkAsyncWorkCompletion();
390
391 // Provides access to functions that aren't part of the public API.
392 GrContextPriv priv();
393 const GrContextPriv priv() const; // NOLINT(readability-const-return-type)
394
395 /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
396 // Chrome is using this!
397 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
398
399 bool supportsDistanceFieldText() const;
400
401 void storeVkPipelineCacheData();
402
403 // Returns the gpu memory size of the the texture that backs the passed in SkImage. Returns 0 if
404 // the SkImage is not texture backed. For external format textures this will also return 0 as we
405 // cannot determine the correct size.
406 static size_t ComputeImageSize(sk_sp<SkImage> image, GrMipmapped, bool useNextPow2 = false);
407
408 /**
409 * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
410 * It is guaranteed that this backend format will be the one used by the following
411 * SkColorType and SkSurfaceCharacterization-based createBackendTexture methods.
412 *
413 * The caller should check that the returned format is valid.
414 */
415 GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const {
416 return INHERITED::defaultBackendFormat(ct, renderable);
417 }
418
419 /**
420 * The explicitly allocated backend texture API allows clients to use Skia to create backend
421 * objects outside of Skia proper (i.e., Skia's caching system will not know about them.)
422 *
423 * It is the client's responsibility to delete all these objects (using deleteBackendTexture)
424 * before deleting the GrContext used to create them. If the backend is Vulkan, the textures must
425 * be deleted before abandoning the GrContext as well. Additionally, clients should only delete
426 * these objects on the thread for which that GrContext is active.
427 *
428 * The client is responsible for ensuring synchronization between different uses
429 * of the backend object (i.e., wrapping it in a surface, rendering to it, deleting the
430 * surface, rewrapping it in a image and drawing the image will require explicit
431 * sychronization on the client's part).
432 */
433
434 /**
435 * If possible, create an uninitialized backend texture. The client should ensure that the
436 * returned backend texture is valid.
437 * For the Vulkan backend the layout of the created VkImage will be:
438 * VK_IMAGE_LAYOUT_UNDEFINED.
439 */
440 GrBackendTexture createBackendTexture(int width, int height,
441 const GrBackendFormat&,
442 GrMipmapped,
443 GrRenderable,
444 GrProtected = GrProtected::kNo);
445
446 /**
447 * If possible, create an uninitialized backend texture. The client should ensure that the
448 * returned backend texture is valid.
449 * If successful, the created backend texture will be compatible with the provided
450 * SkColorType.
451 * For the Vulkan backend the layout of the created VkImage will be:
452 * VK_IMAGE_LAYOUT_UNDEFINED.
453 */
454 GrBackendTexture createBackendTexture(int width, int height,
455 SkColorType,
456 GrMipmapped,
457 GrRenderable,
458 GrProtected = GrProtected::kNo);
459
460
461 /**
462 * If possible, create an uninitialized backend texture that is compatible with the
463 * provided characterization. The client should ensure that the returned backend texture
464 * is valid.
465 * For the Vulkan backend the layout of the created VkImage will be:
466 * VK_IMAGE_LAYOUT_UNDEFINED.
467 */
468 GrBackendTexture createBackendTexture(const SkSurfaceCharacterization& characterization);
469
470 /**
471 * If possible, create a backend texture initialized to a particular color. The client should
472 * ensure that the returned backend texture is valid. The client can pass in a finishedProc
473 * to be notified when the data has been uploaded by the gpu and the texture can be deleted. The
474 * client is required to call GrContext::submit to send the upload work to the gpu. The
475 * finishedProc will always get called even if we failed to create the GrBackendTexture.
476 * For the Vulkan backend the layout of the created VkImage will be:
477 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
478 */
479 GrBackendTexture createBackendTexture(int width, int height,
480 const GrBackendFormat&,
481 const SkColor4f& color,
482 GrMipmapped,
483 GrRenderable,
484 GrProtected = GrProtected::kNo,
485 GrGpuFinishedProc finishedProc = nullptr,
486 GrGpuFinishedContext finishedContext = nullptr);
487
488 /**
489 * If possible, create a backend texture initialized to a particular color. The client should
490 * ensure that the returned backend texture is valid. The client can pass in a finishedProc
491 * to be notified when the data has been uploaded by the gpu and the texture can be deleted. The
492 * client is required to call GrContext::submit to send the upload work to the gpu. The
493 * finishedProc will always get called even if we failed to create the GrBackendTexture.
494 * If successful, the created backend texture will be compatible with the provided
495 * SkColorType.
496 * For the Vulkan backend the layout of the created VkImage will be:
497 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
498 */
499 GrBackendTexture createBackendTexture(int width, int height,
500 SkColorType,
501 const SkColor4f& color,
502 GrMipmapped,
503 GrRenderable,
504 GrProtected = GrProtected::kNo,
505 GrGpuFinishedProc finishedProc = nullptr,
506 GrGpuFinishedContext finishedContext = nullptr);
507
508 /**
509 * If possible, create a backend texture initialized to a particular color that is
510 * compatible with the provided characterization. The client should ensure that the
511 * returned backend texture is valid. The client can pass in a finishedProc to be notified when
512 * the data has been uploaded by the gpu and the texture can be deleted. The client is required
513 * to call GrContext::submit to send the upload work to the gpu. The finishedProc will always
514 * get called even if we failed to create the GrBackendTexture.
515 * For the Vulkan backend the layout of the created VkImage will be:
516 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL if texturaeble
517 * VK_IMAGE_LAYOUT_UNDEFINED if not textureable
518 */
519 GrBackendTexture createBackendTexture(const SkSurfaceCharacterization& characterization,
520 const SkColor4f& color,
521 GrGpuFinishedProc finishedProc = nullptr,
522 GrGpuFinishedContext finishedContext = nullptr);
523
524 /**
525 * If possible, create a backend texture initialized with the provided pixmap data. The client
526 * should ensure that the returned backend texture is valid. The client can pass in a
527 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
528 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
529 * The finishedProc will always get called even if we failed to create the GrBackendTexture.
530 * If successful, the created backend texture will be compatible with the provided
531 * pixmap(s). Compatible, in this case, means that the backend format will be the result
532 * of calling defaultBackendFormat on the base pixmap's colortype. The src data can be deleted
533 * when this call returns.
534 * If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
535 * the data for all the mipmap levels must be provided. In the mipmapped case all the
536 * colortypes of the provided pixmaps must be the same. Additionally, all the miplevels
537 * must be sized correctly (please see SkMipmap::ComputeLevelSize and ComputeLevelCount).
538 * Note: the pixmap's alphatypes and colorspaces are ignored.
539 * For the Vulkan backend the layout of the created VkImage will be:
540 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
541 */
542 GrBackendTexture createBackendTexture(const SkPixmap srcData[], int numLevels,
543 GrRenderable, GrProtected,
544 GrGpuFinishedProc finishedProc = nullptr,
545 GrGpuFinishedContext finishedContext = nullptr);
546
547 // Helper version of above for a single level.
548 GrBackendTexture createBackendTexture(const SkPixmap& srcData,
549 GrRenderable renderable,
550 GrProtected isProtected,
551 GrGpuFinishedProc finishedProc = nullptr,
552 GrGpuFinishedContext finishedContext = nullptr) {
553 return this->createBackendTexture(&srcData, 1, renderable, isProtected, finishedProc,
554 finishedContext);
555 }
556
557 /**
558 * If possible, updates a backend texture to be filled to a particular color. The client should
559 * check the return value to see if the update was successful. The client can pass in a
560 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
561 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
562 * The finishedProc will always get called even if we failed to update the GrBackendTexture.
563 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
564 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
565 */
566 bool updateBackendTexture(const GrBackendTexture&,
567 const SkColor4f& color,
568 GrGpuFinishedProc finishedProc,
569 GrGpuFinishedContext finishedContext);
570
571 /**
572 * If possible, updates a backend texture to be filled to a particular color. The data in
573 * GrBackendTexture and passed in color is interpreted with respect to the passed in
574 * SkColorType. The client should check the return value to see if the update was successful.
575 * The client can pass in a finishedProc to be notified when the data has been uploaded by the
576 * gpu and the texture can be deleted. The client is required to call GrContext::submit to send
577 * the upload work to the gpu. The finishedProc will always get called even if we failed to
578 * update the GrBackendTexture.
579 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
580 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
581 */
582 bool updateBackendTexture(const GrBackendTexture&,
583 SkColorType skColorType,
584 const SkColor4f& color,
585 GrGpuFinishedProc finishedProc,
586 GrGpuFinishedContext finishedContext);
587
588 /**
589 * If possible, updates a backend texture filled with the provided pixmap data. The client
590 * should check the return value to see if the update was successful. The client can pass in a
591 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
592 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
593 * The finishedProc will always get called even if we failed to create the GrBackendTexture.
594 * The backend texture must be compatible with the provided pixmap(s). Compatible, in this case,
595 * means that the backend format is compatible with the base pixmap's colortype. The src data
596 * can be deleted when this call returns.
597 * If the backend texture is mip mapped, the data for all the mipmap levels must be provided.
598 * In the mipmapped case all the colortypes of the provided pixmaps must be the same.
599 * Additionally, all the miplevels must be sized correctly (please see
600 * SkMipmap::ComputeLevelSize and ComputeLevelCount).
601 * Note: the pixmap's alphatypes and colorspaces are ignored.
602 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
603 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
604 */
605 bool updateBackendTexture(const GrBackendTexture&,
606 const SkPixmap srcData[],
607 int numLevels,
608 GrGpuFinishedProc finishedProc,
609 GrGpuFinishedContext finishedContext);
610
611 /**
612 * Retrieve the GrBackendFormat for a given SkImage::CompressionType. This is
613 * guaranteed to match the backend format used by the following
614 * createCompressedsBackendTexture methods that take a CompressionType.
615 * The caller should check that the returned format is valid.
616 */
617 GrBackendFormat compressedBackendFormat(SkImage::CompressionType compression) const {
618 return INHERITED::compressedBackendFormat(compression);
619 }
620
621 /**
622 *If possible, create a compressed backend texture initialized to a particular color. The
623 * client should ensure that the returned backend texture is valid. The client can pass in a
624 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
625 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
626 * The finishedProc will always get called even if we failed to create the GrBackendTexture.
627 * For the Vulkan backend the layout of the created VkImage will be:
628 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
629 */
630 GrBackendTexture createCompressedBackendTexture(int width, int height,
631 const GrBackendFormat&,
632 const SkColor4f& color,
633 GrMipmapped,
634 GrProtected = GrProtected::kNo,
635 GrGpuFinishedProc finishedProc = nullptr,
636 GrGpuFinishedContext finishedContext = nullptr);
637
638 GrBackendTexture createCompressedBackendTexture(int width, int height,
639 SkImage::CompressionType,
640 const SkColor4f& color,
641 GrMipmapped,
642 GrProtected = GrProtected::kNo,
643 GrGpuFinishedProc finishedProc = nullptr,
644 GrGpuFinishedContext finishedContext = nullptr);
645
646 /**
647 * If possible, create a backend texture initialized with the provided raw data. The client
648 * should ensure that the returned backend texture is valid. The client can pass in a
649 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
650 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
651 * The finishedProc will always get called even if we failed to create the GrBackendTexture
652 * If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
653 * the data for all the mipmap levels must be provided. Additionally, all the miplevels
654 * must be sized correctly (please see SkMipmap::ComputeLevelSize and ComputeLevelCount).
655 * For the Vulkan backend the layout of the created VkImage will be:
656 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
657 */
658 GrBackendTexture createCompressedBackendTexture(int width, int height,
659 const GrBackendFormat&,
660 const void* data, size_t dataSize,
661 GrMipmapped,
662 GrProtected = GrProtected::kNo,
663 GrGpuFinishedProc finishedProc = nullptr,
664 GrGpuFinishedContext finishedContext = nullptr);
665
666 GrBackendTexture createCompressedBackendTexture(int width, int height,
667 SkImage::CompressionType,
668 const void* data, size_t dataSize,
669 GrMipmapped,
670 GrProtected = GrProtected::kNo,
671 GrGpuFinishedProc finishedProc = nullptr,
672 GrGpuFinishedContext finishedContext = nullptr);
673
674 /**
675 * If possible, updates a backend texture filled with the provided color. If the texture is
676 * mipmapped, all levels of the mip chain will be updated to have the supplied color. The client
677 * should check the return value to see if the update was successful. The client can pass in a
678 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
679 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
680 * The finishedProc will always get called even if we failed to create the GrBackendTexture.
681 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
682 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
683 */
684 bool updateCompressedBackendTexture(const GrBackendTexture&,
685 const SkColor4f& color,
686 GrGpuFinishedProc finishedProc,
687 GrGpuFinishedContext finishedContext);
688
689 /**
690 * If possible, updates a backend texture filled with the provided raw data. The client
691 * should check the return value to see if the update was successful. The client can pass in a
692 * finishedProc to be notified when the data has been uploaded by the gpu and the texture can be
693 * deleted. The client is required to call GrContext::submit to send the upload work to the gpu.
694 * The finishedProc will always get called even if we failed to create the GrBackendTexture.
695 * If a mipMapped texture is passed in, the data for all the mipmap levels must be provided.
696 * Additionally, all the miplevels must be sized correctly (please see
697 * SkMipMap::ComputeLevelSize and ComputeLevelCount).
698 * For the Vulkan backend after a successful update the layout of the created VkImage will be:
699 * VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
700 */
701 bool updateCompressedBackendTexture(const GrBackendTexture&,
702 const void* data,
703 size_t dataSize,
704 GrGpuFinishedProc finishedProc,
705 GrGpuFinishedContext finishedContext);
706
707 /**
708 * Updates the state of the GrBackendTexture/RenderTarget to have the passed in
709 * GrBackendSurfaceMutableState. All objects that wrap the backend surface (i.e. SkSurfaces and
710 * SkImages) will also be aware of this state change. This call does not submit the state change
711 * to the gpu, but requires the client to call GrContext::submit to send it to the GPU. The work
712 * for this call is ordered linearly with all other calls that require GrContext::submit to be
713 * called (e.g updateBackendTexture and flush). If finishedProc is not null then it will be
714 * called with finishedContext after the state transition is known to have occurred on the GPU.
715 *
716 * See GrBackendSurfaceMutableState to see what state can be set via this call.
717 */
718 bool setBackendTextureState(const GrBackendTexture&,
719 const GrBackendSurfaceMutableState&,
720 GrGpuFinishedProc finishedProc = nullptr,
721 GrGpuFinishedContext finishedContext = nullptr);
722 bool setBackendRenderTargetState(const GrBackendRenderTarget&,
723 const GrBackendSurfaceMutableState&,
724 GrGpuFinishedProc finishedProc = nullptr,
725 GrGpuFinishedContext finishedContext = nullptr);
726
727 void deleteBackendTexture(GrBackendTexture);
728
729 // This interface allows clients to pre-compile shaders and populate the runtime program cache.
730 // The key and data blobs should be the ones passed to the PersistentCache, in SkSL format.
731 //
732 // Steps to use this API:
733 //
734 // 1) Create a GrContext as normal, but set fPersistentCache on GrContextOptions to something
735 // that will save the cached shader blobs. Set fShaderCacheStrategy to kSkSL. This will
736 // ensure that the blobs are SkSL, and are suitable for pre-compilation.
737 // 2) Run your application, and save all of the key/data pairs that are fed to the cache.
738 //
739 // 3) Switch over to shipping your application. Include the key/data pairs from above.
740 // 4) At startup (or any convenient time), call precompileShader for each key/data pair.
741 // This will compile the SkSL to create a GL program, and populate the runtime cache.
742 //
743 // This is only guaranteed to work if the context/device used in step #2 are created in the
744 // same way as the one used in step #4, and the same GrContextOptions are specified.
745 // Using cached shader blobs on a different device or driver are undefined.
746 bool precompileShader(const SkData& key, const SkData& data);
747
748#ifdef SK_ENABLE_DUMP_GPU
749 /** Returns a string with detailed information about the context & GPU, in JSON format. */
750 SkString dump() const;
751#endif
752
753protected:
754 GrContext(sk_sp<GrContextThreadSafeProxy>);
755
756 bool init() override;
757
758 virtual GrAtlasManager* onGetAtlasManager() = 0;
759 virtual GrSmallPathAtlasMgr* onGetSmallPathAtlasMgr() = 0;
760
761private:
762 friend class GrDirectContext; // for access to fGpu
763
764 // fTaskGroup must appear before anything that uses it (e.g. fGpu), so that it is destroyed
765 // after all of its users. Clients of fTaskGroup will generally want to ensure that they call
766 // wait() on it as they are being destroyed, to avoid the possibility of pending tasks being
767 // invoked after objects they depend upon have already been destroyed.
768 std::unique_ptr<SkTaskGroup> fTaskGroup;
769 std::unique_ptr<GrStrikeCache> fStrikeCache;
770 sk_sp<GrGpu> fGpu;
771 GrResourceCache* fResourceCache;
772 GrResourceProvider* fResourceProvider;
773
774 bool fDidTestPMConversions;
775 // true if the PM/UPM conversion succeeded; false otherwise
776 bool fPMUPMConversionsRoundTrip;
777
778 GrContextOptions::PersistentCache* fPersistentCache;
779 GrContextOptions::ShaderErrorHandler* fShaderErrorHandler;
780
781 std::unique_ptr<GrClientMappedBufferManager> fMappedBufferManager;
782
783 // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending
784 friend class GrContextPriv;
785
786 typedef GrRecordingContext INHERITED;
787};
788
789#endif
790