blob: b7ba67405ed2af6dca367a38f7da220db58bc338 [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"
Greg Daniel84261652021-09-19 17:53:40 -040024#include "src/gpu/GrThreadSafePipelineBuilder.h"
Robert Phillips53eaa642021-08-10 13:49:51 -040025#include "src/gpu/SurfaceContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/effects/GrSkSLFP.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#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
Robert Phillipsde60d7a2021-09-13 17:17:45 -040032#include "src/gpu/ops/SmallPathAtlasMgr.h"
Robert Phillipsdb857ce2021-08-17 16:46:41 -040033#else
34// A vestigial definition for v2 that will never be instantiated
Robert Phillipsde60d7a2021-09-13 17:17:45 -040035namespace skgpu::v1 {
36class SmallPathAtlasMgr {
Robert Phillipsdb857ce2021-08-17 16:46:41 -040037public:
Robert Phillipsde60d7a2021-09-13 17:17:45 -040038 SmallPathAtlasMgr() { SkASSERT(0); }
Robert Phillipsdb857ce2021-08-17 16:46:41 -040039 void reset() { SkASSERT(0); }
40};
Robert Phillipsde60d7a2021-09-13 17:17:45 -040041}
Robert Phillipsdb857ce2021-08-17 16:46:41 -040042#endif
Greg Daniel84261652021-09-19 17:53:40 -040043#ifdef SK_GL
44#include "src/gpu/gl/GrGLGpu.h"
45#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -050046#ifdef SK_METAL
Jim Van Verth351c9b52020-11-12 15:21:11 -050047#include "include/gpu/mtl/GrMtlBackendContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050048#include "src/gpu/mtl/GrMtlTrampoline.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050049#endif
50#ifdef SK_VULKAN
Mike Kleinc0bd9f92019-04-23 12:05:21 -050051#include "src/gpu/vk/GrVkGpu.h"
Robert Phillipsa3457b82018-03-08 11:30:12 -050052#endif
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -050053#ifdef SK_DIRECT3D
54#include "src/gpu/d3d/GrD3DGpu.h"
55#endif
Stephen White985741a2019-07-18 11:43:45 -040056#ifdef SK_DAWN
Mike Klein52337de2019-07-25 09:00:52 -050057#include "src/gpu/dawn/GrDawnGpu.h"
Stephen White985741a2019-07-18 11:43:45 -040058#endif
Adlai Holler6d0745b2020-10-13 13:29:00 -040059#include <memory>
Robert Phillipsa3457b82018-03-08 11:30:12 -050060
Brian Salomon24069eb2020-06-24 10:19:52 -040061#if GR_TEST_UTILS
62# include "include/utils/SkRandom.h"
63# if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
64# include <sanitizer/lsan_interface.h>
65# endif
66#endif
67
Adlai Holler9555f292020-10-09 09:41:14 -040068#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
69
Robert Phillipse7a959d2021-03-11 14:44:42 -050070GrDirectContext::DirectContextID GrDirectContext::DirectContextID::Next() {
Robert Phillipsedff4672021-03-11 09:16:25 -050071 static std::atomic<uint32_t> nextID{1};
72 uint32_t id;
73 do {
74 id = nextID.fetch_add(1, std::memory_order_relaxed);
75 } while (id == SK_InvalidUniqueID);
76 return DirectContextID(id);
77}
78
Robert Phillipsad248452020-06-30 09:27:52 -040079GrDirectContext::GrDirectContext(GrBackendApi backend, const GrContextOptions& options)
Robert Phillips23070582021-03-31 17:04:48 -040080 : INHERITED(GrContextThreadSafeProxyPriv::Make(backend, options), false)
Robert Phillipse7a959d2021-03-11 14:44:42 -050081 , fDirectContextID(DirectContextID::Next()) {
Robert Phillipsad248452020-06-30 09:27:52 -040082}
Robert Phillipsa3457b82018-03-08 11:30:12 -050083
Robert Phillipsad248452020-06-30 09:27:52 -040084GrDirectContext::~GrDirectContext() {
Adlai Holler9555f292020-10-09 09:41:14 -040085 ASSERT_SINGLE_OWNER
Robert Phillipsad248452020-06-30 09:27:52 -040086 // this if-test protects against the case where the context is being destroyed
87 // before having been fully created
Adlai Holler9555f292020-10-09 09:41:14 -040088 if (fGpu) {
Greg Daniel0a2464f2020-05-14 15:45:44 -040089 this->flushAndSubmit();
Robert Phillipsa3457b82018-03-08 11:30:12 -050090 }
Adlai Holler9555f292020-10-09 09:41:14 -040091
Greg Daniela89b4302021-01-29 10:48:40 -050092 // We need to make sure all work is finished on the gpu before we start releasing resources.
93 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/false);
94
Adlai Holler9555f292020-10-09 09:41:14 -040095 this->destroyDrawingManager();
Adlai Holler9555f292020-10-09 09:41:14 -040096
97 // Ideally we could just let the ptr drop, but resource cache queries this ptr in releaseAll.
98 if (fResourceCache) {
99 fResourceCache->releaseAll();
100 }
Brian Salomon91a88f02021-02-04 15:34:32 -0500101 // This has to be after GrResourceCache::releaseAll so that other threads that are holding
102 // async pixel result don't try to destroy buffers off thread.
103 fMappedBufferManager.reset();
Robert Phillipsad248452020-06-30 09:27:52 -0400104}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500105
Adlai Holler61a591c2020-10-12 12:38:33 -0400106sk_sp<GrContextThreadSafeProxy> GrDirectContext::threadSafeProxy() {
107 return INHERITED::threadSafeProxy();
108}
109
Adlai Hollera7a40442020-10-09 09:49:42 -0400110void GrDirectContext::resetGLTextureBindings() {
111 if (this->abandoned() || this->backend() != GrBackendApi::kOpenGL) {
112 return;
113 }
114 fGpu->resetTextureBindings();
115}
116
117void GrDirectContext::resetContext(uint32_t state) {
118 ASSERT_SINGLE_OWNER
119 fGpu->markContextDirty(state);
120}
121
Robert Phillipsad248452020-06-30 09:27:52 -0400122void GrDirectContext::abandonContext() {
Adlai Hollera7a40442020-10-09 09:49:42 -0400123 if (INHERITED::abandoned()) {
124 return;
125 }
126
Robert Phillipsad248452020-06-30 09:27:52 -0400127 INHERITED::abandonContext();
Adlai Hollera7a40442020-10-09 09:49:42 -0400128
Greg Daniela89b4302021-01-29 10:48:40 -0500129 // We need to make sure all work is finished on the gpu before we start releasing resources.
130 this->syncAllOutstandingGpuWork(this->caps()->mustSyncGpuDuringAbandon());
131
Adlai Hollera7a40442020-10-09 09:49:42 -0400132 fStrikeCache->freeAll();
133
134 fMappedBufferManager->abandon();
135
136 fResourceProvider->abandon();
137
Robert Phillipseb999bc2020-11-03 08:41:47 -0500138 // abandon first so destructors don't try to free the resources in the API.
Adlai Hollera7a40442020-10-09 09:49:42 -0400139 fResourceCache->abandonAll();
140
141 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
142
Brian Salomon91a88f02021-02-04 15:34:32 -0500143 // Must be after GrResourceCache::abandonAll().
Adlai Hollera7a40442020-10-09 09:49:42 -0400144 fMappedBufferManager.reset();
Brian Salomon91a88f02021-02-04 15:34:32 -0500145
Robert Phillips079455c2020-08-11 15:18:46 -0400146 if (fSmallPathAtlasMgr) {
147 fSmallPathAtlasMgr->reset();
148 }
Robert Phillipsad248452020-06-30 09:27:52 -0400149 fAtlasManager->freeAll();
150}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500151
Adlai Hollera7a40442020-10-09 09:49:42 -0400152bool GrDirectContext::abandoned() {
153 if (INHERITED::abandoned()) {
154 return true;
155 }
156
157 if (fGpu && fGpu->isDeviceLost()) {
158 this->abandonContext();
159 return true;
160 }
161 return false;
162}
163
Adlai Holler61a591c2020-10-12 12:38:33 -0400164bool GrDirectContext::oomed() { return fGpu ? fGpu->checkAndResetOOMed() : false; }
165
Robert Phillipsad248452020-06-30 09:27:52 -0400166void GrDirectContext::releaseResourcesAndAbandonContext() {
Adlai Holler61a591c2020-10-12 12:38:33 -0400167 if (INHERITED::abandoned()) {
168 return;
169 }
170
171 INHERITED::abandonContext();
172
Greg Daniela89b4302021-01-29 10:48:40 -0500173 // We need to make sure all work is finished on the gpu before we start releasing resources.
174 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/true);
175
Adlai Holler61a591c2020-10-12 12:38:33 -0400176 fResourceProvider->abandon();
177
178 // Release all resources in the backend 3D API.
179 fResourceCache->releaseAll();
180
Brian Salomon91a88f02021-02-04 15:34:32 -0500181 // Must be after GrResourceCache::releaseAll().
182 fMappedBufferManager.reset();
183
Adlai Holler61a591c2020-10-12 12:38:33 -0400184 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
Robert Phillips079455c2020-08-11 15:18:46 -0400185 if (fSmallPathAtlasMgr) {
186 fSmallPathAtlasMgr->reset();
187 }
Robert Phillipsad248452020-06-30 09:27:52 -0400188 fAtlasManager->freeAll();
189}
Robert Phillips6db27c22019-05-01 10:43:56 -0400190
Robert Phillipsad248452020-06-30 09:27:52 -0400191void GrDirectContext::freeGpuResources() {
Adlai Holler4aa4c602020-10-12 13:58:52 -0400192 ASSERT_SINGLE_OWNER
193
194 if (this->abandoned()) {
195 return;
196 }
197
Robert Phillipsad248452020-06-30 09:27:52 -0400198 this->flushAndSubmit();
Robert Phillips079455c2020-08-11 15:18:46 -0400199 if (fSmallPathAtlasMgr) {
200 fSmallPathAtlasMgr->reset();
201 }
Robert Phillipsad248452020-06-30 09:27:52 -0400202 fAtlasManager->freeAll();
Robert Phillips56181ba2019-03-08 12:00:45 -0500203
Adlai Holler4aa4c602020-10-12 13:58:52 -0400204 // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
205 // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
206 fStrikeCache->freeAll();
207
208 this->drawingManager()->freeGpuResources();
209
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400210 fResourceCache->purgeUnlockedResources();
Robert Phillipsad248452020-06-30 09:27:52 -0400211}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500212
Robert Phillipsad248452020-06-30 09:27:52 -0400213bool GrDirectContext::init() {
Adlai Holler9555f292020-10-09 09:41:14 -0400214 ASSERT_SINGLE_OWNER
215 if (!fGpu) {
Robert Phillipsad248452020-06-30 09:27:52 -0400216 return false;
Robert Phillipsa3457b82018-03-08 11:30:12 -0500217 }
218
Robert Phillipsae67c522021-03-03 11:03:38 -0500219 fThreadSafeProxy->priv().init(fGpu->refCaps(), fGpu->refPipelineBuilder());
Robert Phillipsad248452020-06-30 09:27:52 -0400220 if (!INHERITED::init()) {
221 return false;
222 }
Robert Phillipsa3457b82018-03-08 11:30:12 -0500223
Adlai Holler9555f292020-10-09 09:41:14 -0400224 SkASSERT(this->getTextBlobCache());
225 SkASSERT(this->threadSafeCache());
226
227 fStrikeCache = std::make_unique<GrStrikeCache>();
Robert Phillipsd074b622021-03-15 08:49:24 -0400228 fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(),
229 this->directContextID(),
230 this->contextID());
Adlai Holler9555f292020-10-09 09:41:14 -0400231 fResourceCache->setProxyProvider(this->proxyProvider());
232 fResourceCache->setThreadSafeCache(this->threadSafeCache());
Adlai Hollerb34270e2021-04-16 11:23:52 -0400233#if GR_TEST_UTILS
234 if (this->options().fResourceCacheLimitOverride != -1) {
235 this->setResourceCacheLimit(this->options().fResourceCacheLimitOverride);
236 }
237#endif
Adlai Holler9555f292020-10-09 09:41:14 -0400238 fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
239 this->singleOwner());
Robert Phillips82ad7af2021-03-11 16:00:10 -0500240 fMappedBufferManager = std::make_unique<GrClientMappedBufferManager>(this->directContextID());
Adlai Holler9555f292020-10-09 09:41:14 -0400241
242 fDidTestPMConversions = false;
243
244 // DDL TODO: we need to think through how the task group & persistent cache
245 // get passed on to/shared between all the DDLRecorders created with this context.
246 if (this->options().fExecutor) {
247 fTaskGroup = std::make_unique<SkTaskGroup>(*this->options().fExecutor);
248 }
249
250 fPersistentCache = this->options().fPersistentCache;
Adlai Holler9555f292020-10-09 09:41:14 -0400251
Robert Phillipsad248452020-06-30 09:27:52 -0400252 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
253 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
254 // multitexturing supported only if range can represent the index + texcoords fully
255 !(this->caps()->shaderCaps()->floatIs32Bits() ||
256 this->caps()->shaderCaps()->integerSupport())) {
257 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
258 } else {
259 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
260 }
261
262 GrProxyProvider* proxyProvider = this->priv().proxyProvider();
263
Robert Phillips3262bc82020-08-10 12:11:58 -0400264 fAtlasManager = std::make_unique<GrAtlasManager>(proxyProvider,
265 this->options().fGlyphCacheTextureMaximumBytes,
266 allowMultitexturing);
267 this->priv().addOnFlushCallbackObject(fAtlasManager.get());
Robert Phillipsad248452020-06-30 09:27:52 -0400268
269 return true;
270}
Robert Phillipsa3457b82018-03-08 11:30:12 -0500271
Adlai Holler3a508e92020-10-12 13:58:01 -0400272void GrDirectContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
273 ASSERT_SINGLE_OWNER
274
275 if (resourceCount) {
276 *resourceCount = fResourceCache->getBudgetedResourceCount();
277 }
278 if (resourceBytes) {
279 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
280 }
281}
282
283size_t GrDirectContext::getResourceCachePurgeableBytes() const {
284 ASSERT_SINGLE_OWNER
285 return fResourceCache->getPurgeableBytes();
286}
287
288void GrDirectContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
289 ASSERT_SINGLE_OWNER
290 if (maxResources) {
291 *maxResources = -1;
292 }
293 if (maxResourceBytes) {
294 *maxResourceBytes = this->getResourceCacheLimit();
295 }
296}
297
298size_t GrDirectContext::getResourceCacheLimit() const {
299 ASSERT_SINGLE_OWNER
300 return fResourceCache->getMaxResourceBytes();
301}
302
303void GrDirectContext::setResourceCacheLimits(int unused, size_t maxResourceBytes) {
304 ASSERT_SINGLE_OWNER
305 this->setResourceCacheLimit(maxResourceBytes);
306}
307
308void GrDirectContext::setResourceCacheLimit(size_t maxResourceBytes) {
309 ASSERT_SINGLE_OWNER
310 fResourceCache->setLimit(maxResourceBytes);
311}
312
Adlai Holler4aa4c602020-10-12 13:58:52 -0400313void GrDirectContext::purgeUnlockedResources(bool scratchResourcesOnly) {
314 ASSERT_SINGLE_OWNER
315
316 if (this->abandoned()) {
317 return;
318 }
319
320 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
321 fResourceCache->purgeAsNeeded();
322
323 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
324 // place to purge stale blobs
325 this->getTextBlobCache()->purgeStaleBlobs();
Greg Daniel428523f2021-03-30 14:22:54 -0400326
327 fGpu->releaseUnlockedBackendObjects();
Adlai Holler4aa4c602020-10-12 13:58:52 -0400328}
329
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400330void GrDirectContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed,
331 bool scratchResourcesOnly) {
Adlai Holler4aa4c602020-10-12 13:58:52 -0400332 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
333
334 ASSERT_SINGLE_OWNER
335
336 if (this->abandoned()) {
337 return;
338 }
339
340 this->checkAsyncWorkCompletion();
341 fMappedBufferManager->process();
342 auto purgeTime = GrStdSteadyClock::now() - msNotUsed;
343
344 fResourceCache->purgeAsNeeded();
Michael Ludwig9d1cc052021-06-09 20:49:48 -0400345 fResourceCache->purgeResourcesNotUsedSince(purgeTime, scratchResourcesOnly);
Adlai Holler4aa4c602020-10-12 13:58:52 -0400346
Adlai Holler4aa4c602020-10-12 13:58:52 -0400347 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
348 // place to purge stale blobs
349 this->getTextBlobCache()->purgeStaleBlobs();
350}
351
352void GrDirectContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
353 ASSERT_SINGLE_OWNER
354
355 if (this->abandoned()) {
356 return;
357 }
358
359 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
360}
361
Adlai Holler3acc69a2020-10-13 08:20:51 -0400362////////////////////////////////////////////////////////////////////////////////
363bool GrDirectContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
364 bool deleteSemaphoresAfterWait) {
Greg Daniel063fdce2021-05-06 19:45:55 +0000365 if (!fGpu || !fGpu->caps()->semaphoreSupport()) {
Adlai Holler3acc69a2020-10-13 08:20:51 -0400366 return false;
367 }
368 GrWrapOwnership ownership =
369 deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
370 for (int i = 0; i < numSemaphores; ++i) {
371 std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
Robert Phillips1a82a4e2021-07-01 10:27:44 -0400372 waitSemaphores[i], GrSemaphoreWrapType::kWillWait, ownership);
Adlai Holler3acc69a2020-10-13 08:20:51 -0400373 // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
374 // to begin with. Therefore, it is fine to not wait on it.
375 if (sema) {
376 fGpu->waitSemaphore(sema.get());
377 }
378 }
379 return true;
380}
Adlai Holler4aa4c602020-10-12 13:58:52 -0400381
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400382skgpu::v1::SmallPathAtlasMgr* GrDirectContext::onGetSmallPathAtlasMgr() {
Robert Phillipsdb857ce2021-08-17 16:46:41 -0400383#if SK_GPU_V1
Robert Phillips079455c2020-08-11 15:18:46 -0400384 if (!fSmallPathAtlasMgr) {
Robert Phillipsde60d7a2021-09-13 17:17:45 -0400385 fSmallPathAtlasMgr = std::make_unique<skgpu::v1::SmallPathAtlasMgr>();
Robert Phillips079455c2020-08-11 15:18:46 -0400386
387 this->priv().addOnFlushCallbackObject(fSmallPathAtlasMgr.get());
388 }
389
390 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
391 return nullptr;
392 }
Robert Phillipsdb857ce2021-08-17 16:46:41 -0400393#endif
Robert Phillips079455c2020-08-11 15:18:46 -0400394
395 return fSmallPathAtlasMgr.get();
Robert Phillips5edf5102020-08-10 16:30:36 -0400396}
397
Adlai Holler3acc69a2020-10-13 08:20:51 -0400398////////////////////////////////////////////////////////////////////////////////
399
400GrSemaphoresSubmitted GrDirectContext::flush(const GrFlushInfo& info) {
401 ASSERT_SINGLE_OWNER
402 if (this->abandoned()) {
403 if (info.fFinishedProc) {
404 info.fFinishedProc(info.fFinishedContext);
405 }
406 if (info.fSubmittedProc) {
407 info.fSubmittedProc(info.fSubmittedContext, false);
408 }
409 return GrSemaphoresSubmitted::kNo;
410 }
411
Robert Phillips80bfda82020-11-12 09:23:36 -0500412 return this->drawingManager()->flushSurfaces({}, SkSurface::BackendSurfaceAccess::kNoAccess,
413 info, nullptr);
Adlai Holler3acc69a2020-10-13 08:20:51 -0400414}
415
416bool GrDirectContext::submit(bool syncCpu) {
417 ASSERT_SINGLE_OWNER
418 if (this->abandoned()) {
419 return false;
420 }
421
422 if (!fGpu) {
423 return false;
424 }
425
426 return fGpu->submitToGpu(syncCpu);
427}
428
429////////////////////////////////////////////////////////////////////////////////
430
431void GrDirectContext::checkAsyncWorkCompletion() {
432 if (fGpu) {
433 fGpu->checkFinishProcs();
434 }
435}
436
Greg Daniela89b4302021-01-29 10:48:40 -0500437void GrDirectContext::syncAllOutstandingGpuWork(bool shouldExecuteWhileAbandoned) {
438 if (fGpu && (!this->abandoned() || shouldExecuteWhileAbandoned)) {
439 fGpu->finishOutstandingGpuWork();
440 this->checkAsyncWorkCompletion();
441 }
442}
443
Adlai Holler3acc69a2020-10-13 08:20:51 -0400444////////////////////////////////////////////////////////////////////////////////
445
446void GrDirectContext::storeVkPipelineCacheData() {
447 if (fGpu) {
448 fGpu->storeVkPipelineCacheData();
449 }
450}
451
452////////////////////////////////////////////////////////////////////////////////
453
454bool GrDirectContext::supportsDistanceFieldText() const {
455 return this->caps()->shaderCaps()->supportsDistanceFieldText();
456}
457
458//////////////////////////////////////////////////////////////////////////////
459
460void GrDirectContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
461 ASSERT_SINGLE_OWNER
462 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
463 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
464 this->getTextBlobCache()->usedBytes());
465}
466
Adlai Holler98dd0042020-10-13 10:04:00 -0400467GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
468 const GrBackendFormat& backendFormat,
469 GrMipmapped mipMapped,
470 GrRenderable renderable,
471 GrProtected isProtected) {
472 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
473 if (this->abandoned()) {
474 return GrBackendTexture();
475 }
476
477 return fGpu->createBackendTexture({width, height}, backendFormat, renderable,
478 mipMapped, isProtected);
479}
480
481GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
482 SkColorType skColorType,
483 GrMipmapped mipMapped,
484 GrRenderable renderable,
485 GrProtected isProtected) {
486 if (this->abandoned()) {
487 return GrBackendTexture();
488 }
489
490 const GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
491
492 return this->createBackendTexture(width, height, format, mipMapped, renderable, isProtected);
493}
494
Brian Salomon71283232021-04-08 12:45:58 -0400495static GrBackendTexture create_and_clear_backend_texture(GrDirectContext* dContext,
496 SkISize dimensions,
497 const GrBackendFormat& backendFormat,
498 GrMipmapped mipMapped,
499 GrRenderable renderable,
500 GrProtected isProtected,
501 sk_sp<GrRefCntedCallback> finishedCallback,
502 std::array<float, 4> color) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400503 GrGpu* gpu = dContext->priv().getGpu();
Adlai Holler98dd0042020-10-13 10:04:00 -0400504 GrBackendTexture beTex = gpu->createBackendTexture(dimensions, backendFormat, renderable,
505 mipMapped, isProtected);
506 if (!beTex.isValid()) {
507 return {};
508 }
509
Brian Salomon71283232021-04-08 12:45:58 -0400510 if (!dContext->priv().getGpu()->clearBackendTexture(beTex,
511 std::move(finishedCallback),
512 color)) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400513 dContext->deleteBackendTexture(beTex);
514 return {};
515 }
516 return beTex;
517}
518
Brian Salomonea1d39b2021-04-01 17:06:52 -0400519static bool update_texture_with_pixmaps(GrDirectContext* context,
520 const SkPixmap src[],
Brian Salomonb5f880a2020-12-07 11:30:16 -0500521 int numLevels,
522 const GrBackendTexture& backendTexture,
523 GrSurfaceOrigin textureOrigin,
524 sk_sp<GrRefCntedCallback> finishedCallback) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400525 GrColorType ct = SkColorTypeToGrColorType(src[0].colorType());
526 const GrBackendFormat& format = backendTexture.getBackendFormat();
Brian Salomon759217e2021-01-31 13:16:39 -0500527
Brian Salomonea1d39b2021-04-01 17:06:52 -0400528 if (!context->priv().caps()->areColorTypeAndFormatCompatible(ct, format)) {
529 return false;
530 }
531
532 auto proxy = context->priv().proxyProvider()->wrapBackendTexture(backendTexture,
533 kBorrow_GrWrapOwnership,
534 GrWrapCacheable::kNo,
535 kRW_GrIOType,
536 std::move(finishedCallback));
537 if (!proxy) {
538 return false;
539 }
540
541 GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(format, ct);
542 GrSurfaceProxyView view(std::move(proxy), textureOrigin, swizzle);
Robert Phillips53eaa642021-08-10 13:49:51 -0400543 skgpu::SurfaceContext surfaceContext(context, std::move(view), src[0].info().colorInfo());
Brian Salomonea1d39b2021-04-01 17:06:52 -0400544 SkAutoSTArray<15, GrCPixmap> tmpSrc(numLevels);
Brian Salomon759217e2021-01-31 13:16:39 -0500545 for (int i = 0; i < numLevels; ++i) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400546 tmpSrc[i] = src[i];
547 }
Brian Salomon75ee7372021-04-06 15:04:35 -0400548 if (!surfaceContext.writePixels(context, tmpSrc.get(), numLevels)) {
Brian Salomonea1d39b2021-04-01 17:06:52 -0400549 return false;
Brian Salomon759217e2021-01-31 13:16:39 -0500550 }
551
Brian Salomonea1d39b2021-04-01 17:06:52 -0400552 GrSurfaceProxy* p = surfaceContext.asSurfaceProxy();
553 GrFlushInfo info;
554 context->priv().drawingManager()->flushSurfaces({&p, 1},
555 SkSurface::BackendSurfaceAccess::kNoAccess,
556 info,
557 nullptr);
558 return true;
Brian Salomonb5f880a2020-12-07 11:30:16 -0500559}
560
Adlai Holler98dd0042020-10-13 10:04:00 -0400561GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
562 const GrBackendFormat& backendFormat,
563 const SkColor4f& color,
564 GrMipmapped mipMapped,
565 GrRenderable renderable,
566 GrProtected isProtected,
567 GrGpuFinishedProc finishedProc,
568 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500569 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400570
571 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
572 if (this->abandoned()) {
573 return {};
574 }
575
Brian Salomon71283232021-04-08 12:45:58 -0400576 return create_and_clear_backend_texture(this,
577 {width, height},
578 backendFormat,
579 mipMapped,
580 renderable,
581 isProtected,
582 std::move(finishedCallback),
583 color.array());
Adlai Holler98dd0042020-10-13 10:04:00 -0400584}
585
586GrBackendTexture GrDirectContext::createBackendTexture(int width, int height,
587 SkColorType skColorType,
588 const SkColor4f& color,
589 GrMipmapped mipMapped,
590 GrRenderable renderable,
591 GrProtected isProtected,
592 GrGpuFinishedProc finishedProc,
593 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500594 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400595
596 if (this->abandoned()) {
597 return {};
598 }
599
600 GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
601 if (!format.isValid()) {
602 return {};
603 }
604
605 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
606 SkColor4f swizzledColor = this->caps()->getWriteSwizzle(format, grColorType).applyTo(color);
607
Brian Salomon71283232021-04-08 12:45:58 -0400608 return create_and_clear_backend_texture(this,
609 {width, height},
610 format,
611 mipMapped,
612 renderable,
613 isProtected,
614 std::move(finishedCallback),
615 swizzledColor.array());
Adlai Holler98dd0042020-10-13 10:04:00 -0400616}
617
618GrBackendTexture GrDirectContext::createBackendTexture(const SkPixmap srcData[],
619 int numProvidedLevels,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500620 GrSurfaceOrigin textureOrigin,
Adlai Holler98dd0042020-10-13 10:04:00 -0400621 GrRenderable renderable,
622 GrProtected isProtected,
623 GrGpuFinishedProc finishedProc,
624 GrGpuFinishedContext finishedContext) {
625 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
626
Brian Salomon694ff172020-11-04 16:54:28 -0500627 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler98dd0042020-10-13 10:04:00 -0400628
629 if (this->abandoned()) {
630 return {};
631 }
632
633 if (!srcData || numProvidedLevels <= 0) {
634 return {};
635 }
636
Adlai Holler98dd0042020-10-13 10:04:00 -0400637 SkColorType colorType = srcData[0].colorType();
638
639 GrMipmapped mipMapped = GrMipmapped::kNo;
Adlai Holler98dd0042020-10-13 10:04:00 -0400640 if (numProvidedLevels > 1) {
Adlai Holler98dd0042020-10-13 10:04:00 -0400641 mipMapped = GrMipmapped::kYes;
642 }
643
Adlai Holler98dd0042020-10-13 10:04:00 -0400644 GrBackendFormat backendFormat = this->defaultBackendFormat(colorType, renderable);
Brian Salomonb5f880a2020-12-07 11:30:16 -0500645 GrBackendTexture beTex = this->createBackendTexture(srcData[0].width(),
646 srcData[0].height(),
647 backendFormat,
648 mipMapped,
649 renderable,
650 isProtected);
651 if (!beTex.isValid()) {
652 return {};
653 }
Brian Salomonea1d39b2021-04-01 17:06:52 -0400654 if (!update_texture_with_pixmaps(this,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500655 srcData,
656 numProvidedLevels,
657 beTex,
658 textureOrigin,
659 std::move(finishedCallback))) {
660 this->deleteBackendTexture(beTex);
661 return {};
662 }
663 return beTex;
Adlai Holler98dd0042020-10-13 10:04:00 -0400664}
665
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400666bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
667 const SkColor4f& color,
668 GrGpuFinishedProc finishedProc,
669 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500670 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400671
672 if (this->abandoned()) {
673 return false;
674 }
675
Brian Salomon71283232021-04-08 12:45:58 -0400676 return fGpu->clearBackendTexture(backendTexture, std::move(finishedCallback), color.array());
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400677}
678
679bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
680 SkColorType skColorType,
681 const SkColor4f& color,
682 GrGpuFinishedProc finishedProc,
683 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500684 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400685
686 if (this->abandoned()) {
687 return false;
688 }
689
690 GrBackendFormat format = backendTexture.getBackendFormat();
Brian Osman9f1e06a2021-08-10 14:39:18 -0400691 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400692
693 if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, format)) {
694 return false;
695 }
696
697 GrSwizzle swizzle = this->caps()->getWriteSwizzle(format, grColorType);
Brian Salomon71283232021-04-08 12:45:58 -0400698 SkColor4f swizzledColor = swizzle.applyTo(color);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400699
Brian Salomon71283232021-04-08 12:45:58 -0400700 return fGpu->clearBackendTexture(backendTexture,
701 std::move(finishedCallback),
702 swizzledColor.array());
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400703}
704
705bool GrDirectContext::updateBackendTexture(const GrBackendTexture& backendTexture,
706 const SkPixmap srcData[],
707 int numLevels,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500708 GrSurfaceOrigin textureOrigin,
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400709 GrGpuFinishedProc finishedProc,
710 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500711 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400712
713 if (this->abandoned()) {
714 return false;
715 }
716
717 if (!srcData || numLevels <= 0) {
718 return false;
719 }
720
Brian Salomonea1d39b2021-04-01 17:06:52 -0400721 // If the texture has MIP levels then we require that the full set is overwritten.
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400722 int numExpectedLevels = 1;
723 if (backendTexture.hasMipmaps()) {
724 numExpectedLevels = SkMipmap::ComputeLevelCount(backendTexture.width(),
725 backendTexture.height()) + 1;
726 }
727 if (numLevels != numExpectedLevels) {
728 return false;
729 }
Brian Salomonea1d39b2021-04-01 17:06:52 -0400730 return update_texture_with_pixmaps(this,
Brian Salomonb5f880a2020-12-07 11:30:16 -0500731 srcData,
732 numLevels,
733 backendTexture,
734 textureOrigin,
735 std::move(finishedCallback));
Adlai Holler2e0c70d2020-10-13 08:21:37 -0400736}
737
Adlai Holler64e13832020-10-13 08:21:56 -0400738//////////////////////////////////////////////////////////////////////////////
739
740static GrBackendTexture create_and_update_compressed_backend_texture(
741 GrDirectContext* dContext,
742 SkISize dimensions,
743 const GrBackendFormat& backendFormat,
744 GrMipmapped mipMapped,
745 GrProtected isProtected,
746 sk_sp<GrRefCntedCallback> finishedCallback,
Brian Salomon71283232021-04-08 12:45:58 -0400747 const void* data,
748 size_t size) {
Adlai Holler64e13832020-10-13 08:21:56 -0400749 GrGpu* gpu = dContext->priv().getGpu();
750
751 GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat,
752 mipMapped, isProtected);
753 if (!beTex.isValid()) {
754 return {};
755 }
756
757 if (!dContext->priv().getGpu()->updateCompressedBackendTexture(
Brian Salomon71283232021-04-08 12:45:58 -0400758 beTex, std::move(finishedCallback), data, size)) {
Adlai Holler64e13832020-10-13 08:21:56 -0400759 dContext->deleteBackendTexture(beTex);
760 return {};
761 }
762 return beTex;
763}
764
Brian Salomon71283232021-04-08 12:45:58 -0400765GrBackendTexture GrDirectContext::createCompressedBackendTexture(
766 int width, int height,
767 const GrBackendFormat& backendFormat,
768 const SkColor4f& color,
769 GrMipmapped mipmapped,
770 GrProtected isProtected,
771 GrGpuFinishedProc finishedProc,
772 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400773 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Brian Salomon694ff172020-11-04 16:54:28 -0500774 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400775
776 if (this->abandoned()) {
777 return {};
778 }
779
Brian Salomon71283232021-04-08 12:45:58 -0400780 SkImage::CompressionType compression = GrBackendFormatToCompressionType(backendFormat);
781 if (compression == SkImage::CompressionType::kNone) {
782 return {};
783 }
784
785 size_t size = SkCompressedDataSize(compression,
786 {width, height},
787 nullptr,
788 mipmapped == GrMipmapped::kYes);
789 auto storage = std::make_unique<char[]>(size);
790 GrFillInCompressedData(compression, {width, height}, mipmapped, storage.get(), color);
791 return create_and_update_compressed_backend_texture(this,
792 {width, height},
793 backendFormat,
794 mipmapped,
795 isProtected,
796 std::move(finishedCallback),
797 storage.get(),
798 size);
Adlai Holler64e13832020-10-13 08:21:56 -0400799}
800
Brian Salomon71283232021-04-08 12:45:58 -0400801GrBackendTexture GrDirectContext::createCompressedBackendTexture(
802 int width, int height,
803 SkImage::CompressionType compression,
804 const SkColor4f& color,
805 GrMipmapped mipMapped,
806 GrProtected isProtected,
807 GrGpuFinishedProc finishedProc,
808 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400809 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
810 GrBackendFormat format = this->compressedBackendFormat(compression);
811 return this->createCompressedBackendTexture(width, height, format, color,
812 mipMapped, isProtected, finishedProc,
813 finishedContext);
814}
815
Brian Salomon71283232021-04-08 12:45:58 -0400816GrBackendTexture GrDirectContext::createCompressedBackendTexture(
817 int width, int height,
818 const GrBackendFormat& backendFormat,
819 const void* compressedData,
820 size_t dataSize,
821 GrMipmapped mipMapped,
822 GrProtected isProtected,
823 GrGpuFinishedProc finishedProc,
824 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400825 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Brian Salomon694ff172020-11-04 16:54:28 -0500826 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400827
828 if (this->abandoned()) {
829 return {};
830 }
831
Brian Salomon71283232021-04-08 12:45:58 -0400832 return create_and_update_compressed_backend_texture(this,
833 {width, height},
834 backendFormat,
835 mipMapped,
836 isProtected,
837 std::move(finishedCallback),
838 compressedData,
839 dataSize);
Adlai Holler64e13832020-10-13 08:21:56 -0400840}
841
Brian Salomon71283232021-04-08 12:45:58 -0400842GrBackendTexture GrDirectContext::createCompressedBackendTexture(
843 int width, int height,
844 SkImage::CompressionType compression,
845 const void* data, size_t dataSize,
846 GrMipmapped mipMapped,
847 GrProtected isProtected,
848 GrGpuFinishedProc finishedProc,
849 GrGpuFinishedContext finishedContext) {
Adlai Holler64e13832020-10-13 08:21:56 -0400850 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
851 GrBackendFormat format = this->compressedBackendFormat(compression);
852 return this->createCompressedBackendTexture(width, height, format, data, dataSize, mipMapped,
853 isProtected, finishedProc, finishedContext);
854}
855
856bool GrDirectContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
857 const SkColor4f& color,
858 GrGpuFinishedProc finishedProc,
859 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500860 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400861
862 if (this->abandoned()) {
863 return false;
864 }
865
Brian Salomon71283232021-04-08 12:45:58 -0400866 SkImage::CompressionType compression =
867 GrBackendFormatToCompressionType(backendTexture.getBackendFormat());
868 if (compression == SkImage::CompressionType::kNone) {
869 return {};
870 }
871 size_t size = SkCompressedDataSize(compression,
872 backendTexture.dimensions(),
873 nullptr,
874 backendTexture.hasMipmaps());
875 SkAutoMalloc storage(size);
876 GrFillInCompressedData(compression,
877 backendTexture.dimensions(),
878 backendTexture.mipmapped(),
879 static_cast<char*>(storage.get()),
880 color);
881 return fGpu->updateCompressedBackendTexture(backendTexture,
882 std::move(finishedCallback),
883 storage.get(),
884 size);
Adlai Holler64e13832020-10-13 08:21:56 -0400885}
886
887bool GrDirectContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
888 const void* compressedData,
889 size_t dataSize,
890 GrGpuFinishedProc finishedProc,
891 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500892 auto finishedCallback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler64e13832020-10-13 08:21:56 -0400893
894 if (this->abandoned()) {
895 return false;
896 }
897
898 if (!compressedData) {
899 return false;
900 }
901
Brian Salomon71283232021-04-08 12:45:58 -0400902 return fGpu->updateCompressedBackendTexture(backendTexture,
903 std::move(finishedCallback),
904 compressedData,
905 dataSize);
Adlai Holler64e13832020-10-13 08:21:56 -0400906}
907
Adlai Holler6d0745b2020-10-13 13:29:00 -0400908//////////////////////////////////////////////////////////////////////////////
909
910bool GrDirectContext::setBackendTextureState(const GrBackendTexture& backendTexture,
911 const GrBackendSurfaceMutableState& state,
912 GrBackendSurfaceMutableState* previousState,
913 GrGpuFinishedProc finishedProc,
914 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500915 auto callback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler6d0745b2020-10-13 13:29:00 -0400916
917 if (this->abandoned()) {
918 return false;
919 }
920
921 return fGpu->setBackendTextureState(backendTexture, state, previousState, std::move(callback));
922}
923
924
925bool GrDirectContext::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
926 const GrBackendSurfaceMutableState& state,
927 GrBackendSurfaceMutableState* previousState,
928 GrGpuFinishedProc finishedProc,
929 GrGpuFinishedContext finishedContext) {
Brian Salomon694ff172020-11-04 16:54:28 -0500930 auto callback = GrRefCntedCallback::Make(finishedProc, finishedContext);
Adlai Holler6d0745b2020-10-13 13:29:00 -0400931
932 if (this->abandoned()) {
933 return false;
934 }
935
936 return fGpu->setBackendRenderTargetState(backendRenderTarget, state, previousState,
937 std::move(callback));
938}
939
940void GrDirectContext::deleteBackendTexture(GrBackendTexture backendTex) {
941 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
942 // For the Vulkan backend we still must destroy the backend texture when the context is
943 // abandoned.
944 if ((this->abandoned() && this->backend() != GrBackendApi::kVulkan) || !backendTex.isValid()) {
945 return;
946 }
947
948 fGpu->deleteBackendTexture(backendTex);
949}
950
951//////////////////////////////////////////////////////////////////////////////
952
953bool GrDirectContext::precompileShader(const SkData& key, const SkData& data) {
954 return fGpu->precompileShader(key, data);
955}
956
957#ifdef SK_ENABLE_DUMP_GPU
958#include "include/core/SkString.h"
959#include "src/utils/SkJSONWriter.h"
960SkString GrDirectContext::dump() const {
961 SkDynamicMemoryWStream stream;
962 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
963 writer.beginObject();
964
965 writer.appendString("backend", GrBackendApiToStr(this->backend()));
966
967 writer.appendName("caps");
968 this->caps()->dumpJSON(&writer);
969
970 writer.appendName("gpu");
971 this->fGpu->dumpJSON(&writer);
972
973 writer.appendName("context");
974 this->dumpJSON(&writer);
975
976 // Flush JSON to the memory stream
977 writer.endObject();
978 writer.flush();
979
980 // Null terminate the JSON data in the memory stream
981 stream.write8(0);
982
983 // Allocate a string big enough to hold all the data, then copy out of the stream
984 SkString result(stream.bytesWritten());
985 stream.copyToAndReset(result.writable_str());
986 return result;
987}
988#endif
989
John Rosascoa9b348f2019-11-08 13:18:15 -0800990#ifdef SK_GL
Robert Phillipsc7228c62020-07-14 12:57:39 -0400991
Robert Phillipsf4f80112020-07-13 16:13:31 -0400992/*************************************************************************************************/
993sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface) {
Robert Phillipsa3457b82018-03-08 11:30:12 -0500994 GrContextOptions defaultOptions;
Jim Van Verth03b8ab22020-02-24 11:36:15 -0500995 return MakeGL(std::move(glInterface), defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -0500996}
997
Robert Phillipsf4f80112020-07-13 16:13:31 -0400998sk_sp<GrDirectContext> GrDirectContext::MakeGL(const GrContextOptions& options) {
Brian Salomonc1b9c102018-04-06 09:18:00 -0400999 return MakeGL(nullptr, options);
1000}
1001
Robert Phillipsf4f80112020-07-13 16:13:31 -04001002sk_sp<GrDirectContext> GrDirectContext::MakeGL() {
Brian Salomonc1b9c102018-04-06 09:18:00 -04001003 GrContextOptions defaultOptions;
1004 return MakeGL(nullptr, defaultOptions);
1005}
1006
Brian Salomon24069eb2020-06-24 10:19:52 -04001007#if GR_TEST_UTILS
1008GrGLFunction<GrGLGetErrorFn> make_get_error_with_random_oom(GrGLFunction<GrGLGetErrorFn> original) {
1009 // A SkRandom and a GrGLFunction<GrGLGetErrorFn> are too big to be captured by a
1010 // GrGLFunction<GrGLGetError> (surprise, surprise). So we make a context object and
1011 // capture that by pointer. However, GrGLFunction doesn't support calling a destructor
1012 // on the thing it captures. So we leak the context.
1013 struct GetErrorContext {
1014 SkRandom fRandom;
1015 GrGLFunction<GrGLGetErrorFn> fGetError;
1016 };
1017
1018 auto errorContext = new GetErrorContext;
1019
1020#if defined(SK_ENABLE_SCOPED_LSAN_SUPPRESSIONS)
1021 __lsan_ignore_object(errorContext);
1022#endif
1023
1024 errorContext->fGetError = original;
1025
1026 return GrGLFunction<GrGLGetErrorFn>([errorContext]() {
1027 GrGLenum error = errorContext->fGetError();
1028 if (error == GR_GL_NO_ERROR && (errorContext->fRandom.nextU() % 300) == 0) {
1029 error = GR_GL_OUT_OF_MEMORY;
1030 }
1031 return error;
1032 });
1033}
1034#endif
1035
Robert Phillipsf4f80112020-07-13 16:13:31 -04001036sk_sp<GrDirectContext> GrDirectContext::MakeGL(sk_sp<const GrGLInterface> glInterface,
1037 const GrContextOptions& options) {
1038 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kOpenGL, options));
Brian Salomon24069eb2020-06-24 10:19:52 -04001039#if GR_TEST_UTILS
1040 if (options.fRandomGLOOM) {
1041 auto copy = sk_make_sp<GrGLInterface>(*glInterface);
1042 copy->fFunctions.fGetError =
1043 make_get_error_with_random_oom(glInterface->fFunctions.fGetError);
1044#if GR_GL_CHECK_ERROR
1045 // Suppress logging GL errors since we'll be synthetically generating them.
1046 copy->suppressErrorLogging();
1047#endif
1048 glInterface = std::move(copy);
1049 }
1050#endif
Robert Phillipsf4f80112020-07-13 16:13:31 -04001051 direct->fGpu = GrGLGpu::Make(std::move(glInterface), options, direct.get());
1052 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001053 return nullptr;
1054 }
Robert Phillipsf4f80112020-07-13 16:13:31 -04001055 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001056}
John Rosascoa9b348f2019-11-08 13:18:15 -08001057#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -05001058
Robert Phillipsf4f80112020-07-13 16:13:31 -04001059/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001060sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions) {
1061 GrContextOptions defaultOptions;
1062 return MakeMock(mockOptions, defaultOptions);
1063}
1064
1065sk_sp<GrDirectContext> GrDirectContext::MakeMock(const GrMockOptions* mockOptions,
1066 const GrContextOptions& options) {
1067 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMock, options));
1068
1069 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
1070 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001071 return nullptr;
1072 }
Chris Daltona378b452019-12-11 13:24:11 -05001073
Robert Phillipsf4f80112020-07-13 16:13:31 -04001074 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001075}
1076
Greg Danielb4d89562018-10-03 18:44:49 +00001077#ifdef SK_VULKAN
Robert Phillipsf4f80112020-07-13 16:13:31 -04001078/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001079sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext) {
1080 GrContextOptions defaultOptions;
1081 return MakeVulkan(backendContext, defaultOptions);
1082}
1083
1084sk_sp<GrDirectContext> GrDirectContext::MakeVulkan(const GrVkBackendContext& backendContext,
1085 const GrContextOptions& options) {
1086 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kVulkan, options));
1087
1088 direct->fGpu = GrVkGpu::Make(backendContext, options, direct.get());
1089 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001090 return nullptr;
1091 }
1092
Robert Phillipsf4f80112020-07-13 16:13:31 -04001093 return direct;
Greg Danielb4d89562018-10-03 18:44:49 +00001094}
Robert Phillipsf4f80112020-07-13 16:13:31 -04001095#endif
Robert Phillipsa3457b82018-03-08 11:30:12 -05001096
1097#ifdef SK_METAL
Robert Phillipsf4f80112020-07-13 16:13:31 -04001098/*************************************************************************************************/
Jim Van Verth351c9b52020-11-12 15:21:11 -05001099sk_sp<GrDirectContext> GrDirectContext::MakeMetal(const GrMtlBackendContext& backendContext) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001100 GrContextOptions defaultOptions;
Jim Van Verth351c9b52020-11-12 15:21:11 -05001101 return MakeMetal(backendContext, defaultOptions);
Robert Phillipsa3457b82018-03-08 11:30:12 -05001102}
1103
Jim Van Verth351c9b52020-11-12 15:21:11 -05001104sk_sp<GrDirectContext> GrDirectContext::MakeMetal(const GrMtlBackendContext& backendContext,
1105 const GrContextOptions& options) {
Robert Phillipsf4f80112020-07-13 16:13:31 -04001106 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
Robert Phillipsa3457b82018-03-08 11:30:12 -05001107
Jim Van Verth351c9b52020-11-12 15:21:11 -05001108 direct->fGpu = GrMtlTrampoline::MakeGpu(backendContext, options, direct.get());
Robert Phillipsf4f80112020-07-13 16:13:31 -04001109 if (!direct->init()) {
Robert Phillipsa3457b82018-03-08 11:30:12 -05001110 return nullptr;
1111 }
Timothy Liang4e85e802018-06-28 16:37:18 -04001112
Robert Phillipsf4f80112020-07-13 16:13:31 -04001113 return direct;
Robert Phillipsa3457b82018-03-08 11:30:12 -05001114}
Jim Van Verth351c9b52020-11-12 15:21:11 -05001115
1116// deprecated
1117sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue) {
1118 GrContextOptions defaultOptions;
1119 return MakeMetal(device, queue, defaultOptions);
1120}
1121
1122// deprecated
1123// remove include/gpu/mtl/GrMtlBackendContext.h, above, when removed
1124sk_sp<GrDirectContext> GrDirectContext::MakeMetal(void* device, void* queue,
1125 const GrContextOptions& options) {
1126 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kMetal, options));
1127 GrMtlBackendContext backendContext = {};
1128 backendContext.fDevice.reset(device);
1129 backendContext.fQueue.reset(queue);
1130
1131 return GrDirectContext::MakeMetal(backendContext, options);
1132}
Robert Phillipsa3457b82018-03-08 11:30:12 -05001133#endif
1134
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001135#ifdef SK_DIRECT3D
Robert Phillipsf4f80112020-07-13 16:13:31 -04001136/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001137sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
1138 GrContextOptions defaultOptions;
1139 return MakeDirect3D(backendContext, defaultOptions);
1140}
1141
1142sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
1143 const GrContextOptions& options) {
1144 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDirect3D, options));
1145
1146 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
1147 if (!direct->init()) {
Jim Van Verthd2d4c5e2020-02-19 14:57:58 -05001148 return nullptr;
1149 }
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001150
Robert Phillipsf4f80112020-07-13 16:13:31 -04001151 return direct;
Jim Van Verthb01e12b2020-02-18 14:34:38 -05001152}
1153#endif
1154
Stephen White985741a2019-07-18 11:43:45 -04001155#ifdef SK_DAWN
Robert Phillipsf4f80112020-07-13 16:13:31 -04001156/*************************************************************************************************/
Robert Phillipsf4f80112020-07-13 16:13:31 -04001157sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device) {
Stephen White985741a2019-07-18 11:43:45 -04001158 GrContextOptions defaultOptions;
1159 return MakeDawn(device, defaultOptions);
1160}
1161
Robert Phillipsf4f80112020-07-13 16:13:31 -04001162sk_sp<GrDirectContext> GrDirectContext::MakeDawn(const wgpu::Device& device,
1163 const GrContextOptions& options) {
1164 sk_sp<GrDirectContext> direct(new GrDirectContext(GrBackendApi::kDawn, options));
Stephen White985741a2019-07-18 11:43:45 -04001165
Robert Phillipsf4f80112020-07-13 16:13:31 -04001166 direct->fGpu = GrDawnGpu::Make(device, options, direct.get());
1167 if (!direct->init()) {
Stephen White985741a2019-07-18 11:43:45 -04001168 return nullptr;
1169 }
1170
Robert Phillipsf4f80112020-07-13 16:13:31 -04001171 return direct;
Stephen White985741a2019-07-18 11:43:45 -04001172}
Robert Phillipsf4f80112020-07-13 16:13:31 -04001173
Stephen White985741a2019-07-18 11:43:45 -04001174#endif