blob: 4ada100374a7d6f193a1396f8f6405d36ac73241 [file] [log] [blame]
Robert Phillipsa3457b82018-03-08 11:30:12 -05001/*
2 * Copyright 2018 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
Greg Daniel54bfb182018-11-20 17:12:36 -05008
Robert Phillipsb7bfbc22020-07-01 12:55:01 -04009#include "include/gpu/GrDirectContext.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050010
Adlai Holler3acc69a2020-10-13 08:20:51 -040011#include "include/core/SkTraceMemoryDump.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/gpu/GrContextThreadSafeProxy.h"
Brian Salomon71283232021-04-08 12:45:58 -040013#include "src/core/SkAutoMalloc.h"
Adlai Holler9555f292020-10-09 09:41:14 -040014#include "src/core/SkTaskGroup.h"
Robert Phillips06273bc2021-08-11 15:43:50 -040015#include "src/core/SkTraceEvent.h"
Brian Salomon71283232021-04-08 12:45:58 -040016#include "src/gpu/GrBackendUtils.h"
Adlai Holler9555f292020-10-09 09:41:14 -040017#include "src/gpu/GrClientMappedBufferManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/GrContextThreadSafeProxyPriv.h"
Adlai Hollera0693042020-10-14 11:23:11 -040019#include "src/gpu/GrDirectContextPriv.h"
Adlai Holler4aa4c602020-10-12 13:58:52 -040020#include "src/gpu/GrDrawingManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/GrGpu.h"
Adlai Holler9555f292020-10-09 09:41:14 -040022#include "src/gpu/GrResourceProvider.h"
23#include "src/gpu/GrShaderUtils.h"
Robert Phillips53eaa642021-08-10 13:49:51 -040024#include "src/gpu/SurfaceContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/effects/GrSkSLFP.h"
26#include "src/gpu/gl/GrGLGpu.h"
27#include "src/gpu/mock/GrMockGpu.h"
Robert Phillipse19babf2020-04-06 13:57:30 -040028#include "src/gpu/text/GrAtlasManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050029#include "src/gpu/text/GrStrikeCache.h"
Brian Salomonea1d39b2021-04-01 17:06:52 -040030#include "src/image/SkImage_GpuBase.h"
Robert Phillipsdb857ce2021-08-17 16:46:41 -040031#if SK_GPU_V1
32#include "src/gpu/ops/GrSmallPathAtlasMgr.h"
33#else
34// A vestigial definition for v2 that will never be instantiated
35class GrSmallPathAtlasMgr {
36public:
37 GrSmallPathAtlasMgr() { SkASSERT(0); }
38 void reset() { SkASSERT(0); }
39};
40#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -050041#ifdef SK_METAL
Jim Van Verth351c9b52020-11-12 15:21:11 -050042#include "include/gpu/mtl/GrMtlBackendContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050043#include "src/gpu/mtl/GrMtlTrampoline.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050044#endif
45#ifdef SK_VULKAN
Mike Kleinc0bd9f92019-04-23 12:05:21 -050046#include "src/gpu/vk/GrVkGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050047#endif
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -050048#ifdef SK_DIRECT3D
49#include "src/gpu/d3d/GrD3DGpu.h"
50#endif
Stephen White985741a2019-07-18 11:43:45 -040051#ifdef SK_DAWN
Mike Klein52337de2019-07-25 09:00:52 -050052#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White985741a2019-07-18 11:43:45 -040053#endif
Adlai Holler6d0745b2020-10-13 13:29:00 -040054#include <memory>
Robert Phillipsa3457b82018-03-08 11:30:12 -050055
Brian Salomon24069eb2020-06-24 10:19:52 -040056#if GR_TEST_UTILS
57# include "include/utils/SkRandom.h"
58# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
59# include <sanitizer/lsan_interface.h>
60# endif
61#endif
62
Adlai Holler9555f292020-10-09 09:41:14 -040063#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
64
Robert Phillipse7a959d2021-03-11 14:44:42 -050065GrDirectContext::DirectContextID GrDirectContext::DirectContextID::Next() {
Robert Phillipsedff4672021-03-11 09:16:25 -050066 static std::atomic<uint32_t> nextID{1};
67 uint32_t id;
68 do {
69 id = nextID.fetch_add(1, std::memory_order_relaxed);
70 } while (id == SK_InvalidUniqueID);
71 return DirectContextID(id);
72}
73
Robert Phillipsad248452020-06-30 09:27:52 -040074GrDirectContext::GrDirectContext(GrBackendApi backend, const GrContextOptions& options)
Robert Phillips23070582021-03-31 17:04:48 -040075 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options), false)
Robert Phillipse7a959d2021-03-11 14:44:42 -050076 , fDirectContextID(DirectContextID::Next()) {
Robert Phillipsad248452020-06-30 09:27:52 -040077}
Robert Phillipsa3457b82018-03-08 11:30:12 -050078
Robert Phillipsad248452020-06-30 09:27:52 -040079GrDirectContext::~GrDirectContext() {
Adlai Holler9555f292020-10-09 09:41:14 -040080 ASSERT_SINGLE_OWNER
Robert Phillipsad248452020-06-30 09:27:52 -040081 // this if-test protects against the case where the context is being destroyed
82 // before having been fully created
Adlai Holler9555f292020-10-09 09:41:14 -040083 if (fGpu) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040084 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050085 }
Adlai Holler9555f292020-10-09 09:41:14 -040086
Greg Daniela89b4302021-01-29 10:48:40 -050087 // We need to make sure all work is finished on the gpu before we start releasing resources.
88 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/false);
89
Adlai Holler9555f292020-10-09 09:41:14 -040090 this->destroyDrawingManager();
Adlai Holler9555f292020-10-09 09:41:14 -040091
92 // Ideally we could just let the ptr drop, but resource cache queries this ptr in releaseAll.
93 if (fResourceCache) {
94 fResourceCache->releaseAll();
95 }
Brian Salomon91a88f02021-02-04 15:34:32 -050096 // This has to be after GrResourceCache::releaseAll so that other threads that are holding
97 // async pixel result don't try to destroy buffers off thread.
98 fMappedBufferManager.reset();
Robert Phillipsad248452020-06-30 09:27:52 -040099}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500100
Adlai Holler61a591c2020-10-12 12:38:33 -0400101sk_sp<GrContextThreadSafeProxy> GrDirectContext::threadSafeProxy() {
102 return INHERITED::threadSafeProxy();
103}
104
Adlai Hollera7a40442020-10-09 09:49:42 -0400105void GrDirectContext::resetGLTextureBindings() {
106 if (this->abandoned() || this->backend() != GrBackendApi::kOpenGL) {
107 return;
108 }
109 fGpu->resetTextureBindings();
110}
111
112void GrDirectContext::resetContext(uint32_t state) {
113 ASSERT_SINGLE_OWNER
114 fGpu->markContextDirty(state);
115}
116
Robert Phillipsad248452020-06-30 09:27:52 -0400117void GrDirectContext::abandonContext() {
Adlai Hollera7a40442020-10-09 09:49:42 -0400118 if (INHERITED::abandoned()) {
119 return;
120 }
121
Robert Phillipsad248452020-06-30 09:27:52 -0400122 INHERITED::abandonContext();
Adlai Hollera7a40442020-10-09 09:49:42 -0400123
Greg Daniela89b4302021-01-29 10:48:40 -0500124 // We need to make sure all work is finished on the gpu before we start releasing resources.
125 this->syncAllOutstandingGpuWork(this->caps()->mustSyncGpuDuringAbandon());
126
Adlai Hollera7a40442020-10-09 09:49:42 -0400127 fStrikeCache->freeAll();
128
129 fMappedBufferManager->abandon();
130
131 fResourceProvider->abandon();
132
Robert Phillipseb999bc2020-11-03 08:41:47 -0500133 // abandon first so destructors don't try to free the resources in the API.
Adlai Hollera7a40442020-10-09 09:49:42 -0400134 fResourceCache->abandonAll();
135
136 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
137
Brian Salomon91a88f02021-02-04 15:34:32 -0500138 // Must be after GrResourceCache::abandonAll().
Adlai Hollera7a40442020-10-09 09:49:42 -0400139 fMappedBufferManager.reset();
Brian Salomon91a88f02021-02-04 15:34:32 -0500140
Robert Phillips079455c2020-08-11 15:18:46 -0400141 if (fSmallPathAtlasMgr) {
142 fSmallPathAtlasMgr->reset();
143 }
Robert Phillipsad248452020-06-30 09:27:52 -0400144 fAtlasManager->freeAll();
145}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500146
Adlai Hollera7a40442020-10-09 09:49:42 -0400147bool GrDirectContext::abandoned() {
148 if (INHERITED::abandoned()) {
149 return true;
150 }
151
152 if (fGpu && fGpu->isDeviceLost()) {
153 this->abandonContext();
154 return true;
155 }
156 return false;
157}
158
Adlai Holler61a591c2020-10-12 12:38:33 -0400159bool GrDirectContext::oomed() { return fGpu ? fGpu->checkAndResetOOMed() : false; }
160
Robert Phillipsad248452020-06-30 09:27:52 -0400161void GrDirectContext::releaseResourcesAndAbandonContext() {
Adlai Holler61a591c2020-10-12 12:38:33 -0400162 if (INHERITED::abandoned()) {
163 return;
164 }
165
166 INHERITED::abandonContext();
167
Greg Daniela89b4302021-01-29 10:48:40 -0500168 // We need to make sure all work is finished on the gpu before we start releasing resources.
169 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/true);
170
Adlai Holler61a591c2020-10-12 12:38:33 -0400171 fResourceProvider->abandon();
172
173 // Release all resources in the backend 3D API.
174 fResourceCache->releaseAll();
175
Brian Salomon91a88f02021-02-04 15:34:32 -0500176 // Must be after GrResourceCache::releaseAll().
177 fMappedBufferManager.reset();
178
Adlai Holler61a591c2020-10-12 12:38:33 -0400179 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
Robert Phillips079455c2020-08-11 15:18:46 -0400180 if (fSmallPathAtlasMgr) {
181 fSmallPathAtlasMgr->reset();
182 }
Robert Phillipsad248452020-06-30 09:27:52 -0400183 fAtlasManager->freeAll();
184}
Robert Phillips6db27c22019-05-01 10:43:56 -0400185
Robert Phillipsad248452020-06-30 09:27:52 -0400186void GrDirectContext::freeGpuResources() {
Adlai Holler4aa4c602020-10-12 13:58:52 -0400187 ASSERT_SINGLE_OWNER
188
189 if (this->abandoned()) {
190 return;
191 }
192
Robert Phillipsad248452020-06-30 09:27:52 -0400193 this->flushAndSubmit();
Robert Phillips079455c2020-08-11 15:18:46 -0400194 if (fSmallPathAtlasMgr) {
195 fSmallPathAtlasMgr->reset();
196 }
Robert Phillipsad248452020-06-30 09:27:52 -0400197 fAtlasManager->freeAll();
Robert Phillips56181ba2019-03-08 12:00:45 -0500198
Adlai Holler4aa4c602020-10-12 13:58:52 -0400199 // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
200 // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
201 fStrikeCache->freeAll();
202
203 this->drawingManager()->freeGpuResources();
204
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400205 fResourceCache->purgeUnlockedResources();
Robert Phillipsad248452020-06-30 09:27:52 -0400206}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500207
Robert Phillipsad248452020-06-30 09:27:52 -0400208bool GrDirectContext::init() {
Adlai Holler9555f292020-10-09 09:41:14 -0400209 ASSERT_SINGLE_OWNER
210 if (!fGpu) {
Robert Phillipsad248452020-06-30 09:27:52 -0400211 return false;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500212 }
213
Robert Phillipsae67c522021-03-03 11:03:38 -0500214 fThreadSafeProxy->priv().init(fGpu->refCaps(), fGpu->refPipelineBuilder());
Robert Phillipsad248452020-06-30 09:27:52 -0400215 if (!INHERITED::init()) {
216 return false;
217 }
Robert Phillipsa3457b82018-03-08 11:30:12 -0500218
Adlai Holler9555f292020-10-09 09:41:14 -0400219 SkASSERT(this->getTextBlobCache());
220 SkASSERT(this->threadSafeCache());
221
222 fStrikeCache = std::make_unique<GrStrikeCache>();
Robert Phillipsd074b622021-03-15 08:49:24 -0400223 fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(),
224 this->directContextID(),
225 this->contextID());
Adlai Holler9555f292020-10-09 09:41:14 -0400226 fResourceCache->setProxyProvider(this->proxyProvider());
227 fResourceCache->setThreadSafeCache(this->threadSafeCache());
Adlai Hollerb34270e2021-04-16 11:23:52 -0400228#if GR_TEST_UTILS
229 if (this->options().fResourceCacheLimitOverride != -1) {
230 this->setResourceCacheLimit(this->options().fResourceCacheLimitOverride);
231 }
232#endif
Adlai Holler9555f292020-10-09 09:41:14 -0400233 fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
234 this->singleOwner());
Robert Phillips82ad7af2021-03-11 16:00:10 -0500235 fMappedBufferManager = std::make_unique<GrClientMappedBufferManager>(this->directContextID());
Adlai Holler9555f292020-10-09 09:41:14 -0400236
237 fDidTestPMConversions = false;
238
239 // DDL TODO: we need to think through how the task group & persistent cache
240 // get passed on to/shared between all the DDLRecorders created with this context.
241 if (this->options().fExecutor) {
242 fTaskGroup = std::make_unique<SkTaskGroup>(*this->options().fExecutor);
243 }
244
245 fPersistentCache = this->options().fPersistentCache;
Adlai Holler9555f292020-10-09 09:41:14 -0400246
Robert Phillipsad248452020-06-30 09:27:52 -0400247 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
248 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
249 // multitexturing supported only if range can represent the index + texcoords fully
250 !(this->caps()->shaderCaps()->floatIs32Bits() ||
251 this->caps()->shaderCaps()->integerSupport())) {
252 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
253 } else {
254 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
255 }
256
257 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
258
Robert Phillips3262bc82020-08-10 12:11:58 -0400259 fAtlasManager = std::make_unique<GrAtlasManager>(proxyProvider,
260 this->options().fGlyphCacheTextureMaximumBytes,
261 allowMultitexturing);
262 this->priv().addOnFlushCallbackObject(fAtlasManager.get());
Robert Phillipsad248452020-06-30 09:27:52 -0400263
264 return true;
265}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500266
Adlai Holler3a508e92020-10-12 13:58:01 -0400267void GrDirectContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
268 ASSERT_SINGLE_OWNER
269
270 if (resourceCount) {
271 *resourceCount = fResourceCache->getBudgetedResourceCount();
272 }
273 if (resourceBytes) {
274 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
275 }
276}
277
278size_t GrDirectContext::getResourceCachePurgeableBytes() const {
279 ASSERT_SINGLE_OWNER
280 return fResourceCache->getPurgeableBytes();
281}
282
283void GrDirectContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
284 ASSERT_SINGLE_OWNER
285 if (maxResources) {
286 *maxResources = -1;
287 }
288 if (maxResourceBytes) {
289 *maxResourceBytes = this->getResourceCacheLimit();
290 }
291}
292
293size_t GrDirectContext::getResourceCacheLimit() const {
294 ASSERT_SINGLE_OWNER
295 return fResourceCache->getMaxResourceBytes();
296}
297
298void GrDirectContext::setResourceCacheLimits(int unused, size_t maxResourceBytes) {
299 ASSERT_SINGLE_OWNER
300 this->setResourceCacheLimit(maxResourceBytes);
301}
302
303void GrDirectContext::setResourceCacheLimit(size_t maxResourceBytes) {
304 ASSERT_SINGLE_OWNER
305 fResourceCache->setLimit(maxResourceBytes);
306}
307
Adlai Holler4aa4c602020-10-12 13:58:52 -0400308void GrDirectContext::purgeUnlockedResources(bool scratchResourcesOnly) {
309 ASSERT_SINGLE_OWNER
310
311 if (this->abandoned()) {
312 return;
313 }
314
315 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
316 fResourceCache->purgeAsNeeded();
317
318 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
319 // place to purge stale blobs
320 this->getTextBlobCache()->purgeStaleBlobs();
Greg Daniel428523f2021-03-30 14:22:54 -0400321
322 fGpu->releaseUnlockedBackendObjects();
Adlai Holler4aa4c602020-10-12 13:58:52 -0400323}
324
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400325void GrDirectContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed,
326 bool scratchResourcesOnly) {
Adlai Holler4aa4c602020-10-12 13:58:52 -0400327 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
328
329 ASSERT_SINGLE_OWNER
330
331 if (this->abandoned()) {
332 return;
333 }
334
335 this->checkAsyncWorkCompletion();
336 fMappedBufferManager->process();
337 auto purgeTime = GrStdSteadyClock::now() - msNotUsed;
338
339 fResourceCache->purgeAsNeeded();
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400340 fResourceCache->purgeResourcesNotUsedSince(purgeTime, scratchResourcesOnly);
Adlai Holler4aa4c602020-10-12 13:58:52 -0400341
Adlai Holler4aa4c602020-10-12 13:58:52 -0400342 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
343 // place to purge stale blobs
344 this->getTextBlobCache()->purgeStaleBlobs();
345}
346
347void GrDirectContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
348 ASSERT_SINGLE_OWNER
349
350 if (this->abandoned()) {
351 return;
352 }
353
354 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
355}
356
Adlai Holler3acc69a2020-10-13 08:20:51 -0400357////////////////////////////////////////////////////////////////////////////////
358bool GrDirectContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
359 bool deleteSemaphoresAfterWait) {
Greg Daniel063fdce2021-05-06 19:45:55 +0000360 if (!fGpu || !fGpu->caps()->semaphoreSupport()) {
Adlai Holler3acc69a2020-10-13 08:20:51 -0400361 return false;
362 }
363 GrWrapOwnership ownership =
364 deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
365 for (int i = 0; i < numSemaphores; ++i) {
366 std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
Robert Phillips1a82a4e2021-07-01 10:27:44 -0400367 waitSemaphores[i], GrSemaphoreWrapType::kWillWait, ownership);
Adlai Holler3acc69a2020-10-13 08:20:51 -0400368 // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
369 // to begin with. Therefore, it is fine to not wait on it.
370 if (sema) {
371 fGpu->waitSemaphore(sema.get());
372 }
373 }
374 return true;
375}
Adlai Holler4aa4c602020-10-12 13:58:52 -0400376
Robert Phillips5edf5102020-08-10 16:30:36 -0400377GrSmallPathAtlasMgr* GrDirectContext::onGetSmallPathAtlasMgr() {
Robert Phillipsdb857ce2021-08-17 16:46:41 -0400378#if SK_GPU_V1
Robert Phillips079455c2020-08-11 15:18:46 -0400379 if (!fSmallPathAtlasMgr) {
380 fSmallPathAtlasMgr = std::make_unique<GrSmallPathAtlasMgr>();
381
382 this->priv().addOnFlushCallbackObject(fSmallPathAtlasMgr.get());
383 }
384
385 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
386 return nullptr;
387 }
Robert Phillipsdb857ce2021-08-17 16:46:41 -0400388#endif
Robert Phillips079455c2020-08-11 15:18:46 -0400389
390 return fSmallPathAtlasMgr.get();
Robert Phillips5edf5102020-08-10 16:30:36 -0400391}
392
Adlai Holler3acc69a2020-10-13 08:20:51 -0400393////////////////////////////////////////////////////////////////////////////////
394
395GrSemaphoresSubmitted GrDirectContext::flush(const GrFlushInfo& info) {
396 ASSERT_SINGLE_OWNER
397 if (this->abandoned()) {
398 if (info.fFinishedProc) {
399 info.fFinishedProc(info.fFinishedContext);
400 }
401 if (info.fSubmittedProc) {
402 info.fSubmittedProc(info.fSubmittedContext, false);
403 }
404 return GrSemaphoresSubmitted::kNo;
405 }
406
Robert Phillips80bfda82020-11-12 09:23:36 -0500407 return this->drawingManager()->flushSurfaces({}, SkSurface::BackendSurfaceAccess::kNoAccess,
408 info, nullptr);
Adlai Holler3acc69a2020-10-13 08:20:51 -0400409}
410
411bool GrDirectContext::submit(bool syncCpu) {
412 ASSERT_SINGLE_OWNER
413 if (this->abandoned()) {
414 return false;
415 }
416
417 if (!fGpu) {
418 return false;
419 }
420
421 return fGpu->submitToGpu(syncCpu);
422}
423
424////////////////////////////////////////////////////////////////////////////////
425
426void GrDirectContext::checkAsyncWorkCompletion() {
427 if (fGpu) {
428 fGpu->checkFinishProcs();
429 }
430}
431
Greg Daniela89b4302021-01-29 10:48:40 -0500432void GrDirectContext::syncAllOutstandingGpuWork(bool shouldExecuteWhileAbandoned) {
433 if (fGpu && (!this->abandoned() || shouldExecuteWhileAbandoned)) {
434 fGpu->finishOutstandingGpuWork();
435 this->checkAsyncWorkCompletion();
436 }
437}
438
Adlai Holler3acc69a2020-10-13 08:20:51 -0400439////////////////////////////////////////////////////////////////////////////////
440
441void GrDirectContext::storeVkPipelineCacheData() {
442 if (fGpu) {
443 fGpu->storeVkPipelineCacheData();
444 }
445}
446
447////////////////////////////////////////////////////////////////////////////////
448
449bool GrDirectContext::supportsDistanceFieldText() const {
450 return this->caps()->shaderCaps()->supportsDistanceFieldText();
451}
452
453//////////////////////////////////////////////////////////////////////////////
454
455void GrDirectContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
456 ASSERT_SINGLE_OWNER
457 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
458 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
459 this->getTextBlobCache()->usedBytes());
460}
461
Adlai Holler98dd0042020-10-13 10:04:00 -0400462GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
463 const GrBackendFormat& backendFormat,
464 GrMipmapped mipMapped,
465 GrRenderable renderable,
466 GrProtected isProtected) {
467 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
468 if (this->abandoned()) {
469 return GrBackendTexture();
470 }
471
472 return fGpu->createBackendTexture({width, height}, backendFormat, renderable,
473 mipMapped, isProtected);
474}
475
476GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
477 SkColorType skColorType,
478 GrMipmapped mipMapped,
479 GrRenderable renderable,
480 GrProtected isProtected) {
481 if (this->abandoned()) {
482 return GrBackendTexture();
483 }
484
485 const GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
486
487 return this->createBackendTexture(width, height, format, mipMapped, renderable, isProtected);
488}
489
Brian Salomon71283232021-04-08 12:45:58 -0400490static GrBackendTexture create_and_clear_backend_texture(GrDirectContext* dContext,
491 SkISize dimensions,
492 const GrBackendFormat& backendFormat,
493 GrMipmapped mipMapped,
494 GrRenderable renderable,
495 GrProtected isProtected,
496 sk_sp<GrRefCntedCallback> finishedCallback,
497 std::array<float, 4> color) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400498 GrGpu* gpu = dContext->priv().getGpu();
Adlai Holler98dd0042020-10-13 10:04:00 -0400499 GrBackendTexture beTex = gpu->createBackendTexture(dimensions, backendFormat, renderable,
500 mipMapped, isProtected);
501 if (!beTex.isValid()) {
502 return {};
503 }
504
Brian Salomon71283232021-04-08 12:45:58 -0400505 if (!dContext->priv().getGpu()->clearBackendTexture(beTex,
506 std::move(finishedCallback),
507 color)) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400508 dContext->deleteBackendTexture(beTex);
509 return {};
510 }
511 return beTex;
512}
513
Brian Salomonea1d39b2021-04-01 17:06:52 -0400514static bool update_texture_with_pixmaps(GrDirectContext* context,
515 const SkPixmap src[],
Brian Salomonb5f880a2020-12-07 11:30:16 -0500516 int numLevels,
517 const GrBackendTexture& backendTexture,
518 GrSurfaceOrigin textureOrigin,
519 sk_sp<GrRefCntedCallback> finishedCallback) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400520 GrColorType ct = SkColorTypeToGrColorType(src[0].colorType());
521 const GrBackendFormat& format = backendTexture.getBackendFormat();
Brian Salomon759217e2021-01-31 13:16:39 -0500522
Brian Salomonea1d39b2021-04-01 17:06:52 -0400523 if (!context->priv().caps()->areColorTypeAndFormatCompatible(ct, format)) {
524 return false;
525 }
526
527 auto proxy = context->priv().proxyProvider()->wrapBackendTexture(backendTexture,
528 kBorrow_GrWrapOwnership,
529 GrWrapCacheable::kNo,
530 kRW_GrIOType,
531 std::move(finishedCallback));
532 if (!proxy) {
533 return false;
534 }
535
536 GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(format, ct);
537 GrSurfaceProxyView view(std::move(proxy), textureOrigin, swizzle);
Robert Phillips53eaa642021-08-10 13:49:51 -0400538 skgpu::SurfaceContext surfaceContext(context, std::move(view), src[0].info().colorInfo());
Brian Salomonea1d39b2021-04-01 17:06:52 -0400539 SkAutoSTArray<15, GrCPixmap> tmpSrc(numLevels);
Brian Salomon759217e2021-01-31 13:16:39 -0500540 for (int i = 0; i < numLevels; ++i) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400541 tmpSrc[i] = src[i];
542 }
Brian Salomon75ee7372021-04-06 15:04:35 -0400543 if (!surfaceContext.writePixels(context, tmpSrc.get(), numLevels)) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400544 return false;
Brian Salomon759217e2021-01-31 13:16:39 -0500545 }
546
Brian Salomonea1d39b2021-04-01 17:06:52 -0400547 GrSurfaceProxy* p = surfaceContext.asSurfaceProxy();
548 GrFlushInfo info;
549 context->priv().drawingManager()->flushSurfaces({&p, 1},
550 SkSurface::BackendSurfaceAccess::kNoAccess,
551 info,
552 nullptr);
553 return true;
Brian Salomonb5f880a2020-12-07 11:30:16 -0500554}
555
Adlai Holler98dd0042020-10-13 10:04:00 -0400556GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
557 const GrBackendFormat& backendFormat,
558 const SkColor4f& color,
559 GrMipmapped mipMapped,
560 GrRenderable renderable,
561 GrProtected isProtected,
562 GrGpuFinishedProc finishedProc,
563 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500564 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400565
566 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
567 if (this->abandoned()) {
568 return {};
569 }
570
Brian Salomon71283232021-04-08 12:45:58 -0400571 return create_and_clear_backend_texture(this,
572 {width, height},
573 backendFormat,
574 mipMapped,
575 renderable,
576 isProtected,
577 std::move(finishedCallback),
578 color.array());
Adlai Holler98dd0042020-10-13 10:04:00 -0400579}
580
581GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
582 SkColorType skColorType,
583 const SkColor4f& color,
584 GrMipmapped mipMapped,
585 GrRenderable renderable,
586 GrProtected isProtected,
587 GrGpuFinishedProc finishedProc,
588 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500589 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400590
591 if (this->abandoned()) {
592 return {};
593 }
594
595 GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
596 if (!format.isValid()) {
597 return {};
598 }
599
600 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
601 SkColor4f swizzledColor = this->caps()->getWriteSwizzle(format, grColorType).applyTo(color);
602
Brian Salomon71283232021-04-08 12:45:58 -0400603 return create_and_clear_backend_texture(this,
604 {width, height},
605 format,
606 mipMapped,
607 renderable,
608 isProtected,
609 std::move(finishedCallback),
610 swizzledColor.array());
Adlai Holler98dd0042020-10-13 10:04:00 -0400611}
612
613GrBackendTexture GrDirectContext::createBackendTexture(const SkPixmap srcData[],
614 int numProvidedLevels,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500615 GrSurfaceOrigin textureOrigin,
Adlai Holler98dd0042020-10-13 10:04:00 -0400616 GrRenderable renderable,
617 GrProtected isProtected,
618 GrGpuFinishedProc finishedProc,
619 GrGpuFinishedContext finishedContext) {
620 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
621
Brian Salomon694ff172020-11-04 16:54:28 -0500622 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400623
624 if (this->abandoned()) {
625 return {};
626 }
627
628 if (!srcData || numProvidedLevels <= 0) {
629 return {};
630 }
631
Adlai Holler98dd0042020-10-13 10:04:00 -0400632 SkColorType colorType = srcData[0].colorType();
633
634 GrMipmapped mipMapped = GrMipmapped::kNo;
Adlai Holler98dd0042020-10-13 10:04:00 -0400635 if (numProvidedLevels > 1) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400636 mipMapped = GrMipmapped::kYes;
637 }
638
Adlai Holler98dd0042020-10-13 10:04:00 -0400639 GrBackendFormat backendFormat = this->defaultBackendFormat(colorType, renderable);
Brian Salomonb5f880a2020-12-07 11:30:16 -0500640 GrBackendTexture beTex = this->createBackendTexture(srcData[0].width(),
641 srcData[0].height(),
642 backendFormat,
643 mipMapped,
644 renderable,
645 isProtected);
646 if (!beTex.isValid()) {
647 return {};
648 }
Brian Salomonea1d39b2021-04-01 17:06:52 -0400649 if (!update_texture_with_pixmaps(this,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500650 srcData,
651 numProvidedLevels,
652 beTex,
653 textureOrigin,
654 std::move(finishedCallback))) {
655 this->deleteBackendTexture(beTex);
656 return {};
657 }
658 return beTex;
Adlai Holler98dd0042020-10-13 10:04:00 -0400659}
660
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400661bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
662 const SkColor4f& color,
663 GrGpuFinishedProc finishedProc,
664 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500665 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400666
667 if (this->abandoned()) {
668 return false;
669 }
670
Brian Salomon71283232021-04-08 12:45:58 -0400671 return fGpu->clearBackendTexture(backendTexture, std::move(finishedCallback), color.array());
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400672}
673
674bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
675 SkColorType skColorType,
676 const SkColor4f& color,
677 GrGpuFinishedProc finishedProc,
678 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500679 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400680
681 if (this->abandoned()) {
682 return false;
683 }
684
685 GrBackendFormat format = backendTexture.getBackendFormat();
Brian Osman9f1e06a2021-08-10 14:39:18 -0400686 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400687
688 if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, format)) {
689 return false;
690 }
691
692 GrSwizzle swizzle = this->caps()->getWriteSwizzle(format, grColorType);
Brian Salomon71283232021-04-08 12:45:58 -0400693 SkColor4f swizzledColor = swizzle.applyTo(color);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400694
Brian Salomon71283232021-04-08 12:45:58 -0400695 return fGpu->clearBackendTexture(backendTexture,
696 std::move(finishedCallback),
697 swizzledColor.array());
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400698}
699
700bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
701 const SkPixmap srcData[],
702 int numLevels,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500703 GrSurfaceOrigin textureOrigin,
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400704 GrGpuFinishedProc finishedProc,
705 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500706 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400707
708 if (this->abandoned()) {
709 return false;
710 }
711
712 if (!srcData || numLevels <= 0) {
713 return false;
714 }
715
Brian Salomonea1d39b2021-04-01 17:06:52 -0400716 // If the texture has MIP levels then we require that the full set is overwritten.
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400717 int numExpectedLevels = 1;
718 if (backendTexture.hasMipmaps()) {
719 numExpectedLevels = SkMipmap::ComputeLevelCount(backendTexture.width(),
720 backendTexture.height()) + 1;
721 }
722 if (numLevels != numExpectedLevels) {
723 return false;
724 }
Brian Salomonea1d39b2021-04-01 17:06:52 -0400725 return update_texture_with_pixmaps(this,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500726 srcData,
727 numLevels,
728 backendTexture,
729 textureOrigin,
730 std::move(finishedCallback));
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400731}
732
Adlai Holler64e13832020-10-13 08:21:56 -0400733//////////////////////////////////////////////////////////////////////////////
734
735static GrBackendTexture create_and_update_compressed_backend_texture(
736 GrDirectContext* dContext,
737 SkISize dimensions,
738 const GrBackendFormat& backendFormat,
739 GrMipmapped mipMapped,
740 GrProtected isProtected,
741 sk_sp<GrRefCntedCallback> finishedCallback,
Brian Salomon71283232021-04-08 12:45:58 -0400742 const void* data,
743 size_t size) {
Adlai Holler64e13832020-10-13 08:21:56 -0400744 GrGpu* gpu = dContext->priv().getGpu();
745
746 GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat,
747 mipMapped, isProtected);
748 if (!beTex.isValid()) {
749 return {};
750 }
751
752 if (!dContext->priv().getGpu()->updateCompressedBackendTexture(
Brian Salomon71283232021-04-08 12:45:58 -0400753 beTex, std::move(finishedCallback), data, size)) {
Adlai Holler64e13832020-10-13 08:21:56 -0400754 dContext->deleteBackendTexture(beTex);
755 return {};
756 }
757 return beTex;
758}
759
Brian Salomon71283232021-04-08 12:45:58 -0400760GrBackendTexture GrDirectContext::createCompressedBackendTexture(
761 int width, int height,
762 const GrBackendFormat& backendFormat,
763 const SkColor4f& color,
764 GrMipmapped mipmapped,
765 GrProtected isProtected,
766 GrGpuFinishedProc finishedProc,
767 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400768 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Brian Salomon694ff172020-11-04 16:54:28 -0500769 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400770
771 if (this->abandoned()) {
772 return {};
773 }
774
Brian Salomon71283232021-04-08 12:45:58 -0400775 SkImage::CompressionType compression = GrBackendFormatToCompressionType(backendFormat);
776 if (compression == SkImage::CompressionType::kNone) {
777 return {};
778 }
779
780 size_t size = SkCompressedDataSize(compression,
781 {width, height},
782 nullptr,
783 mipmapped == GrMipmapped::kYes);
784 auto storage = std::make_unique<char[]>(size);
785 GrFillInCompressedData(compression, {width, height}, mipmapped, storage.get(), color);
786 return create_and_update_compressed_backend_texture(this,
787 {width, height},
788 backendFormat,
789 mipmapped,
790 isProtected,
791 std::move(finishedCallback),
792 storage.get(),
793 size);
Adlai Holler64e13832020-10-13 08:21:56 -0400794}
795
Brian Salomon71283232021-04-08 12:45:58 -0400796GrBackendTexture GrDirectContext::createCompressedBackendTexture(
797 int width, int height,
798 SkImage::CompressionType compression,
799 const SkColor4f& color,
800 GrMipmapped mipMapped,
801 GrProtected isProtected,
802 GrGpuFinishedProc finishedProc,
803 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400804 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
805 GrBackendFormat format = this->compressedBackendFormat(compression);
806 return this->createCompressedBackendTexture(width, height, format, color,
807 mipMapped, isProtected, finishedProc,
808 finishedContext);
809}
810
Brian Salomon71283232021-04-08 12:45:58 -0400811GrBackendTexture GrDirectContext::createCompressedBackendTexture(
812 int width, int height,
813 const GrBackendFormat& backendFormat,
814 const void* compressedData,
815 size_t dataSize,
816 GrMipmapped mipMapped,
817 GrProtected isProtected,
818 GrGpuFinishedProc finishedProc,
819 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400820 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Brian Salomon694ff172020-11-04 16:54:28 -0500821 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400822
823 if (this->abandoned()) {
824 return {};
825 }
826
Brian Salomon71283232021-04-08 12:45:58 -0400827 return create_and_update_compressed_backend_texture(this,
828 {width, height},
829 backendFormat,
830 mipMapped,
831 isProtected,
832 std::move(finishedCallback),
833 compressedData,
834 dataSize);
Adlai Holler64e13832020-10-13 08:21:56 -0400835}
836
Brian Salomon71283232021-04-08 12:45:58 -0400837GrBackendTexture GrDirectContext::createCompressedBackendTexture(
838 int width, int height,
839 SkImage::CompressionType compression,
840 const void* data, size_t dataSize,
841 GrMipmapped mipMapped,
842 GrProtected isProtected,
843 GrGpuFinishedProc finishedProc,
844 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400845 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
846 GrBackendFormat format = this->compressedBackendFormat(compression);
847 return this->createCompressedBackendTexture(width, height, format, data, dataSize, mipMapped,
848 isProtected, finishedProc, finishedContext);
849}
850
851bool GrDirectContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
852 const SkColor4f& color,
853 GrGpuFinishedProc finishedProc,
854 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500855 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400856
857 if (this->abandoned()) {
858 return false;
859 }
860
Brian Salomon71283232021-04-08 12:45:58 -0400861 SkImage::CompressionType compression =
862 GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
863 if (compression == SkImage::CompressionType::kNone) {
864 return {};
865 }
866 size_t size = SkCompressedDataSize(compression,
867 backendTexture.dimensions(),
868 nullptr,
869 backendTexture.hasMipmaps());
870 SkAutoMalloc storage(size);
871 GrFillInCompressedData(compression,
872 backendTexture.dimensions(),
873 backendTexture.mipmapped(),
874 static_cast<char*>(storage.get()),
875 color);
876 return fGpu->updateCompressedBackendTexture(backendTexture,
877 std::move(finishedCallback),
878 storage.get(),
879 size);
Adlai Holler64e13832020-10-13 08:21:56 -0400880}
881
882bool GrDirectContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
883 const void* compressedData,
884 size_t dataSize,
885 GrGpuFinishedProc finishedProc,
886 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500887 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400888
889 if (this->abandoned()) {
890 return false;
891 }
892
893 if (!compressedData) {
894 return false;
895 }
896
Brian Salomon71283232021-04-08 12:45:58 -0400897 return fGpu->updateCompressedBackendTexture(backendTexture,
898 std::move(finishedCallback),
899 compressedData,
900 dataSize);
Adlai Holler64e13832020-10-13 08:21:56 -0400901}
902
Adlai Holler6d0745b2020-10-13 13:29:00 -0400903//////////////////////////////////////////////////////////////////////////////
904
905bool GrDirectContext::setBackendTextureState(const GrBackendTexture& backendTexture,
906 const GrBackendSurfaceMutableState& state,
907 GrBackendSurfaceMutableState* previousState,
908 GrGpuFinishedProc finishedProc,
909 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500910 auto callback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler6d0745b2020-10-13 13:29:00 -0400911
912 if (this->abandoned()) {
913 return false;
914 }
915
916 return fGpu->setBackendTextureState(backendTexture, state, previousState, std::move(callback));
917}
918
919
920bool GrDirectContext::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
921 const GrBackendSurfaceMutableState& state,
922 GrBackendSurfaceMutableState* previousState,
923 GrGpuFinishedProc finishedProc,
924 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500925 auto callback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler6d0745b2020-10-13 13:29:00 -0400926
927 if (this->abandoned()) {
928 return false;
929 }
930
931 return fGpu->setBackendRenderTargetState(backendRenderTarget, state, previousState,
932 std::move(callback));
933}
934
935void GrDirectContext::deleteBackendTexture(GrBackendTexture backendTex) {
936 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
937 // For the Vulkan backend we still must destroy the backend texture when the context is
938 // abandoned.
939 if ((this->abandoned() && this->backend() != GrBackendApi::kVulkan) || !backendTex.isValid()) {
940 return;
941 }
942
943 fGpu->deleteBackendTexture(backendTex);
944}
945
946//////////////////////////////////////////////////////////////////////////////
947
948bool GrDirectContext::precompileShader(const SkData& key, const SkData& data) {
949 return fGpu->precompileShader(key, data);
950}
951
952#ifdef SK_ENABLE_DUMP_GPU
953#include "include/core/SkString.h"
954#include "src/utils/SkJSONWriter.h"
955SkString GrDirectContext::dump() const {
956 SkDynamicMemoryWStream stream;
957 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
958 writer.beginObject();
959
960 writer.appendString("backend", GrBackendApiToStr(this->backend()));
961
962 writer.appendName("caps");
963 this->caps()->dumpJSON(&writer);
964
965 writer.appendName("gpu");
966 this->fGpu->dumpJSON(&writer);
967
968 writer.appendName("context");
969 this->dumpJSON(&writer);
970
971 // Flush JSON to the memory stream
972 writer.endObject();
973 writer.flush();
974
975 // Null terminate the JSON data in the memory stream
976 stream.write8(0);
977
978 // Allocate a string big enough to hold all the data, then copy out of the stream
979 SkString result(stream.bytesWritten());
980 stream.copyToAndReset(result.writable_str());
981 return result;
982}
983#endif
984
John Rosascoa9b348f2019-11-08 13:18:15 -0800985#ifdef SK_GL
Robert Phillipsc7228c62020-07-14 12:57:39 -0400986
Robert Phillipsf4f80112020-07-13 16:13:31 -0400987/*************************************************************************************************/
988sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500989 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500990 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500991}
992
Robert Phillipsf4f80112020-07-13 16:13:31 -0400993sk_sp<GrDirectContext> GrDirectContext::MakeGL(const GrContextOptions& options) {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400994 return MakeGL(nullptr, options);
995}
996
Robert Phillipsf4f80112020-07-13 16:13:31 -0400997sk_sp<GrDirectContext> GrDirectContext::MakeGL() {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400998 GrContextOptions defaultOptions;
999 return MakeGL(nullptr, defaultOptions);
1000}
1001
Brian Salomon24069eb2020-06-24 10:19:52 -04001002#if GR_TEST_UTILS
1003GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
1004 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
1005 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
1006 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
1007 // on the thing it captures. So we leak the context.
1008 struct GetErrorContext {
1009 SkRandom fRandom;
1010 GrGLFunction<GrGLGetErrorFn> fGetError;
1011 };
1012
1013 auto errorContext = new GetErrorContext;
1014
1015#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
1016 __lsan_ignore_object(errorContext);
1017#endif
1018
1019 errorContext->fGetError = original;
1020
1021 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
1022 GrGLenum error = errorContext->fGetError();
1023 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
1024 error = GR_GL_OUT_OF_MEMORY;
1025 }
1026 return error;
1027 });
1028}
1029#endif
1030
Robert Phillipsf4f80112020-07-13 16:13:31 -04001031sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
1032 const GrContextOptions& options) {
1033 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -04001034#if GR_TEST_UTILS
1035 if (options.fRandomGLOOM) {
1036 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
1037 copy->fFunctions.fGetError =
1038 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
1039#if GR_GL_CHECK_ERROR
1040 // Suppress logging GL errors since we'll be synthetically generating them.
1041 copy->suppressErrorLogging();
1042#endif
1043 glInterface = std::move(copy);
1044 }
1045#endif
Robert Phillipsf4f80112020-07-13 16:13:31 -04001046 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct.get());
1047 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001048 return nullptr;
1049 }
Robert Phillipsf4f80112020-07-13 16:13:31 -04001050 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001051}
John Rosascoa9b348f2019-11-08 13:18:15 -08001052#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -05001053
Robert Phillipsf4f80112020-07-13 16:13:31 -04001054/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001055sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions) {
1056 GrContextOptions defaultOptions;
1057 return MakeMock(mockOptions, defaultOptions);
1058}
1059
1060sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions,
1061 const GrContextOptions& options) {
1062 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMock, options));
1063
1064 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
1065 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001066 return nullptr;
1067 }
Chris Daltona378b452019-12-11 13:24:11 -05001068
Robert Phillipsf4f80112020-07-13 16:13:31 -04001069 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001070}
1071
Greg Danielb4d89562018-10-03 18:44:49 +00001072#ifdef SK_VULKAN
Robert Phillipsf4f80112020-07-13 16:13:31 -04001073/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001074sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext) {
1075 GrContextOptions defaultOptions;
1076 return MakeVulkan(backendContext, defaultOptions);
1077}
1078
1079sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext,
1080 const GrContextOptions& options) {
1081 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kVulkan, options));
1082
1083 direct->fGpu = GrVkGpu::Make(backendContext, options, direct.get());
1084 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001085 return nullptr;
1086 }
1087
Robert Phillipsf4f80112020-07-13 16:13:31 -04001088 return direct;
Greg Danielb4d89562018-10-03 18:44:49 +00001089}
Robert Phillipsf4f80112020-07-13 16:13:31 -04001090#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -05001091
1092#ifdef SK_METAL
Robert Phillipsf4f80112020-07-13 16:13:31 -04001093/*************************************************************************************************/
Jim Van Verth351c9b52020-11-12 15:21:11 -05001094sk_sp<GrDirectContext> GrDirectContext::MakeMetal(const GrMtlBackendContext& backendContext) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001095 GrContextOptions defaultOptions;
Jim Van Verth351c9b52020-11-12 15:21:11 -05001096 return MakeMetal(backendContext, defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -05001097}
1098
Jim Van Verth351c9b52020-11-12 15:21:11 -05001099sk_sp<GrDirectContext> GrDirectContext::MakeMetal(const GrMtlBackendContext& backendContext,
1100 const GrContextOptions& options) {
Robert Phillipsf4f80112020-07-13 16:13:31 -04001101 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -05001102
Jim Van Verth351c9b52020-11-12 15:21:11 -05001103 direct->fGpu = GrMtlTrampoline::MakeGpu(backendContext, options, direct.get());
Robert Phillipsf4f80112020-07-13 16:13:31 -04001104 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001105 return nullptr;
1106 }
Timothy Liang4e85e802018-06-28 16:37:18 -04001107
Robert Phillipsf4f80112020-07-13 16:13:31 -04001108 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001109}
Jim Van Verth351c9b52020-11-12 15:21:11 -05001110
1111// deprecated
1112sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue) {
1113 GrContextOptions defaultOptions;
1114 return MakeMetal(device, queue, defaultOptions);
1115}
1116
1117// deprecated
1118// remove include/gpu/mtl/GrMtlBackendContext.h, above, when removed
1119sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue,
1120 const GrContextOptions& options) {
1121 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
1122 GrMtlBackendContext backendContext = {};
1123 backendContext.fDevice.reset(device);
1124 backendContext.fQueue.reset(queue);
1125
1126 return GrDirectContext::MakeMetal(backendContext, options);
1127}
Robert Phillipsa3457b82018-03-08 11:30:12 -05001128#endif
1129
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001130#ifdef SK_DIRECT3D
Robert Phillipsf4f80112020-07-13 16:13:31 -04001131/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001132sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
1133 GrContextOptions defaultOptions;
1134 return MakeDirect3D(backendContext, defaultOptions);
1135}
1136
1137sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
1138 const GrContextOptions& options) {
1139 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDirect3D, options));
1140
1141 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
1142 if (!direct->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -05001143 return nullptr;
1144 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001145
Robert Phillipsf4f80112020-07-13 16:13:31 -04001146 return direct;
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001147}
1148#endif
1149
Stephen White985741a2019-07-18 11:43:45 -04001150#ifdef SK_DAWN
Robert Phillipsf4f80112020-07-13 16:13:31 -04001151/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001152sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -04001153 GrContextOptions defaultOptions;
1154 return MakeDawn(device, defaultOptions);
1155}
1156
Robert Phillipsf4f80112020-07-13 16:13:31 -04001157sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device,
1158 const GrContextOptions& options) {
1159 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDawn, options));
Stephen White985741a2019-07-18 11:43:45 -04001160
Robert Phillipsf4f80112020-07-13 16:13:31 -04001161 direct->fGpu = GrDawnGpu::Make(device, options, direct.get());
1162 if (!direct->init()) {
Stephen White985741a2019-07-18 11:43:45 -04001163 return nullptr;
1164 }
1165
Robert Phillipsf4f80112020-07-13 16:13:31 -04001166 return direct;
Stephen White985741a2019-07-18 11:43:45 -04001167}
Robert Phillipsf4f80112020-07-13 16:13:31 -04001168
Stephen White985741a2019-07-18 11:43:45 -04001169#endif