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/private/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 GrStrikeCache;
37class GrSurfaceProxy;
38class GrSwizzle;
39class GrTextContext;
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#ifdef SK_GL
53 /**
54 * Creates a GrContext for a backend context. If no GrGLInterface is provided then the result of
55 * GrGLMakeNativeInterface() is used if it succeeds.
56 */
57 static sk_sp<GrContext> MakeGL(sk_sp<const GrGLInterface>, const GrContextOptions&);
58 static sk_sp<GrContext> MakeGL(sk_sp<const GrGLInterface>);
59 static sk_sp<GrContext> MakeGL(const GrContextOptions&);
60 static sk_sp<GrContext> MakeGL();
61#endif
62
63 /**
64 * The Vulkan context (VkQueue, VkDevice, VkInstance) must be kept alive until the returned
65 * GrContext is first destroyed or abandoned.
66 */
67 static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext&, const GrContextOptions&);
68 static sk_sp<GrContext> MakeVulkan(const GrVkBackendContext&);
69
70#ifdef SK_METAL
71 /**
72 * Makes a GrContext which uses Metal as the backend. The device parameter is an MTLDevice
73 * and queue is an MTLCommandQueue which should be used by the backend. These objects must
74 * have a ref on them which can be transferred to Ganesh which will release the ref when the
75 * GrContext is destroyed.
76 */
77 static sk_sp<GrContext> MakeMetal(void* device, void* queue, const GrContextOptions& options);
78 static sk_sp<GrContext> MakeMetal(void* device, void* queue);
79#endif
80
81#ifdef SK_DIRECT3D
82 /**
83 * Makes a GrContext which uses Direct3D as the backend. The Direct3D context
84 * must be kept alive until the returned GrContext is first destroyed or abandoned.
85 */
86 static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&,
87 const GrContextOptions& options);
88 static sk_sp<GrContext> MakeDirect3D(const GrD3DBackendContext&);
89#endif
90
91#ifdef SK_DAWN
92 static sk_sp<GrContext> MakeDawn(const wgpu::Device& device, const GrContextOptions& options);
93 static sk_sp<GrContext> MakeDawn(const wgpu::Device& device);
94#endif
95
96 static sk_sp<GrContext> MakeMock(const GrMockOptions*, const GrContextOptions&);
97 static sk_sp<GrContext> MakeMock(const GrMockOptions*);
98
99 ~GrContext() override;
100
101 sk_sp<GrContextThreadSafeProxy> threadSafeProxy();
102
103 /**
104 * The GrContext normally assumes that no outsider is setting state
105 * within the underlying 3D API's context/device/whatever. This call informs
106 * the context that the state was modified and it should resend. Shouldn't
107 * be called frequently for good performance.
108 * The flag bits, state, is dpendent on which backend is used by the
109 * context, either GL or D3D (possible in future).
110 */
111 void resetContext(uint32_t state = kAll_GrBackendState);
112
113 /**
114 * If the backend is GrBackendApi::kOpenGL, then all texture unit/target combinations for which
115 * the GrContext has modified the bound texture will have texture id 0 bound. This does not
116 * flush the GrContext. Calling resetContext() does not change the set that will be bound
117 * to texture id 0 on the next call to resetGLTextureBindings(). After this is called
118 * all unit/target combinations are considered to have unmodified bindings until the GrContext
119 * subsequently modifies them (meaning if this is called twice in a row with no intervening
120 * GrContext usage then the second call is a no-op.)
121 */
122 void resetGLTextureBindings();
123
124 /**
125 * Abandons all GPU resources and assumes the underlying backend 3D API context is no longer
126 * usable. Call this if you have lost the associated GPU context, and thus internal texture,
127 * buffer, etc. references/IDs are now invalid. Calling this ensures that the destructors of the
128 * GrContext and any of its created resource objects will not make backend 3D API calls. Content
129 * rendered but not previously flushed may be lost. After this function is called all subsequent
130 * calls on the GrContext will fail or be no-ops.
131 *
132 * The typical use case for this function is that the underlying 3D context was lost and further
133 * API calls may crash.
134 *
135 * For Vulkan, even if the device becomes lost, the VkQueue, VkDevice, or VkInstance used to
136 * create the GrContext must be alive before calling abandonContext.
137 */
138 void abandonContext() override;
139
140 /**
141 * Returns true if the context was abandoned or if the if the backend specific context has
142 * gotten into an unrecoverarble, lost state (e.g. in Vulkan backend if we've gotten a
143 * VK_ERROR_DEVICE_LOST). If the backend context is lost, this call will also abandon the
144 * GrContext.
145 */
146 bool abandoned() override;
147
148 /**
149 * This is similar to abandonContext() however the underlying 3D context is not yet lost and
150 * the GrContext will cleanup all allocated resources before returning. After returning it will
151 * assume that the underlying context may no longer be valid.
152 *
153 * The typical use case for this function is that the client is going to destroy the 3D context
154 * but can't guarantee that GrContext will be destroyed first (perhaps because it may be ref'ed
155 * elsewhere by either the client or Skia objects).
156 *
157 * For Vulkan, even if the device becomes lost, the VkQueue, VkDevice, or VkInstance used to
158 * create the GrContext must be alive before calling releaseResourcesAndAbandonContext.
159 */
160 virtual void releaseResourcesAndAbandonContext();
161
162 ///////////////////////////////////////////////////////////////////////////
163 // Resource Cache
164
165 /** DEPRECATED
166 * Return the current GPU resource cache limits.
167 *
168 * @param maxResources If non-null, will be set to -1.
169 * @param maxResourceBytes If non-null, returns maximum number of bytes of
170 * video memory that can be held in the cache.
171 */
172 void getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const;
173
174 /**
175 * Return the current GPU resource cache limit in bytes.
176 */
177 size_t getResourceCacheLimit() const;
178
179 /**
180 * Gets the current GPU resource cache usage.
181 *
182 * @param resourceCount If non-null, returns the number of resources that are held in the
183 * cache.
184 * @param maxResourceBytes If non-null, returns the total number of bytes of video memory held
185 * in the cache.
186 */
187 void getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
188
189 /**
190 * Gets the number of bytes in the cache consumed by purgeable (e.g. unlocked) resources.
191 */
192 size_t getResourceCachePurgeableBytes() const;
193
194 /** DEPRECATED
195 * Specify the GPU resource cache limits. If the current cache exceeds the maxResourceBytes
196 * limit, it will be purged (LRU) to keep the cache within the limit.
197 *
198 * @param maxResources Unused.
199 * @param maxResourceBytes The maximum number of bytes of video memory
200 * that can be held in the cache.
201 */
202 void setResourceCacheLimits(int maxResources, size_t maxResourceBytes);
203
204 /**
205 * Specify the GPU resource cache limit. If the cache currently exceeds this limit,
206 * it will be purged (LRU) to keep the cache within the limit.
207 *
208 * @param maxResourceBytes The maximum number of bytes of video memory
209 * that can be held in the cache.
210 */
211 void setResourceCacheLimit(size_t maxResourceBytes);
212
213 /**
214 * Frees GPU created by the context. Can be called to reduce GPU memory
215 * pressure.
216 */
217 virtual void freeGpuResources();
218
219 /**
220 * Purge GPU resources that haven't been used in the past 'msNotUsed' milliseconds or are
221 * otherwise marked for deletion, regardless of whether the context is under budget.
222 */
223 void performDeferredCleanup(std::chrono::milliseconds msNotUsed);
224
225 // Temporary compatibility API for Android.
226 void purgeResourcesNotUsedInMs(std::chrono::milliseconds msNotUsed) {
227 this->performDeferredCleanup(msNotUsed);
228 }
229
230 /**
231 * Purge unlocked resources from the cache until the the provided byte count has been reached
232 * or we have purged all unlocked resources. The default policy is to purge in LRU order, but
233 * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other
234 * resource types.
235 *
236 * @param maxBytesToPurge the desired number of bytes to be purged.
237 * @param preferScratchResources If true scratch resources will be purged prior to other
238 * resource types.
239 */
240 void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources);
241
242 /**
243 * This entry point is intended for instances where an app has been backgrounded or
244 * suspended.
245 * If 'scratchResourcesOnly' is true all unlocked scratch resources will be purged but the
246 * unlocked resources with persistent data will remain. If 'scratchResourcesOnly' is false
247 * then all unlocked resources will be purged.
248 * In either case, after the unlocked resources are purged a separate pass will be made to
249 * ensure that resource usage is under budget (i.e., even if 'scratchResourcesOnly' is true
250 * some resources with persistent data may be purged to be under budget).
251 *
252 * @param scratchResourcesOnly If true only unlocked scratch resources will be purged prior
253 * enforcing the budget requirements.
254 */
255 void purgeUnlockedResources(bool scratchResourcesOnly);
256
257 /**
258 * Gets the maximum supported texture size.
259 */
260 int maxTextureSize() const;
261
262 /**
263 * Gets the maximum supported render target size.
264 */
265 int maxRenderTargetSize() const;
266
267 /**
268 * Can a SkImage be created with the given color type.
269 */
270 bool colorTypeSupportedAsImage(SkColorType) const;
271
272 /**
273 * Can a SkSurface be created with the given color type. To check whether MSAA is supported
274 * use maxSurfaceSampleCountForColorType().
275 */
276 bool colorTypeSupportedAsSurface(SkColorType colorType) const {
277 if (kR16G16_unorm_SkColorType == colorType ||
278 kA16_unorm_SkColorType == colorType ||
279 kA16_float_SkColorType == colorType ||
280 kR16G16_float_SkColorType == colorType ||
281 kR16G16B16A16_unorm_SkColorType == colorType ||
282 kGray_8_SkColorType == colorType) {
283 return false;
284 }
285
286 return this->maxSurfaceSampleCountForColorType(colorType) > 0;
287 }
288
289 /**
290 * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA
291 * rendering is supported for the color type. 0 is returned if rendering to this color type
292 * is not supported at all.
293 */
294 int maxSurfaceSampleCountForColorType(SkColorType) const;
295
296 ///////////////////////////////////////////////////////////////////////////
297 // Misc.
298
299
300 /**
301 * Inserts a list of GPU semaphores that the current GPU-backed API must wait on before
302 * executing any more commands on the GPU. Skia will take ownership of the underlying semaphores
303 * and delete them once they have been signaled and waited on. If this call returns false, then
304 * the GPU back-end will not wait on any passed in semaphores, and the client will still own the
305 * semaphores.
306 */
307 bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores);
308
309 /**
310 * Call to ensure all drawing to the context has been issued to the underlying 3D API.
311 */
312 void flush() {
313 this->flush(GrFlushInfo(), GrPrepareForExternalIORequests());
314 }
315
316 /**
317 * Call to ensure all drawing to the context has been issued to the underlying 3D API.
318 *
319 * If the return is GrSemaphoresSubmitted::kYes, only initialized GrBackendSemaphores will have
320 * been submitted and can be waited on (it is possible Skia failed to create a subset of the
321 * semaphores). If this call returns GrSemaphoresSubmitted::kNo, the GPU backend will not have
322 * submitted any semaphores to be signaled on the GPU. Thus the client should not have the GPU
323 * wait on any of the semaphores passed in with the GrFlushInfo. Regardless of whether
324 * semaphores were submitted to the GPU or not, the client is still responsible for deleting any
325 * initialized semaphores.
326 * Regardleess of semaphore submission the context will still be flushed. It should be
327 * emphasized that a return value of GrSemaphoresSubmitted::kNo does not mean the flush did not
328 * happen. It simply means there were no semaphores submitted to the GPU. A caller should only
329 * take this as a failure if they passed in semaphores to be submitted.
330 */
331 GrSemaphoresSubmitted flush(const GrFlushInfo& info) {
332 return this->flush(info, GrPrepareForExternalIORequests());
333 }
334
335 /**
336 * Call to ensure all drawing to the context has been issued to the underlying 3D API.
337 *
338 * If this call returns GrSemaphoresSubmitted::kNo, the GPU backend will not have created or
339 * added any semaphores to signal on the GPU. Thus the client should not have the GPU wait on
340 * any of the semaphores passed in with the GrFlushInfo. However, any pending commands to the
341 * context will still be flushed. It should be emphasized that a return value of
342 * GrSemaphoresSubmitted::kNo does not mean the flush did not happen. It simply means there were
343 * no semaphores submitted to the GPU. A caller should only take this as a failure if they
344 * passed in semaphores to be submitted.
345 *
346 * If the GrPrepareForExternalIORequests contains valid gpu backed SkSurfaces or SkImages, Skia
347 * will put the underlying backend objects into a state that is ready for external uses. See
348 * declaration of GrPreopareForExternalIORequests for more details.
349 */
350 GrSemaphoresSubmitted flush(const GrFlushInfo&, const GrPrepareForExternalIORequests&);
351
352 /**
353 * Deprecated.
354 */
355 GrSemaphoresSubmitted flush(GrFlushFlags flags, int numSemaphores,
356 GrBackendSemaphore signalSemaphores[],
357 GrGpuFinishedProc finishedProc = nullptr,
358 GrGpuFinishedContext finishedContext = nullptr) {
359 GrFlushInfo info;
360 info.fFlags = flags;
361 info.fNumSemaphores = numSemaphores;
362 info.fSignalSemaphores = signalSemaphores;
363 info.fFinishedProc = finishedProc;
364 info.fFinishedContext = finishedContext;
365 return this->flush(info);
366 }
367
368 /**
369 * Deprecated.
370 */
371 GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
372 GrBackendSemaphore signalSemaphores[]) {
373 GrFlushInfo info;
374 info.fNumSemaphores = numSemaphores;
375 info.fSignalSemaphores = signalSemaphores;
376 return this->flush(info);
377 }
378
379 /**
380 * Checks whether any asynchronous work is complete and if so calls related callbacks.
381 */
382 void checkAsyncWorkCompletion();
383
384 // Provides access to functions that aren't part of the public API.
385 GrContextPriv priv();
386 const GrContextPriv priv() const;
387
388 /** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
389 // Chrome is using this!
390 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
391
392 bool supportsDistanceFieldText() const;
393
394 void storeVkPipelineCacheData();
395
396 // Returns the gpu memory size of the the texture that backs the passed in SkImage. Returns 0 if
397 // the SkImage is not texture backed. For external format textures this will also return 0 as we
398 // cannot determine the correct size.
399 static size_t ComputeImageSize(sk_sp<SkImage> image, GrMipMapped, bool useNextPow2 = false);
400
401 /*
402 * Retrieve the default GrBackendFormat for a given SkColorType and renderability.
403 * It is guaranteed that this backend format will be the one used by the following
404 * SkColorType and SkSurfaceCharacterization-based createBackendTexture methods.
405 *
406 * The caller should check that the returned format is valid.
407 */
408 GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const {
409 return INHERITED::defaultBackendFormat(ct, renderable);
410 }
411
412 /*
413 * The explicitly allocated backend texture API allows clients to use Skia to create backend
414 * objects outside of Skia proper (i.e., Skia's caching system will not know about them.)
415 *
416 * It is the client's responsibility to delete all these objects (using deleteBackendTexture)
417 * before deleting the GrContext used to create them. If the backend is Vulkan, the textures must
418 * be deleted before abandoning the GrContext as well. Additionally, clients should only delete
419 * these objects on the thread for which that GrContext is active.
420 *
421 * The client is responsible for ensuring synchronization between different uses
422 * of the backend object (i.e., wrapping it in a surface, rendering to it, deleting the
423 * surface, rewrapping it in a image and drawing the image will require explicit
424 * sychronization on the client's part).
425 */
426
427 // If possible, create an uninitialized backend texture. The client should ensure that the
428 // returned backend texture is valid.
429 // For the Vulkan backend the layout of the created VkImage will be:
430 // VK_IMAGE_LAYOUT_UNDEFINED.
431 GrBackendTexture createBackendTexture(int width, int height,
432 const GrBackendFormat&,
433 GrMipMapped,
434 GrRenderable,
435 GrProtected = GrProtected::kNo);
436
437 // If possible, create an uninitialized backend texture. The client should ensure that the
438 // returned backend texture is valid.
439 // If successful, the created backend texture will be compatible with the provided
440 // SkColorType.
441 // For the Vulkan backend the layout of the created VkImage will be:
442 // VK_IMAGE_LAYOUT_UNDEFINED.
443 GrBackendTexture createBackendTexture(int width, int height,
444 SkColorType,
445 GrMipMapped,
446 GrRenderable,
447 GrProtected = GrProtected::kNo);
448
449
450 // If possible, create an uninitialized backend texture that is compatible with the
451 // provided characterization. The client should ensure that the returned backend texture
452 // is valid.
453 // For the Vulkan backend the layout of the created VkImage will be:
454 // VK_IMAGE_LAYOUT_UNDEFINED.
455 GrBackendTexture createBackendTexture(const SkSurfaceCharacterization& characterization);
456
457 // If possible, create a backend texture initialized to a particular color. The client should
458 // ensure that the returned backend texture is valid.
459 // For the Vulkan backend the layout of the created VkImage will be:
460 // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL if renderable is kNo
461 // and VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL if renderable is kYes
462 GrBackendTexture createBackendTexture(int width, int height,
463 const GrBackendFormat&,
464 const SkColor4f& color,
465 GrMipMapped,
466 GrRenderable,
467 GrProtected = GrProtected::kNo);
468
469 // If possible, create a backend texture initialized to a particular color. The client should
470 // ensure that the returned backend texture is valid.
471 // If successful, the created backend texture will be compatible with the provided
472 // SkColorType.
473 // For the Vulkan backend the layout of the created VkImage will be:
474 // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL if renderable is kNo
475 // and VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL if renderable is kYes
476 GrBackendTexture createBackendTexture(int width, int height,
477 SkColorType,
478 const SkColor4f& color,
479 GrMipMapped,
480 GrRenderable,
481 GrProtected = GrProtected::kNo);
482
483 // If possible, create a backend texture initialized to a particular color that is
484 // compatible with the provided characterization. The client should ensure that the
485 // returned backend texture is valid.
486 // For the Vulkan backend the layout of the created VkImage will be:
487 // VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
488 GrBackendTexture createBackendTexture(const SkSurfaceCharacterization& characterization,
489 const SkColor4f& color);
490
491 // If possible, create a backend texture initialized with the provided pixmap data. The client
492 // should ensure that the returned backend texture is valid.
493 // If successful, the created backend texture will be compatible with the provided
494 // pixmap(s). Compatible, in this case, means that the backend format will be the result
495 // of calling defaultBackendFormat on the base pixmap's colortype.
496 // If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
497 // the data for all the mipmap levels must be provided. In the mipmapped case all the
498 // colortypes of the provided pixmaps must be the same. Additionally, all the miplevels
499 // must be sized correctly (please see SkMipMap::ComputeLevelSize and ComputeLevelCount).
500 // Note: the pixmap's alphatypes and colorspaces are ignored.
501 // For the Vulkan backend the layout of the created VkImage will be:
502 // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
503 // regardless of the renderability setting
504 GrBackendTexture createBackendTexture(const SkPixmap srcData[], int numLevels,
505 GrRenderable, GrProtected);
506
507 // Helper version of above for a single level.
508 GrBackendTexture createBackendTexture(const SkPixmap& srcData,
509 GrRenderable renderable,
510 GrProtected isProtected) {
511 return this->createBackendTexture(&srcData, 1, renderable, isProtected);
512 }
513
514 /*
515 * Retrieve the GrBackendFormat for a given SkImage::CompressionType. This is
516 * guaranteed to match the backend format used by the following
517 * createCompressedsBackendTexture methods that take a CompressionType.
518 * The caller should check that the returned format is valid.
519 */
520 GrBackendFormat compressedBackendFormat(SkImage::CompressionType compression) const {
521 return INHERITED::compressedBackendFormat(compression);
522 }
523
524 // If possible, create a compressed backend texture initialized to a particular color. The
525 // client should ensure that the returned backend texture is valid.
526 // For the Vulkan backend the layout of the created VkImage will be:
527 // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
528 GrBackendTexture createCompressedBackendTexture(int width, int height,
529 const GrBackendFormat&,
530 const SkColor4f& color,
531 GrMipMapped,
532 GrProtected = GrProtected::kNo);
533
534 GrBackendTexture createCompressedBackendTexture(int width, int height,
535 SkImage::CompressionType,
536 const SkColor4f& color,
537 GrMipMapped,
538 GrProtected = GrProtected::kNo);
539
540 // If possible, create a backend texture initialized with the provided raw data. The client
541 // should ensure that the returned backend texture is valid.
542 // If numLevels is 1 a non-mipMapped texture will result. If a mipMapped texture is desired
543 // the data for all the mipmap levels must be provided. Additionally, all the miplevels
544 // must be sized correctly (please see SkMipMap::ComputeLevelSize and ComputeLevelCount).
545 // For the Vulkan backend the layout of the created VkImage will be:
546 // VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
547 GrBackendTexture createCompressedBackendTexture(int width, int height,
548 const GrBackendFormat&,
549 const void* data, size_t dataSize,
550 GrMipMapped,
551 GrProtected = GrProtected::kNo);
552
553 GrBackendTexture createCompressedBackendTexture(int width, int height,
554 SkImage::CompressionType,
555 const void* data, size_t dataSize,
556 GrMipMapped,
557 GrProtected = GrProtected::kNo);
558
559 void deleteBackendTexture(GrBackendTexture);
560
561 // This interface allows clients to pre-compile shaders and populate the runtime program cache.
562 // The key and data blobs should be the ones passed to the PersistentCache, in SkSL format.
563 //
564 // Steps to use this API:
565 //
566 // 1) Create a GrContext as normal, but set fPersistentCache on GrContextOptions to something
567 // that will save the cached shader blobs. Set fShaderCacheStrategy to kSkSL. This will
568 // ensure that the blobs are SkSL, and are suitable for pre-compilation.
569 // 2) Run your application, and save all of the key/data pairs that are fed to the cache.
570 //
571 // 3) Switch over to shipping your application. Include the key/data pairs from above.
572 // 4) At startup (or any convenient time), call precompileShader for each key/data pair.
573 // This will compile the SkSL to create a GL program, and populate the runtime cache.
574 //
575 // This is only guaranteed to work if the context/device used in step #2 are created in the
576 // same way as the one used in step #4, and the same GrContextOptions are specified.
577 // Using cached shader blobs on a different device or driver are undefined.
578 bool precompileShader(const SkData& key, const SkData& data);
579
580#ifdef SK_ENABLE_DUMP_GPU
581 /** Returns a string with detailed information about the context & GPU, in JSON format. */
582 SkString dump() const;
583#endif
584
585protected:
586 GrContext(GrBackendApi, const GrContextOptions&, int32_t contextID = SK_InvalidGenID);
587
588 bool init(sk_sp<const GrCaps>) override;
589
590 GrContext* asDirectContext() override { return this; }
591
592 virtual GrAtlasManager* onGetAtlasManager() = 0;
593
594 sk_sp<GrContextThreadSafeProxy> fThreadSafeProxy;
595
596private:
597 // fTaskGroup must appear before anything that uses it (e.g. fGpu), so that it is destroyed
598 // after all of its users. Clients of fTaskGroup will generally want to ensure that they call
599 // wait() on it as they are being destroyed, to avoid the possibility of pending tasks being
600 // invoked after objects they depend upon have already been destroyed.
601 std::unique_ptr<SkTaskGroup> fTaskGroup;
602 std::unique_ptr<GrStrikeCache> fStrikeCache;
603 sk_sp<GrGpu> fGpu;
604 GrResourceCache* fResourceCache;
605 GrResourceProvider* fResourceProvider;
606
607 bool fDidTestPMConversions;
608 // true if the PM/UPM conversion succeeded; false otherwise
609 bool fPMUPMConversionsRoundTrip;
610
611 GrContextOptions::PersistentCache* fPersistentCache;
612 GrContextOptions::ShaderErrorHandler* fShaderErrorHandler;
613
614 std::unique_ptr<GrClientMappedBufferManager> fMappedBufferManager;
615
616 // TODO: have the GrClipStackClip use renderTargetContexts and rm this friending
617 friend class GrContextPriv;
618
619 typedef GrRecordingContext INHERITED;
620};
621
622#endif
623