65#include <forward_list>
75#define ASSERT_SINGLE_OWNER SKGPU_ASSERT_SINGLE_OWNER(this->singleOwner())
80 static std::atomic<uint32_t> nextID{1};
83 id = nextID.fetch_add(1, std::memory_order_relaxed);
92 , fDeleteCallbackHelper(new DeleteCallbackHelper(
options.fContextDeleteContext,
105 this->syncAllOutstandingGpuWork(
false);
110 if (fResourceCache) {
111 fResourceCache->releaseAll();
115 fMappedBufferManager.reset();
126 fGpu->resetTextureBindings();
131 fGpu->markContextDirty(
state);
139 if (fInsideReleaseProcCnt) {
140 SkDEBUGFAIL(
"Calling GrDirectContext::abandonContext() while inside a ReleaseProc is not "
148 this->syncAllOutstandingGpuWork(this->
caps()->mustSyncGpuDuringAbandon());
150 fStrikeCache->freeAll();
152 fMappedBufferManager->abandon();
154 fResourceProvider->abandon();
157 fResourceCache->abandonAll();
161#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
162 if (fSmallPathAtlasMgr) {
163 fSmallPathAtlasMgr->reset();
166 fAtlasManager->freeAll();
174 if (fGpu && fGpu->isDeviceLost()) {
182 if (fGpu && fGpu->isDeviceLost()) {
201 this->syncAllOutstandingGpuWork(
true);
203 fResourceProvider->abandon();
206 fResourceCache->releaseAll();
209 fMappedBufferManager.reset();
212#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
213 if (fSmallPathAtlasMgr) {
214 fSmallPathAtlasMgr->reset();
217 fAtlasManager->freeAll();
228#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
229 if (fSmallPathAtlasMgr) {
230 fSmallPathAtlasMgr->reset();
233 fAtlasManager->freeAll();
237 fStrikeCache->freeAll();
258 fStrikeCache = std::make_unique<StrikeCache>();
259 fResourceCache = std::make_unique<GrResourceCache>(this->
singleOwner(),
264#if defined(GR_TEST_UTILS)
265 if (this->
options().fResourceCacheLimitOverride != -1) {
269 fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
270 this->singleOwner());
271 fMappedBufferManager = std::make_unique<GrClientMappedBufferManager>(this->
directContextID());
273 fDidTestPMConversions =
false;
277 if (this->
options().fExecutor) {
278 fTaskGroup = std::make_unique<SkTaskGroup>(*this->
options().fExecutor);
286 !(this->
caps()->shaderCaps()->fFloatIs32Bits ||
287 this->
caps()->shaderCaps()->fIntegerSupport)) {
295 fAtlasManager = std::make_unique<GrAtlasManager>(
proxyProvider,
296 this->
options().fGlyphCacheTextureMaximumBytes,
298 this->
options().fSupportBilerpFromGlyphAtlas);
308 *resourceCount = fResourceCache->getBudgetedResourceCount();
311 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
317 return fResourceCache->getPurgeableBytes();
325 if (maxResourceBytes) {
332 return fResourceCache->getMaxResourceBytes();
342 fResourceCache->setLimit(maxResourceBytes);
352 fResourceCache->purgeUnlockedResources(opts);
353 fResourceCache->purgeAsNeeded();
359 fGpu->releaseUnlockedBackendObjects();
373 fMappedBufferManager->process();
374 auto purgeTime = skgpu::StdSteadyClock::now() - msNotUsed;
376 fResourceCache->purgeAsNeeded();
377 fResourceCache->purgeResourcesNotUsedSince(purgeTime, opts);
391 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
396 bool deleteSemaphoresAfterWait) {
397 if (!fGpu || !fGpu->caps()->backendSemaphoreSupport()) {
402 for (
int i = 0; i < numSemaphores; ++i) {
403 std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
408 fGpu->waitSemaphore(sema.get());
414#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
416 if (!fSmallPathAtlasMgr) {
417 fSmallPathAtlasMgr = std::make_unique<skgpu::ganesh::SmallPathAtlasMgr>();
422 if (!fSmallPathAtlasMgr->initAtlas(this->proxyProvider(), this->caps())) {
426 return fSmallPathAtlasMgr.get();
436 info.fFinishedProc(
info.fFinishedContext);
438 if (
info.fSubmittedProc) {
439 info.fSubmittedProc(
info.fSubmittedContext,
false);
458 return fGpu->submitToGpu(sync);
467 if (!ib->isGaneshBacked()) {
471 return igb->
flush(
this, flushInfo);
475 this->
flush(image, {});
479 this->
flush(image, {});
490 if (!sb->isGaneshBacked()) {
508 if (!sb->isGaneshBacked()) {
533 fGpu->checkFinishProcs();
537void GrDirectContext::syncAllOutstandingGpuWork(
bool shouldExecuteWhileAbandoned) {
538 if (fGpu && (!this->
abandoned() || shouldExecuteWhileAbandoned)) {
539 fGpu->finishOutstandingGpuWork();
548 fGpu->storeVkPipelineCacheData();
562 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
563 traceMemoryDump->
dumpNumericValue(
"skia/gr_text_blob_cache",
"size",
"bytes",
573 std::string_view label) {
579 return fGpu->createBackendTexture({
width,
height}, backendFormat, renderable,
580 mipmapped, isProtected, label);
589 std::string_view label) {
591 finishedProc, finishedContext, label);
599 std::string_view label) {
615 std::string_view label) {
632 std::string_view label) {
640 width,
height,
format, mipmapped, renderable, isProtected, label);
651 std::array<float, 4>
color,
652 std::string_view label) {
655 mipmapped, isProtected, label);
661 std::move(finishedCallback),
686 std::move(finishedCallback));
694 context, std::move(view), src[0].
info().colorInfo());
696 for (
int i = 0; i < numLevels; ++i) {
699 if (!surfaceContext.
writePixels(context, tmpSrc.
get(), numLevels)) {
719 std::string_view label) {
733 std::move(finishedCallback),
747 std::string_view label) {
768 std::move(finishedCallback),
769 swizzledColor.array(),
774 int numProvidedLevels,
780 std::string_view label) {
789 if (!srcData || numProvidedLevels <= 0) {
796 if (numProvidedLevels > 1) {
797 mipmapped = skgpu::Mipmapped::kYes;
816 std::move(finishedCallback))) {
846 return fGpu->clearBackendTexture(backendTexture, std::move(finishedCallback),
color.array());
863 if (!this->
caps()->areColorTypeAndFormatCompatible(grColorType,
format)) {
870 return fGpu->clearBackendTexture(backendTexture,
871 std::move(finishedCallback),
872 swizzledColor.array());
887 if (!srcData || numLevels <= 0) {
892 int numExpectedLevels = 1;
895 backendTexture.
height()) + 1;
897 if (numLevels != numExpectedLevels) {
905 std::move(finishedCallback));
922 mipmapped, isProtected);
928 beTex, std::move(finishedCallback), data, size)) {
957 compression, {
width,
height},
nullptr, mipmapped == skgpu::Mipmapped::kYes);
958 auto storage = std::make_unique<char[]>(size);
965 std::move(finishedCallback),
982 mipmapped, isProtected, finishedProc,
990 const void* compressedData,
1008 std::move(finishedCallback),
1026 isProtected, finishedProc, finishedContext);
1052 static_cast<char*
>(storage.
get()),
1054 return fGpu->updateCompressedBackendTexture(backendTexture,
1055 std::move(finishedCallback),
1061 const void* compressedData,
1071 if (!compressedData) {
1075 return fGpu->updateCompressedBackendTexture(backendTexture,
1076 std::move(finishedCallback),
1094 return fGpu->setBackendTextureState(backendTexture,
state, previousState, std::move(
callback));
1109 return fGpu->setBackendRenderTargetState(backendRenderTarget,
state, previousState,
1121 fGpu->deleteBackendTexture(backendTex);
1127 return fGpu->precompileShader(
key, data);
1130#ifdef SK_ENABLE_DUMP_GPU
1133SkString GrDirectContext::dump()
const {
1136 writer.beginObject();
1138 writer.appendCString(
"backend", GrBackendApiToStr(this->
backend()));
1140 writer.appendName(
"caps");
1143 writer.appendName(
"gpu");
1144 this->fGpu->dumpJSON(&writer);
1146 writer.appendName(
"context");
1158 stream.copyToAndReset(
result.data());
1166 return MakeMock(mockOptions, defaultOptions);
1177 if (!direct->init()) {
1188 return MakeDirect3D(backendContext, defaultOptions);
1199 if (!direct->init()) {
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
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)
@ kBorrow_GrWrapOwnership
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
@ kTopLeft_GrSurfaceOrigin
void * GrGpuFinishedContext
void(* GrGpuFinishedProc)(GrGpuFinishedContext finishedContext)
#define SkDEBUGFAIL(message)
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)
static constexpr uint32_t SK_InvalidUniqueID
SkISize dimensions() const
GrBackendFormat getBackendFormat() const
skgpu::Mipmapped mipmapped() const
const GrCaps * caps() const
const GrShaderCaps * shaderCaps() const
virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const =0
void dumpJSON(SkJSONWriter *) const
bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat &format) const
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
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 *)
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)
void checkAsyncWorkCompletion()
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={})
void storeVkPipelineCacheData()
bool wait(int numSemaphores, const GrBackendSemaphore *waitSemaphores, bool deleteSemaphoresAfterWait=true)
void getResourceCacheUsage(int *resourceCount, size_t *resourceBytes) const
void dumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump) const
void resetGLTextureBindings()
void getResourceCacheLimits(int *maxResources, size_t *maxResourceBytes) const
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
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)
GrBackendTexture createCompressedBackendTexture(SkISize dimensions, const GrBackendFormat &, skgpu::Mipmapped, GrProtected)
bool updateCompressedBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, const void *data, size_t length)
GrBackendTexture createBackendTexture(SkISize dimensions, const GrBackendFormat &, GrRenderable, skgpu::Mipmapped, GrProtected, std::string_view label)
bool clearBackendTexture(const GrBackendTexture &, sk_sp< skgpu::RefCntedCallback > finishedCallback, std::array< float, 4 > color)
skgpu::SingleOwner * singleOwner() const
static std::unique_ptr< GrGpu > Make(const GrMockOptions *, const GrContextOptions &, GrDirectContext *)
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 destroyDrawingManager()
void abandonContext() override
virtual GrSemaphoresSubmitted flush(GrDirectContext *, const GrFlushInfo &) const =0
static int ComputeLevelCount(int baseWidth, int baseHeight)
SkColorType colorType() const
virtual void dumpNumericValue(const char *dumpName, const char *valueName, const char *units, uint64_t value)=0
static sk_sp< RefCntedCallback > Make(Callback proc, Context ctx)
constexpr std::array< float, 4 > applyTo(std::array< float, 4 > color) const
GrSurfaceProxy * asSurfaceProxy()
bool writePixels(GrDirectContext *dContext, GrCPixmap src, SkIPoint dstPt)
void purgeStaleBlobs() SK_EXCLUDES(fSpinLock)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
uint32_t uint32_t * format
#define ASSERT_SINGLE_OWNER
@ kNoAccess
back-end surface will not be used by client
void FillInCompressedData(SkTextureCompressionType type, SkISize dimensions, skgpu::Mipmapped mipmapped, char *dstPixels, const SkColor4f &colorf)
PersistentCache * fPersistentCache
GrGpuFinishedProc fFinishedProc
bool supportsDistanceFieldText() const
#define TRACE_EVENT0(category_group, name)