Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrDirectContext.cpp
Go to the documentation of this file.
1/*
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 */
8
11#include "include/core/SkSize.h"
25#include "src/core/SkMipmap.h"
28#include "src/gpu/DataUtils.h"
31#include "src/gpu/Swizzle.h"
47#include "src/gpu/ganesh/GrSemaphore.h" // IWYU pragma: keep
51#include "src/gpu/ganesh/GrThreadSafePipelineBuilder.h" // IWYU pragma: keep
62
63#include <array>
64#include <atomic>
65#include <forward_list>
66#include <memory>
67#include <utility>
68
69#ifdef SK_DIRECT3D
71#endif
72
73using namespace skia_private;
74
75#define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(this->singleOwner())
76
78
80 static std::atomic<uint32_t> nextID{1};
81 uint32_t id;
82 do {
83 id = nextID.fetch_add(1, std::memory_order_relaxed);
84 } while (id == SK_InvalidUniqueID);
85 return DirectContextID(id);
86}
87
91 : GrRecordingContext(std::move(proxy), false)
92 , fDeleteCallbackHelper(new DeleteCallbackHelper(options.fContextDeleteContext,
93 options.fContextDeleteProc))
94 , fDirectContextID(DirectContextID::Next()) {}
95
98 // this if-test protects against the case where the context is being destroyed
99 // before having been fully created
100 if (fGpu) {
101 this->flushAndSubmit();
102 }
103
104 // We need to make sure all work is finished on the gpu before we start releasing resources.
105 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/false);
106
107 this->destroyDrawingManager();
108
109 // Ideally we could just let the ptr drop, but resource cache queries this ptr in releaseAll.
110 if (fResourceCache) {
111 fResourceCache->releaseAll();
112 }
113 // This has to be after GrResourceCache::releaseAll so that other threads that are holding
114 // async pixel result don't try to destroy buffers off thread.
115 fMappedBufferManager.reset();
116}
117
121
123 if (this->abandoned() || this->backend() != GrBackendApi::kOpenGL) {
124 return;
125 }
126 fGpu->resetTextureBindings();
127}
128
131 fGpu->markContextDirty(state);
132}
133
136 return;
137 }
138
139 if (fInsideReleaseProcCnt) {
140 SkDEBUGFAIL("Calling GrDirectContext::abandonContext() while inside a ReleaseProc is not "
141 "allowed");
142 return;
143 }
144
146
147 // We need to make sure all work is finished on the gpu before we start releasing resources.
148 this->syncAllOutstandingGpuWork(this->caps()->mustSyncGpuDuringAbandon());
149
150 fStrikeCache->freeAll();
151
152 fMappedBufferManager->abandon();
153
154 fResourceProvider->abandon();
155
156 // abandon first so destructors don't try to free the resources in the API.
157 fResourceCache->abandonAll();
158
159 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
160
161#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
162 if (fSmallPathAtlasMgr) {
163 fSmallPathAtlasMgr->reset();
164 }
165#endif
166 fAtlasManager->freeAll();
167}
168
171 return true;
172 }
173
174 if (fGpu && fGpu->isDeviceLost()) {
175 this->abandonContext();
176 return true;
177 }
178 return false;
179}
180
182 if (fGpu && fGpu->isDeviceLost()) {
184 this->abandonContext();
185 }
186 return true;
187 }
188 return false;
189}
190
191bool GrDirectContext::oomed() { return fGpu ? fGpu->checkAndResetOOMed() : false; }
192
195 return;
196 }
197
199
200 // We need to make sure all work is finished on the gpu before we start releasing resources.
201 this->syncAllOutstandingGpuWork(/*shouldExecuteWhileAbandoned=*/true);
202
203 fResourceProvider->abandon();
204
205 // Release all resources in the backend 3D API.
206 fResourceCache->releaseAll();
207
208 // Must be after GrResourceCache::releaseAll().
209 fMappedBufferManager.reset();
210
211 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
212#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
213 if (fSmallPathAtlasMgr) {
214 fSmallPathAtlasMgr->reset();
215 }
216#endif
217 fAtlasManager->freeAll();
218}
219
222
223 if (this->abandoned()) {
224 return;
225 }
226
227 this->flushAndSubmit();
228#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
229 if (fSmallPathAtlasMgr) {
230 fSmallPathAtlasMgr->reset();
231 }
232#endif
233 fAtlasManager->freeAll();
234
235 // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
236 // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
237 fStrikeCache->freeAll();
238
240
241 fResourceCache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
242}
243
246 if (!fGpu) {
247 return false;
248 }
249
250 fThreadSafeProxy->priv().init(fGpu->refCaps(), fGpu->refPipelineBuilder());
252 return false;
253 }
254
256 SkASSERT(this->threadSafeCache());
257
258 fStrikeCache = std::make_unique<StrikeCache>();
259 fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(),
260 this->directContextID(),
261 this->contextID());
262 fResourceCache->setProxyProvider(this->proxyProvider());
263 fResourceCache->setThreadSafeCache(this->threadSafeCache());
264#if defined(GR_TEST_UTILS)
265 if (this->options().fResourceCacheLimitOverride != -1) {
266 this->setResourceCacheLimit(this->options().fResourceCacheLimitOverride);
267 }
268#endif
269 fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
270 this->singleOwner());
271 fMappedBufferManager = std::make_unique<GrClientMappedBufferManager>(this->directContextID());
272
273 fDidTestPMConversions = false;
274
275 // DDL TODO: we need to think through how the task group & persistent cache
276 // get passed on to/shared between all the DDLRecorders created with this context.
277 if (this->options().fExecutor) {
278 fTaskGroup = std::make_unique<SkTaskGroup>(*this->options().fExecutor);
279 }
280
281 fPersistentCache = this->options().fPersistentCache;
282
283 GrDrawOpAtlas::AllowMultitexturing allowMultitexturing;
284 if (GrContextOptions::Enable::kNo == this->options().fAllowMultipleGlyphCacheTextures ||
285 // multitexturing supported only if range can represent the index + texcoords fully
286 !(this->caps()->shaderCaps()->fFloatIs32Bits ||
287 this->caps()->shaderCaps()->fIntegerSupport)) {
288 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kNo;
289 } else {
290 allowMultitexturing = GrDrawOpAtlas::AllowMultitexturing::kYes;
291 }
292
294
295 fAtlasManager = std::make_unique<GrAtlasManager>(proxyProvider,
296 this->options().fGlyphCacheTextureMaximumBytes,
297 allowMultitexturing,
298 this->options().fSupportBilerpFromGlyphAtlas);
299 this->priv().addOnFlushCallbackObject(fAtlasManager.get());
300
301 return true;
302}
303
304void GrDirectContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
306
307 if (resourceCount) {
308 *resourceCount = fResourceCache->getBudgetedResourceCount();
309 }
310 if (resourceBytes) {
311 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
312 }
313}
314
317 return fResourceCache->getPurgeableBytes();
318}
319
320void GrDirectContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
322 if (maxResources) {
323 *maxResources = -1;
324 }
325 if (maxResourceBytes) {
326 *maxResourceBytes = this->getResourceCacheLimit();
327 }
328}
329
332 return fResourceCache->getMaxResourceBytes();
333}
334
335void GrDirectContext::setResourceCacheLimits(int unused, size_t maxResourceBytes) {
337 this->setResourceCacheLimit(maxResourceBytes);
338}
339
340void GrDirectContext::setResourceCacheLimit(size_t maxResourceBytes) {
342 fResourceCache->setLimit(maxResourceBytes);
343}
344
347
348 if (this->abandoned()) {
349 return;
350 }
351
352 fResourceCache->purgeUnlockedResources(opts);
353 fResourceCache->purgeAsNeeded();
354
355 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
356 // place to purge stale blobs
358
359 fGpu->releaseUnlockedBackendObjects();
360}
361
362void GrDirectContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed,
364 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
365
367
368 if (this->abandoned()) {
369 return;
370 }
371
373 fMappedBufferManager->process();
374 auto purgeTime = skgpu::StdSteadyClock::now() - msNotUsed;
375
376 fResourceCache->purgeAsNeeded();
377 fResourceCache->purgeResourcesNotUsedSince(purgeTime, opts);
378
379 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
380 // place to purge stale blobs
382}
383
384void GrDirectContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
386
387 if (this->abandoned()) {
388 return;
389 }
390
391 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
392}
393
394////////////////////////////////////////////////////////////////////////////////
395bool GrDirectContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
396 bool deleteSemaphoresAfterWait) {
397 if (!fGpu || !fGpu->caps()->backendSemaphoreSupport()) {
398 return false;
399 }
400 GrWrapOwnership ownership =
401 deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
402 for (int i = 0; i < numSemaphores; ++i) {
403 std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
404 waitSemaphores[i], GrSemaphoreWrapType::kWillWait, ownership);
405 // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
406 // to begin with. Therefore, it is fine to not wait on it.
407 if (sema) {
408 fGpu->waitSemaphore(sema.get());
409 }
410 }
411 return true;
412}
413
414#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
416 if (!fSmallPathAtlasMgr) {
417 fSmallPathAtlasMgr = std::make_unique<skgpu::ganesh::SmallPathAtlasMgr>();
418
419 this->priv().addOnFlushCallbackObject(fSmallPathAtlasMgr.get());
420 }
421
422 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
423 return nullptr;
424 }
425
426 return fSmallPathAtlasMgr.get();
427}
428#endif
429
430////////////////////////////////////////////////////////////////////////////////
431
434 if (this->abandoned()) {
435 if (info.fFinishedProc) {
436 info.fFinishedProc(info.fFinishedContext);
437 }
438 if (info.fSubmittedProc) {
439 info.fSubmittedProc(info.fSubmittedContext, false);
440 }
442 }
443
444 return this->drawingManager()->flushSurfaces(
446}
447
450 if (this->abandoned()) {
451 return false;
452 }
453
454 if (!fGpu) {
455 return false;
456 }
457
458 return fGpu->submitToGpu(sync);
459}
460
462 const GrFlushInfo& flushInfo) {
463 if (!image) {
465 }
466 auto ib = as_IB(image);
467 if (!ib->isGaneshBacked()) {
469 }
470 auto igb = static_cast<const SkImage_GaneshBase*>(image.get());
471 return igb->flush(this, flushInfo);
472}
473
475 this->flush(image, {});
476}
477
479 this->flush(image, {});
480 this->submit();
481}
482
485 const GrFlushInfo& info) {
486 if (!surface) {
488 }
489 auto sb = asSB(surface);
490 if (!sb->isGaneshBacked()) {
492 }
493
494 auto gs = static_cast<SkSurface_Ganesh*>(surface);
495 SkASSERT(this->priv().matches(gs->getDevice()->recordingContext()->asDirectContext()));
496 GrRenderTargetProxy* rtp = gs->getDevice()->targetProxy();
497
498 return this->priv().flushSurface(rtp, access, info, nullptr);
499}
500
502 const GrFlushInfo& info,
503 const skgpu::MutableTextureState* newState) {
504 if (!surface) {
506 }
507 auto sb = asSB(surface);
508 if (!sb->isGaneshBacked()) {
510 }
511
512 auto gs = static_cast<SkSurface_Ganesh*>(surface);
513 SkASSERT(this->priv().matches(gs->getDevice()->recordingContext()->asDirectContext()));
514 GrRenderTargetProxy* rtp = gs->getDevice()->targetProxy();
515
516 return this->priv().flushSurface(
518}
519
524
526 this->flush(surface, GrFlushInfo(), nullptr);
527}
528
529////////////////////////////////////////////////////////////////////////////////
530
532 if (fGpu) {
533 fGpu->checkFinishProcs();
534 }
535}
536
537void GrDirectContext::syncAllOutstandingGpuWork(bool shouldExecuteWhileAbandoned) {
538 if (fGpu && (!this->abandoned() || shouldExecuteWhileAbandoned)) {
539 fGpu->finishOutstandingGpuWork();
541 }
542}
543
544////////////////////////////////////////////////////////////////////////////////
545
547 if (fGpu) {
548 fGpu->storeVkPipelineCacheData();
549 }
550}
551
552////////////////////////////////////////////////////////////////////////////////
553
557
558//////////////////////////////////////////////////////////////////////////////
559
562 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
563 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
564 this->getTextBlobRedrawCoordinator()->usedBytes());
565}
566
568 int height,
569 const GrBackendFormat& backendFormat,
570 skgpu::Mipmapped mipmapped,
571 GrRenderable renderable,
572 GrProtected isProtected,
573 std::string_view label) {
574 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
575 if (this->abandoned()) {
576 return GrBackendTexture();
577 }
578
579 return fGpu->createBackendTexture({width, height}, backendFormat, renderable,
580 mipmapped, isProtected, label);
581}
582
584 GrSurfaceOrigin textureOrigin,
585 GrRenderable renderable,
586 GrProtected isProtected,
587 GrGpuFinishedProc finishedProc,
588 GrGpuFinishedContext finishedContext,
589 std::string_view label) {
590 return this->createBackendTexture(&srcData, 1, textureOrigin, renderable, isProtected,
591 finishedProc, finishedContext, label);
592}
593
595 GrRenderable renderable,
596 GrProtected isProtected,
597 GrGpuFinishedProc finishedProc,
598 GrGpuFinishedContext finishedContext,
599 std::string_view label) {
600 return this->createBackendTexture(&srcData,
601 1,
602 renderable,
603 isProtected,
604 finishedProc,
605 finishedContext,
606 label);
607}
608
610 int numLevels,
611 GrRenderable renderable,
612 GrProtected isProtected,
613 GrGpuFinishedProc finishedProc,
614 GrGpuFinishedContext finishedContext,
615 std::string_view label) {
616 return this->createBackendTexture(srcData,
617 numLevels,
619 renderable,
620 isProtected,
621 finishedProc,
622 finishedContext,
623 label);
624}
625
627 int height,
628 SkColorType skColorType,
629 skgpu::Mipmapped mipmapped,
630 GrRenderable renderable,
631 GrProtected isProtected,
632 std::string_view label) {
633 if (this->abandoned()) {
634 return GrBackendTexture();
635 }
636
637 const GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
638
639 return this->createBackendTexture(
640 width, height, format, mipmapped, renderable, isProtected, label);
641}
642
644 GrDirectContext* dContext,
645 SkISize dimensions,
646 const GrBackendFormat& backendFormat,
647 skgpu::Mipmapped mipmapped,
648 GrRenderable renderable,
649 GrProtected isProtected,
650 sk_sp<skgpu::RefCntedCallback> finishedCallback,
651 std::array<float, 4> color,
652 std::string_view label) {
653 GrGpu* gpu = dContext->priv().getGpu();
654 GrBackendTexture beTex = gpu->createBackendTexture(dimensions, backendFormat, renderable,
655 mipmapped, isProtected, label);
656 if (!beTex.isValid()) {
657 return {};
658 }
659
660 if (!dContext->priv().getGpu()->clearBackendTexture(beTex,
661 std::move(finishedCallback),
662 color)) {
663 dContext->deleteBackendTexture(beTex);
664 return {};
665 }
666 return beTex;
667}
668
670 const SkPixmap src[],
671 int numLevels,
672 const GrBackendTexture& backendTexture,
673 GrSurfaceOrigin textureOrigin,
674 sk_sp<skgpu::RefCntedCallback> finishedCallback) {
676 const GrBackendFormat& format = backendTexture.getBackendFormat();
677
678 if (!context->priv().caps()->areColorTypeAndFormatCompatible(ct, format)) {
679 return false;
680 }
681
682 auto proxy = context->priv().proxyProvider()->wrapBackendTexture(backendTexture,
686 std::move(finishedCallback));
687 if (!proxy) {
688 return false;
689 }
690
691 skgpu::Swizzle swizzle = context->priv().caps()->getReadSwizzle(format, ct);
692 GrSurfaceProxyView view(std::move(proxy), textureOrigin, swizzle);
693 skgpu::ganesh::SurfaceContext surfaceContext(
694 context, std::move(view), src[0].info().colorInfo());
695 AutoSTArray<15, GrCPixmap> tmpSrc(numLevels);
696 for (int i = 0; i < numLevels; ++i) {
697 tmpSrc[i] = src[i];
698 }
699 if (!surfaceContext.writePixels(context, tmpSrc.get(), numLevels)) {
700 return false;
701 }
702
703 GrSurfaceProxy* p = surfaceContext.asSurfaceProxy();
705 context->priv().drawingManager()->flushSurfaces(
707 return true;
708}
709
711 int height,
712 const GrBackendFormat& backendFormat,
713 const SkColor4f& color,
714 skgpu::Mipmapped mipmapped,
715 GrRenderable renderable,
716 GrProtected isProtected,
717 GrGpuFinishedProc finishedProc,
718 GrGpuFinishedContext finishedContext,
719 std::string_view label) {
720 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
721
722 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
723 if (this->abandoned()) {
724 return {};
725 }
726
728 {width, height},
729 backendFormat,
730 mipmapped,
731 renderable,
732 isProtected,
733 std::move(finishedCallback),
734 color.array(),
735 label);
736}
737
739 int height,
740 SkColorType skColorType,
741 const SkColor4f& color,
742 skgpu::Mipmapped mipmapped,
743 GrRenderable renderable,
744 GrProtected isProtected,
745 GrGpuFinishedProc finishedProc,
746 GrGpuFinishedContext finishedContext,
747 std::string_view label) {
748 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
749
750 if (this->abandoned()) {
751 return {};
752 }
753
754 GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
755 if (!format.isValid()) {
756 return {};
757 }
758
759 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
760 SkColor4f swizzledColor = this->caps()->getWriteSwizzle(format, grColorType).applyTo(color);
761
763 {width, height},
764 format,
765 mipmapped,
766 renderable,
767 isProtected,
768 std::move(finishedCallback),
769 swizzledColor.array(),
770 label);
771}
772
774 int numProvidedLevels,
775 GrSurfaceOrigin textureOrigin,
776 GrRenderable renderable,
777 GrProtected isProtected,
778 GrGpuFinishedProc finishedProc,
779 GrGpuFinishedContext finishedContext,
780 std::string_view label) {
781 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
782
783 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
784
785 if (this->abandoned()) {
786 return {};
787 }
788
789 if (!srcData || numProvidedLevels <= 0) {
790 return {};
791 }
792
793 SkColorType colorType = srcData[0].colorType();
794
795 skgpu::Mipmapped mipmapped = skgpu::Mipmapped::kNo;
796 if (numProvidedLevels > 1) {
797 mipmapped = skgpu::Mipmapped::kYes;
798 }
799
800 GrBackendFormat backendFormat = this->defaultBackendFormat(colorType, renderable);
801 GrBackendTexture beTex = this->createBackendTexture(srcData[0].width(),
802 srcData[0].height(),
803 backendFormat,
804 mipmapped,
805 renderable,
806 isProtected,
807 label);
808 if (!beTex.isValid()) {
809 return {};
810 }
812 srcData,
813 numProvidedLevels,
814 beTex,
815 textureOrigin,
816 std::move(finishedCallback))) {
817 this->deleteBackendTexture(beTex);
818 return {};
819 }
820 return beTex;
821}
822
824 const SkPixmap srcData[],
825 int numLevels,
826 GrGpuFinishedProc finishedProc,
827 GrGpuFinishedContext finishedContext) {
828 return this->updateBackendTexture(texture,
829 srcData,
830 numLevels,
832 finishedProc,
833 finishedContext);
834}
835
837 const SkColor4f& color,
838 GrGpuFinishedProc finishedProc,
839 GrGpuFinishedContext finishedContext) {
840 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
841
842 if (this->abandoned()) {
843 return false;
844 }
845
846 return fGpu->clearBackendTexture(backendTexture, std::move(finishedCallback), color.array());
847}
848
850 SkColorType skColorType,
851 const SkColor4f& color,
852 GrGpuFinishedProc finishedProc,
853 GrGpuFinishedContext finishedContext) {
854 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
855
856 if (this->abandoned()) {
857 return false;
858 }
859
860 GrBackendFormat format = backendTexture.getBackendFormat();
861 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
862
863 if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, format)) {
864 return false;
865 }
866
867 skgpu::Swizzle swizzle = this->caps()->getWriteSwizzle(format, grColorType);
868 SkColor4f swizzledColor = swizzle.applyTo(color);
869
870 return fGpu->clearBackendTexture(backendTexture,
871 std::move(finishedCallback),
872 swizzledColor.array());
873}
874
876 const SkPixmap srcData[],
877 int numLevels,
878 GrSurfaceOrigin textureOrigin,
879 GrGpuFinishedProc finishedProc,
880 GrGpuFinishedContext finishedContext) {
881 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
882
883 if (this->abandoned()) {
884 return false;
885 }
886
887 if (!srcData || numLevels <= 0) {
888 return false;
889 }
890
891 // If the texture has MIP levels then we require that the full set is overwritten.
892 int numExpectedLevels = 1;
893 if (backendTexture.hasMipmaps()) {
894 numExpectedLevels = SkMipmap::ComputeLevelCount(backendTexture.width(),
895 backendTexture.height()) + 1;
896 }
897 if (numLevels != numExpectedLevels) {
898 return false;
899 }
900 return update_texture_with_pixmaps(this,
901 srcData,
902 numLevels,
903 backendTexture,
904 textureOrigin,
905 std::move(finishedCallback));
906}
907
908//////////////////////////////////////////////////////////////////////////////
909
911 GrDirectContext* dContext,
912 SkISize dimensions,
913 const GrBackendFormat& backendFormat,
914 skgpu::Mipmapped mipmapped,
915 GrProtected isProtected,
916 sk_sp<skgpu::RefCntedCallback> finishedCallback,
917 const void* data,
918 size_t size) {
919 GrGpu* gpu = dContext->priv().getGpu();
920
921 GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat,
922 mipmapped, isProtected);
923 if (!beTex.isValid()) {
924 return {};
925 }
926
927 if (!dContext->priv().getGpu()->updateCompressedBackendTexture(
928 beTex, std::move(finishedCallback), data, size)) {
929 dContext->deleteBackendTexture(beTex);
930 return {};
931 }
932 return beTex;
933}
934
936 int width,
937 int height,
938 const GrBackendFormat& backendFormat,
939 const SkColor4f& color,
940 skgpu::Mipmapped mipmapped,
941 GrProtected isProtected,
942 GrGpuFinishedProc finishedProc,
943 GrGpuFinishedContext finishedContext) {
944 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
945 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
946
947 if (this->abandoned()) {
948 return {};
949 }
950
952 if (compression == SkTextureCompressionType::kNone) {
953 return {};
954 }
955
956 size_t size = SkCompressedDataSize(
957 compression, {width, height}, nullptr, mipmapped == skgpu::Mipmapped::kYes);
958 auto storage = std::make_unique<char[]>(size);
959 skgpu::FillInCompressedData(compression, {width, height}, mipmapped, storage.get(), color);
961 {width, height},
962 backendFormat,
963 mipmapped,
964 isProtected,
965 std::move(finishedCallback),
966 storage.get(),
967 size);
968}
969
971 int width,
972 int height,
973 SkTextureCompressionType compression,
974 const SkColor4f& color,
975 skgpu::Mipmapped mipmapped,
976 GrProtected isProtected,
977 GrGpuFinishedProc finishedProc,
978 GrGpuFinishedContext finishedContext) {
979 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
982 mipmapped, isProtected, finishedProc,
983 finishedContext);
984}
985
987 int width,
988 int height,
989 const GrBackendFormat& backendFormat,
990 const void* compressedData,
991 size_t dataSize,
992 skgpu::Mipmapped mipmapped,
993 GrProtected isProtected,
994 GrGpuFinishedProc finishedProc,
995 GrGpuFinishedContext finishedContext) {
996 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
997 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
998
999 if (this->abandoned()) {
1000 return {};
1001 }
1002
1004 {width, height},
1005 backendFormat,
1006 mipmapped,
1007 isProtected,
1008 std::move(finishedCallback),
1009 compressedData,
1010 dataSize);
1011}
1012
1014 int width,
1015 int height,
1016 SkTextureCompressionType compression,
1017 const void* data,
1018 size_t dataSize,
1019 skgpu::Mipmapped mipmapped,
1020 GrProtected isProtected,
1021 GrGpuFinishedProc finishedProc,
1022 GrGpuFinishedContext finishedContext) {
1023 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
1024 GrBackendFormat format = this->compressedBackendFormat(compression);
1025 return this->createCompressedBackendTexture(width, height, format, data, dataSize, mipmapped,
1026 isProtected, finishedProc, finishedContext);
1027}
1028
1030 const SkColor4f& color,
1031 GrGpuFinishedProc finishedProc,
1032 GrGpuFinishedContext finishedContext) {
1033 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
1034
1035 if (this->abandoned()) {
1036 return false;
1037 }
1038
1039 SkTextureCompressionType compression =
1041 if (compression == SkTextureCompressionType::kNone) {
1042 return {};
1043 }
1044 size_t size = SkCompressedDataSize(compression,
1045 backendTexture.dimensions(),
1046 nullptr,
1047 backendTexture.hasMipmaps());
1048 SkAutoMalloc storage(size);
1049 skgpu::FillInCompressedData(compression,
1050 backendTexture.dimensions(),
1051 backendTexture.mipmapped(),
1052 static_cast<char*>(storage.get()),
1053 color);
1054 return fGpu->updateCompressedBackendTexture(backendTexture,
1055 std::move(finishedCallback),
1056 storage.get(),
1057 size);
1058}
1059
1061 const void* compressedData,
1062 size_t dataSize,
1063 GrGpuFinishedProc finishedProc,
1064 GrGpuFinishedContext finishedContext) {
1065 auto finishedCallback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
1066
1067 if (this->abandoned()) {
1068 return false;
1069 }
1070
1071 if (!compressedData) {
1072 return false;
1073 }
1074
1075 return fGpu->updateCompressedBackendTexture(backendTexture,
1076 std::move(finishedCallback),
1077 compressedData,
1078 dataSize);
1079}
1080
1081//////////////////////////////////////////////////////////////////////////////
1082
1085 skgpu::MutableTextureState* previousState,
1086 GrGpuFinishedProc finishedProc,
1087 GrGpuFinishedContext finishedContext) {
1088 auto callback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
1089
1090 if (this->abandoned()) {
1091 return false;
1092 }
1093
1094 return fGpu->setBackendTextureState(backendTexture, state, previousState, std::move(callback));
1095}
1096
1097
1100 skgpu::MutableTextureState* previousState,
1101 GrGpuFinishedProc finishedProc,
1102 GrGpuFinishedContext finishedContext) {
1103 auto callback = skgpu::RefCntedCallback::Make(finishedProc, finishedContext);
1104
1105 if (this->abandoned()) {
1106 return false;
1107 }
1108
1109 return fGpu->setBackendRenderTargetState(backendRenderTarget, state, previousState,
1110 std::move(callback));
1111}
1112
1114 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
1115 // For the Vulkan backend we still must destroy the backend texture when the context is
1116 // abandoned.
1117 if ((this->abandoned() && this->backend() != GrBackendApi::kVulkan) || !backendTex.isValid()) {
1118 return;
1119 }
1120
1121 fGpu->deleteBackendTexture(backendTex);
1122}
1123
1124//////////////////////////////////////////////////////////////////////////////
1125
1127 return fGpu->precompileShader(key, data);
1128}
1129
1130#ifdef SK_ENABLE_DUMP_GPU
1131#include "include/core/SkString.h"
1132#include "src/utils/SkJSONWriter.h"
1133SkString GrDirectContext::dump() const {
1136 writer.beginObject();
1137
1138 writer.appendCString("backend", GrBackendApiToStr(this->backend()));
1139
1140 writer.appendName("caps");
1141 this->caps()->dumpJSON(&writer);
1142
1143 writer.appendName("gpu");
1144 this->fGpu->dumpJSON(&writer);
1145
1146 writer.appendName("context");
1147 this->dumpJSON(&writer);
1148
1149 // Flush JSON to the memory stream
1150 writer.endObject();
1151 writer.flush();
1152
1153 // Null terminate the JSON data in the memory stream
1154 stream.write8(0);
1155
1156 // Allocate a string big enough to hold all the data, then copy out of the stream
1157 SkString result(stream.bytesWritten());
1158 stream.copyToAndReset(result.data());
1159 return result;
1160}
1161#endif
1162
1163/*************************************************************************************************/
1165 GrContextOptions defaultOptions;
1166 return MakeMock(mockOptions, defaultOptions);
1167}
1168
1170 const GrContextOptions& options) {
1173 options,
1175
1176 direct->fGpu = GrMockGpu::Make(mockOptions, options, direct.get());
1177 if (!direct->init()) {
1178 return nullptr;
1179 }
1180
1181 return direct;
1182}
1183
1184#ifdef SK_DIRECT3D
1185/*************************************************************************************************/
1186sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext) {
1187 GrContextOptions defaultOptions;
1188 return MakeDirect3D(backendContext, defaultOptions);
1189}
1190
1191sk_sp<GrDirectContext> GrDirectContext::MakeDirect3D(const GrD3DBackendContext& backendContext,
1192 const GrContextOptions& options) {
1195 options,
1197
1198 direct->fGpu = GrD3DGpu::Make(backendContext, options, direct.get());
1199 if (!direct->init()) {
1200 return nullptr;
1201 }
1202
1203 return direct;
1204}
1205#endif
static bool unused
const char * options
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
SkTextureCompressionType GrBackendFormatToCompressionType(const GrBackendFormat &format)
static GrBackendTexture create_and_update_compressed_backend_texture(GrDirectContext *dContext, SkISize dimensions, const GrBackendFormat &backendFormat, skgpu::Mipmapped mipmapped, GrProtected isProtected, sk_sp< skgpu::RefCntedCallback > finishedCallback, const void *data, size_t size)
static GrBackendTexture create_and_clear_backend_texture(GrDirectContext *dContext, SkISize dimensions, const GrBackendFormat &backendFormat, skgpu::Mipmapped mipmapped, GrRenderable renderable, GrProtected isProtected, sk_sp< skgpu::RefCntedCallback > finishedCallback, std::array< float, 4 > color, std::string_view label)
static bool update_texture_with_pixmaps(GrDirectContext *context, const SkPixmap src[], int numLevels, const GrBackendTexture &backendTexture, GrSurfaceOrigin textureOrigin, sk_sp< skgpu::RefCntedCallback > finishedCallback)
@ kRW_GrIOType
GrWrapOwnership
Definition GrTypesPriv.h:76
@ kAdopt_GrWrapOwnership
Definition GrTypesPriv.h:81
@ kBorrow_GrWrapOwnership
Definition GrTypesPriv.h:78
GrColorType
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
GrPurgeResourceOptions
Definition GrTypes.h:234
GrSurfaceOrigin
Definition GrTypes.h:147
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
GrBackendApi
Definition GrTypes.h:95
GrSemaphoresSubmitted
Definition GrTypes.h:229
void * GrGpuFinishedContext
Definition GrTypes.h:178
void(* GrGpuFinishedProc)(GrGpuFinishedContext finishedContext)
Definition GrTypes.h:179
GrSyncCpu
Definition GrTypes.h:239
SkColor4f color
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
size_t SkCompressedDataSize(SkTextureCompressionType type, SkISize dimensions, TArray< size_t > *individualMipOffsets, bool mipmapped)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static SkImage_Base * as_IB(SkImage *image)
static SkSurface_Base * asSB(SkSurface *surface)
#define TRACE_FUNC
static constexpr uint32_t SK_InvalidUniqueID
Definition SkTypes.h:196
SkISize dimensions() const
GrBackendFormat getBackendFormat() const
skgpu::Mipmapped mipmapped() const
bool hasMipmaps() const
const GrCaps * caps() const
const GrShaderCaps * shaderCaps() const
Definition GrCaps.h:63
virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const =0
void dumpJSON(SkJSONWriter *) const
Definition GrCaps.cpp:302
bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat &format) const
Definition GrCaps.cpp:428
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
Definition GrCaps.cpp:443
static sk_sp< GrContextThreadSafeProxy > Make(GrBackendApi, const GrContextOptions &)
void init(sk_sp< const GrCaps >, sk_sp< GrThreadSafePipelineBuilder >) const
GrContextThreadSafeProxyPriv priv()
uint32_t contextID() const
const GrCaps * caps() const
SK_API GrBackendApi backend() const
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
bool matches(GrContext_Base *candidate) const
SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const
SK_API GrBackendFormat compressedBackendFormat(SkTextureCompressionType) const
sk_sp< GrContextThreadSafeProxy > fThreadSafeProxy
const GrContextOptions & options() const
static std::unique_ptr< GrGpu > Make(const GrD3DBackendContext &backendContext, const GrContextOptions &, GrDirectContext *)
Definition GrD3DGpu.cpp:50
GrSemaphoresSubmitted flushSurface(GrSurfaceProxy *proxy, SkSurfaces::BackendSurfaceAccess access=SkSurfaces::BackendSurfaceAccess::kNoAccess, const GrFlushInfo &info={}, const skgpu::MutableTextureState *newState=nullptr)
static GrDirectContext::DirectContextID Next()
void setResourceCacheLimits(int maxResources, size_t maxResourceBytes)
bool updateCompressedBackendTexture(const GrBackendTexture &, const SkColor4f &color, GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext)
GrBackendTexture createCompressedBackendTexture(int width, int height, const GrBackendFormat &, const SkColor4f &color, skgpu::Mipmapped, GrProtected=GrProtected::kNo, GrGpuFinishedProc finishedProc=nullptr, GrGpuFinishedContext finishedContext=nullptr)
skgpu::ganesh::SmallPathAtlasMgr * onGetSmallPathAtlasMgr()
size_t getResourceCachePurgeableBytes() const
GrDirectContext(GrBackendApi backend, const GrContextOptions &options, sk_sp< GrContextThreadSafeProxy > proxy)
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
bool submit(GrSyncCpu sync=GrSyncCpu::kNo)
size_t getResourceCacheLimit() const
bool precompileShader(const SkData &key, const SkData &data)
void resetContext(uint32_t state=kAll_GrBackendState)
void releaseResourcesAndAbandonContext()
bool abandoned() override
bool setBackendTextureState(const GrBackendTexture &, const skgpu::MutableTextureState &, skgpu::MutableTextureState *previousState=nullptr, GrGpuFinishedProc finishedProc=nullptr, GrGpuFinishedContext finishedContext=nullptr)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
~GrDirectContext() override
bool updateBackendTexture(const GrBackendTexture &, const SkColor4f &color, GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext)
bool setBackendRenderTargetState(const GrBackendRenderTarget &, const skgpu::MutableTextureState &, skgpu::MutableTextureState *previousState=nullptr, GrGpuFinishedProc finishedProc=nullptr, GrGpuFinishedContext finishedContext=nullptr)
void deleteBackendTexture(const GrBackendTexture &)
GrBackendTexture createBackendTexture(int width, int height, const GrBackendFormat &, skgpu::Mipmapped, GrRenderable, GrProtected=GrProtected::kNo, std::string_view label={})
bool wait(int numSemaphores, const GrBackendSemaphore *waitSemaphores, bool deleteSemaphoresAfterWait=true)
void getResourceCacheUsage(int *resourceCount, size_t *resourceBytes) const
void dumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump) const
void getResourceCacheLimits(int *maxResources, size_t *maxResourceBytes) const
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
bool init() override
DirectContextID directContextID() const
GrDirectContextPriv priv()
void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources)
bool supportsDistanceFieldText() const
void performDeferredCleanup(std::chrono::milliseconds msNotUsed, GrPurgeResourceOptions opts=GrPurgeResourceOptions::kAllResources)
void abandonContext() override
void setResourceCacheLimit(size_t maxResourceBytes)
GrSemaphoresSubmitted flushSurfaces(SkSpan< GrSurfaceProxy * >, SkSurfaces::BackendSurfaceAccess, const GrFlushInfo &, const skgpu::MutableTextureState *newState)
Definition GrGpu.h:62
GrBackendTexture createCompressedBackendTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Mipmapped, GrProtected)
Definition GrGpu.cpp:912
bool updateCompressedBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, const void *data, size_t length)
Definition GrGpu.cpp:941
GrBackendTexture createBackendTexture(SkISize dimensions, const GrBackendFormat &, GrRenderable, skgpu::Mipmapped, GrProtected, std::string_view label)
Definition GrGpu.cpp:868
bool clearBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, std::array< float, 4 > color)
Definition GrGpu.cpp:898
skgpu::SingleOwner * singleOwner() const
static std::unique_ptr< GrGpu > Make(const GrMockOptions *, const GrContextOptions &, GrDirectContext *)
Definition GrMockGpu.cpp:56
sk_sp< GrTextureProxy > wrapBackendTexture(const GrBackendTexture &, GrWrapOwnership, GrWrapCacheable, GrIOType, sk_sp< skgpu::RefCntedCallback >=nullptr)
void addOnFlushCallbackObject(GrOnFlushCallbackObject *)
GrDrawingManager * drawingManager()
GrProxyProvider * proxyProvider()
GrThreadSafeCache * threadSafeCache()
void dumpJSON(SkJSONWriter *) const
bool abandoned() override
sktext::gpu::TextBlobRedrawCoordinator * getTextBlobRedrawCoordinator()
GrDrawingManager * drawingManager()
GrProxyProvider * proxyProvider()
void abandonContext() override
void * get()
virtual GrSemaphoresSubmitted flush(GrDirectContext *, const GrFlushInfo &) const =0
static int ComputeLevelCount(int baseWidth, int baseHeight)
Definition SkMipmap.cpp:134
SkColorType colorType() const
Definition SkPixmap.h:173
virtual void dumpNumericValue(const char *dumpName, const char *valueName, const char *units, uint64_t value)=0
T * get() const
Definition SkRefCnt.h:303
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
constexpr std::array< float, 4 > applyTo(std::array< float, 4 > color) const
Definition Swizzle.h:101
GrSurfaceProxy * asSurfaceProxy()
bool writePixels(GrDirectContext *dContext, GrCPixmap src, SkIPoint dstPt)
void purgeStaleBlobs() SK_EXCLUDES(fSpinLock)
VkSurfaceKHR surface
Definition main.cc:49
sk_sp< SkImage > image
Definition examples.cpp:29
AtkStateType state
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
GAsyncResult * result
uint32_t uint32_t * format
#define ASSERT_SINGLE_OWNER
Definition Device.cpp:120
FlTexture * texture
BackendSurfaceAccess
Definition SkSurface.h:44
@ kNoAccess
back-end surface will not be used by client
void FillInCompressedData(SkTextureCompressionType type, SkISize dimensions, skgpu::Mipmapped mipmapped, char *dstPixels, const SkColor4f &colorf)
Renderable
Definition GpuTypes.h:69
Mipmapped
Definition GpuTypes.h:53
Protected
Definition GpuTypes.h:61
Definition ref_ptr.h:256
int32_t height
int32_t width
PersistentCache * fPersistentCache
GrGpuFinishedProc fFinishedProc
Definition GrTypes.h:219
bool supportsDistanceFieldText() const
Definition SkSLUtil.h:80
const uintptr_t id
#define TRACE_EVENT0(category_group, name)