xref: /aosp_15_r20/external/skia/src/gpu/graphite/ResourceProvider.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceProvider.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTileMode.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/BackendTexture.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTraceEvent.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Buffer.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Caps.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/CommandBuffer.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ComputePipeline.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextUtils.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GlobalCache.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GraphicsPipeline.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GraphicsPipelineDesc.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Log.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RenderPassDesc.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RendererProvider.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceCache.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Sampler.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/SharedContext.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Texture.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLCompiler.h"
31*c8dee2aaSAndroid Build Coastguard Worker 
32*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
33*c8dee2aaSAndroid Build Coastguard Worker 
34*c8dee2aaSAndroid Build Coastguard Worker // This is only used when tracing is enabled at compile time.
to_str(const SharedContext * ctx,const GraphicsPipelineDesc & gpDesc,const RenderPassDesc & rpDesc)35*c8dee2aaSAndroid Build Coastguard Worker [[maybe_unused]] static std::string to_str(const SharedContext* ctx,
36*c8dee2aaSAndroid Build Coastguard Worker                                            const GraphicsPipelineDesc& gpDesc,
37*c8dee2aaSAndroid Build Coastguard Worker                                            const RenderPassDesc& rpDesc) {
38*c8dee2aaSAndroid Build Coastguard Worker     const ShaderCodeDictionary* dict = ctx->shaderCodeDictionary();
39*c8dee2aaSAndroid Build Coastguard Worker     const RenderStep* step = ctx->rendererProvider()->lookup(gpDesc.renderStepID());
40*c8dee2aaSAndroid Build Coastguard Worker     return GetPipelineLabel(dict, rpDesc, step, gpDesc.paintParamsID());
41*c8dee2aaSAndroid Build Coastguard Worker }
42*c8dee2aaSAndroid Build Coastguard Worker 
ResourceProvider(SharedContext * sharedContext,SingleOwner * singleOwner,uint32_t recorderID,size_t resourceBudget)43*c8dee2aaSAndroid Build Coastguard Worker ResourceProvider::ResourceProvider(SharedContext* sharedContext,\
44*c8dee2aaSAndroid Build Coastguard Worker                                    SingleOwner* singleOwner,
45*c8dee2aaSAndroid Build Coastguard Worker                                    uint32_t recorderID,
46*c8dee2aaSAndroid Build Coastguard Worker                                    size_t resourceBudget)
47*c8dee2aaSAndroid Build Coastguard Worker         : fSharedContext(sharedContext)
48*c8dee2aaSAndroid Build Coastguard Worker         , fResourceCache(ResourceCache::Make(singleOwner, recorderID, resourceBudget)) {}
49*c8dee2aaSAndroid Build Coastguard Worker 
~ResourceProvider()50*c8dee2aaSAndroid Build Coastguard Worker ResourceProvider::~ResourceProvider() {
51*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->shutdown();
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateGraphicsPipeline(const RuntimeEffectDictionary * runtimeDict,const GraphicsPipelineDesc & pipelineDesc,const RenderPassDesc & renderPassDesc,SkEnumBitMask<PipelineCreationFlags> pipelineCreationFlags)54*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GraphicsPipeline> ResourceProvider::findOrCreateGraphicsPipeline(
55*c8dee2aaSAndroid Build Coastguard Worker         const RuntimeEffectDictionary* runtimeDict,
56*c8dee2aaSAndroid Build Coastguard Worker         const GraphicsPipelineDesc& pipelineDesc,
57*c8dee2aaSAndroid Build Coastguard Worker         const RenderPassDesc& renderPassDesc,
58*c8dee2aaSAndroid Build Coastguard Worker         SkEnumBitMask<PipelineCreationFlags> pipelineCreationFlags) {
59*c8dee2aaSAndroid Build Coastguard Worker     auto globalCache = fSharedContext->globalCache();
60*c8dee2aaSAndroid Build Coastguard Worker     UniqueKey pipelineKey = fSharedContext->caps()->makeGraphicsPipelineKey(pipelineDesc,
61*c8dee2aaSAndroid Build Coastguard Worker                                                                             renderPassDesc);
62*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GraphicsPipeline> pipeline = globalCache->findGraphicsPipeline(pipelineKey);
63*c8dee2aaSAndroid Build Coastguard Worker     if (!pipeline) {
64*c8dee2aaSAndroid Build Coastguard Worker         // Haven't encountered this pipeline, so create a new one. Since pipelines are shared
65*c8dee2aaSAndroid Build Coastguard Worker         // across Recorders, we could theoretically create equivalent pipelines on different
66*c8dee2aaSAndroid Build Coastguard Worker         // threads. If this happens, GlobalCache returns the first-through-gate pipeline and we
67*c8dee2aaSAndroid Build Coastguard Worker         // discard the redundant pipeline. While this is wasted effort in the rare event of a race,
68*c8dee2aaSAndroid Build Coastguard Worker         // it allows pipeline creation to be performed without locking the global cache.
69*c8dee2aaSAndroid Build Coastguard Worker         // NOTE: The parameters to TRACE_EVENT are only evaluated inside an if-block when the
70*c8dee2aaSAndroid Build Coastguard Worker         // category is enabled.
71*c8dee2aaSAndroid Build Coastguard Worker         TRACE_EVENT1_ALWAYS(
72*c8dee2aaSAndroid Build Coastguard Worker                 "skia.shaders", "createGraphicsPipeline", "desc",
73*c8dee2aaSAndroid Build Coastguard Worker                 TRACE_STR_COPY(to_str(fSharedContext, pipelineDesc, renderPassDesc).c_str()));
74*c8dee2aaSAndroid Build Coastguard Worker         pipeline = this->createGraphicsPipeline(runtimeDict, pipelineDesc, renderPassDesc,
75*c8dee2aaSAndroid Build Coastguard Worker                                                 pipelineCreationFlags);
76*c8dee2aaSAndroid Build Coastguard Worker         if (pipeline) {
77*c8dee2aaSAndroid Build Coastguard Worker             // TODO: Should we store a null pipeline if we failed to create one so that subsequent
78*c8dee2aaSAndroid Build Coastguard Worker             // usage immediately sees that the pipeline cannot be created, vs. retrying every time?
79*c8dee2aaSAndroid Build Coastguard Worker             pipeline = globalCache->addGraphicsPipeline(pipelineKey, std::move(pipeline));
80*c8dee2aaSAndroid Build Coastguard Worker         }
81*c8dee2aaSAndroid Build Coastguard Worker     }
82*c8dee2aaSAndroid Build Coastguard Worker     return pipeline;
83*c8dee2aaSAndroid Build Coastguard Worker }
84*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateComputePipeline(const ComputePipelineDesc & pipelineDesc)85*c8dee2aaSAndroid Build Coastguard Worker sk_sp<ComputePipeline> ResourceProvider::findOrCreateComputePipeline(
86*c8dee2aaSAndroid Build Coastguard Worker         const ComputePipelineDesc& pipelineDesc) {
87*c8dee2aaSAndroid Build Coastguard Worker     auto globalCache = fSharedContext->globalCache();
88*c8dee2aaSAndroid Build Coastguard Worker     UniqueKey pipelineKey = fSharedContext->caps()->makeComputePipelineKey(pipelineDesc);
89*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<ComputePipeline> pipeline = globalCache->findComputePipeline(pipelineKey);
90*c8dee2aaSAndroid Build Coastguard Worker     if (!pipeline) {
91*c8dee2aaSAndroid Build Coastguard Worker         pipeline = this->createComputePipeline(pipelineDesc);
92*c8dee2aaSAndroid Build Coastguard Worker         if (pipeline) {
93*c8dee2aaSAndroid Build Coastguard Worker             pipeline = globalCache->addComputePipeline(pipelineKey, std::move(pipeline));
94*c8dee2aaSAndroid Build Coastguard Worker         }
95*c8dee2aaSAndroid Build Coastguard Worker     }
96*c8dee2aaSAndroid Build Coastguard Worker     return pipeline;
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////
100*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateScratchTexture(SkISize dimensions,const TextureInfo & info,std::string_view label,skgpu::Budgeted budgeted)101*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> ResourceProvider::findOrCreateScratchTexture(SkISize dimensions,
102*c8dee2aaSAndroid Build Coastguard Worker                                                             const TextureInfo& info,
103*c8dee2aaSAndroid Build Coastguard Worker                                                             std::string_view label,
104*c8dee2aaSAndroid Build Coastguard Worker                                                             skgpu::Budgeted budgeted) {
105*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(info.isValid());
106*c8dee2aaSAndroid Build Coastguard Worker 
107*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key;
110*c8dee2aaSAndroid Build Coastguard Worker     // Scratch textures are not shareable
111*c8dee2aaSAndroid Build Coastguard Worker     fSharedContext->caps()->buildKeyForTexture(dimensions, info, kType, Shareable::kNo, &key);
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     return this->findOrCreateTextureWithKey(dimensions,
114*c8dee2aaSAndroid Build Coastguard Worker                                             info,
115*c8dee2aaSAndroid Build Coastguard Worker                                             key,
116*c8dee2aaSAndroid Build Coastguard Worker                                             std::move(label),
117*c8dee2aaSAndroid Build Coastguard Worker                                             budgeted);
118*c8dee2aaSAndroid Build Coastguard Worker }
119*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateDepthStencilAttachment(SkISize dimensions,const TextureInfo & info)120*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> ResourceProvider::findOrCreateDepthStencilAttachment(SkISize dimensions,
121*c8dee2aaSAndroid Build Coastguard Worker                                                                     const TextureInfo& info) {
122*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(info.isValid());
123*c8dee2aaSAndroid Build Coastguard Worker 
124*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
125*c8dee2aaSAndroid Build Coastguard Worker 
126*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key;
127*c8dee2aaSAndroid Build Coastguard Worker     // We always make depth and stencil attachments shareable. Between any render pass the values
128*c8dee2aaSAndroid Build Coastguard Worker     // are reset. Thus it is safe to be used by multiple different render passes without worry of
129*c8dee2aaSAndroid Build Coastguard Worker     // stomping on each other's data.
130*c8dee2aaSAndroid Build Coastguard Worker     fSharedContext->caps()->buildKeyForTexture(dimensions, info, kType, Shareable::kYes, &key);
131*c8dee2aaSAndroid Build Coastguard Worker 
132*c8dee2aaSAndroid Build Coastguard Worker     return this->findOrCreateTextureWithKey(dimensions,
133*c8dee2aaSAndroid Build Coastguard Worker                                             info,
134*c8dee2aaSAndroid Build Coastguard Worker                                             key,
135*c8dee2aaSAndroid Build Coastguard Worker                                             "DepthStencilAttachment",
136*c8dee2aaSAndroid Build Coastguard Worker                                             skgpu::Budgeted::kYes);
137*c8dee2aaSAndroid Build Coastguard Worker }
138*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateDiscardableMSAAAttachment(SkISize dimensions,const TextureInfo & info)139*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> ResourceProvider::findOrCreateDiscardableMSAAAttachment(SkISize dimensions,
140*c8dee2aaSAndroid Build Coastguard Worker                                                                        const TextureInfo& info) {
141*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(info.isValid());
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key;
146*c8dee2aaSAndroid Build Coastguard Worker     // We always make discardable msaa attachments shareable. Between any render pass we discard
147*c8dee2aaSAndroid Build Coastguard Worker     // the values of the MSAA texture. Thus it is safe to be used by multiple different render
148*c8dee2aaSAndroid Build Coastguard Worker     // passes without worry of stomping on each other's data. It is the callings code's
149*c8dee2aaSAndroid Build Coastguard Worker     // responsibility to populate the discardable MSAA texture with data at the start of the
150*c8dee2aaSAndroid Build Coastguard Worker     // render pass.
151*c8dee2aaSAndroid Build Coastguard Worker     fSharedContext->caps()->buildKeyForTexture(dimensions, info, kType, Shareable::kYes, &key);
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker     return this->findOrCreateTextureWithKey(dimensions,
154*c8dee2aaSAndroid Build Coastguard Worker                                             info,
155*c8dee2aaSAndroid Build Coastguard Worker                                             key,
156*c8dee2aaSAndroid Build Coastguard Worker                                             "DiscardableMSAAAttachment",
157*c8dee2aaSAndroid Build Coastguard Worker                                             skgpu::Budgeted::kYes);
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateTextureWithKey(SkISize dimensions,const TextureInfo & info,const GraphiteResourceKey & key,std::string_view label,skgpu::Budgeted budgeted)160*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> ResourceProvider::findOrCreateTextureWithKey(SkISize dimensions,
161*c8dee2aaSAndroid Build Coastguard Worker                                                             const TextureInfo& info,
162*c8dee2aaSAndroid Build Coastguard Worker                                                             const GraphiteResourceKey& key,
163*c8dee2aaSAndroid Build Coastguard Worker                                                             std::string_view label,
164*c8dee2aaSAndroid Build Coastguard Worker                                                             skgpu::Budgeted budgeted) {
165*c8dee2aaSAndroid Build Coastguard Worker     // If the resource is shareable it should be budgeted since it shouldn't be backing any client
166*c8dee2aaSAndroid Build Coastguard Worker     // owned object.
167*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(key.shareable() == Shareable::kNo || budgeted == skgpu::Budgeted::kYes);
168*c8dee2aaSAndroid Build Coastguard Worker 
169*c8dee2aaSAndroid Build Coastguard Worker     if (Resource* resource = fResourceCache->findAndRefResource(key, budgeted)) {
170*c8dee2aaSAndroid Build Coastguard Worker         resource->setLabel(std::move(label));
171*c8dee2aaSAndroid Build Coastguard Worker         return sk_sp<Texture>(static_cast<Texture*>(resource));
172*c8dee2aaSAndroid Build Coastguard Worker     }
173*c8dee2aaSAndroid Build Coastguard Worker 
174*c8dee2aaSAndroid Build Coastguard Worker     auto tex = this->createTexture(dimensions, info, budgeted);
175*c8dee2aaSAndroid Build Coastguard Worker     if (!tex) {
176*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
177*c8dee2aaSAndroid Build Coastguard Worker     }
178*c8dee2aaSAndroid Build Coastguard Worker 
179*c8dee2aaSAndroid Build Coastguard Worker     tex->setKey(key);
180*c8dee2aaSAndroid Build Coastguard Worker     tex->setLabel(std::move(label));
181*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->insertResource(tex.get());
182*c8dee2aaSAndroid Build Coastguard Worker 
183*c8dee2aaSAndroid Build Coastguard Worker     return tex;
184*c8dee2aaSAndroid Build Coastguard Worker }
185*c8dee2aaSAndroid Build Coastguard Worker 
createWrappedTexture(const BackendTexture & backendTexture,std::string_view label)186*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> ResourceProvider::createWrappedTexture(const BackendTexture& backendTexture,
187*c8dee2aaSAndroid Build Coastguard Worker                                                       std::string_view label) {
188*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<Texture> texture = this->onCreateWrappedTexture(backendTexture);
189*c8dee2aaSAndroid Build Coastguard Worker     if (texture) {
190*c8dee2aaSAndroid Build Coastguard Worker         texture->setLabel(std::move(label));
191*c8dee2aaSAndroid Build Coastguard Worker     }
192*c8dee2aaSAndroid Build Coastguard Worker     return texture;
193*c8dee2aaSAndroid Build Coastguard Worker }
194*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateCompatibleSampler(const SamplerDesc & samplerDesc)195*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Sampler> ResourceProvider::findOrCreateCompatibleSampler(const SamplerDesc& samplerDesc) {
196*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key = fSharedContext->caps()->makeSamplerKey(samplerDesc);
197*c8dee2aaSAndroid Build Coastguard Worker 
198*c8dee2aaSAndroid Build Coastguard Worker     if (Resource* resource = fResourceCache->findAndRefResource(key, skgpu::Budgeted::kYes)) {
199*c8dee2aaSAndroid Build Coastguard Worker         return sk_sp<Sampler>(static_cast<Sampler*>(resource));
200*c8dee2aaSAndroid Build Coastguard Worker     }
201*c8dee2aaSAndroid Build Coastguard Worker 
202*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<Sampler> sampler = this->createSampler(samplerDesc);
203*c8dee2aaSAndroid Build Coastguard Worker     if (!sampler) {
204*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
205*c8dee2aaSAndroid Build Coastguard Worker     }
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     sampler->setKey(key);
208*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->insertResource(sampler.get());
209*c8dee2aaSAndroid Build Coastguard Worker     return sampler;
210*c8dee2aaSAndroid Build Coastguard Worker }
211*c8dee2aaSAndroid Build Coastguard Worker 
findOrCreateBuffer(size_t size,BufferType type,AccessPattern accessPattern,std::string_view label)212*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Buffer> ResourceProvider::findOrCreateBuffer(size_t size,
213*c8dee2aaSAndroid Build Coastguard Worker                                                    BufferType type,
214*c8dee2aaSAndroid Build Coastguard Worker                                                    AccessPattern accessPattern,
215*c8dee2aaSAndroid Build Coastguard Worker                                                    std::string_view label) {
216*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
217*c8dee2aaSAndroid Build Coastguard Worker 
218*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key;
219*c8dee2aaSAndroid Build Coastguard Worker     {
220*c8dee2aaSAndroid Build Coastguard Worker         // For the key we need ((sizeof(size_t) + (sizeof(uint32_t) - 1)) / (sizeof(uint32_t))
221*c8dee2aaSAndroid Build Coastguard Worker         // uint32_t's for the size and one uint32_t for the rest.
222*c8dee2aaSAndroid Build Coastguard Worker         static_assert(sizeof(uint32_t) == 4);
223*c8dee2aaSAndroid Build Coastguard Worker         static const int kSizeKeyNum32DataCnt = (sizeof(size_t) + 3) / 4;
224*c8dee2aaSAndroid Build Coastguard Worker         static const int kKeyNum32DataCnt =  kSizeKeyNum32DataCnt + 1;
225*c8dee2aaSAndroid Build Coastguard Worker 
226*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(static_cast<uint32_t>(type) < (1u << 4));
227*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(static_cast<uint32_t>(accessPattern) < (1u << 1));
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker         GraphiteResourceKey::Builder builder(&key, kType, kKeyNum32DataCnt, Shareable::kNo);
230*c8dee2aaSAndroid Build Coastguard Worker         builder[0] = (static_cast<uint32_t>(type) << 0) |
231*c8dee2aaSAndroid Build Coastguard Worker                      (static_cast<uint32_t>(accessPattern) << 4);
232*c8dee2aaSAndroid Build Coastguard Worker         size_t szKey = size;
233*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kSizeKeyNum32DataCnt; ++i) {
234*c8dee2aaSAndroid Build Coastguard Worker             builder[i + 1] = (uint32_t) szKey;
235*c8dee2aaSAndroid Build Coastguard Worker 
236*c8dee2aaSAndroid Build Coastguard Worker             // If size_t is 4 bytes, we cannot do a shift of 32 or else we get a warning/error that
237*c8dee2aaSAndroid Build Coastguard Worker             // shift amount is >= width of the type.
238*c8dee2aaSAndroid Build Coastguard Worker             if constexpr(kSizeKeyNum32DataCnt > 1) {
239*c8dee2aaSAndroid Build Coastguard Worker                 szKey = szKey >> 32;
240*c8dee2aaSAndroid Build Coastguard Worker             }
241*c8dee2aaSAndroid Build Coastguard Worker         }
242*c8dee2aaSAndroid Build Coastguard Worker     }
243*c8dee2aaSAndroid Build Coastguard Worker 
244*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Budgeted budgeted = skgpu::Budgeted::kYes;
245*c8dee2aaSAndroid Build Coastguard Worker     if (Resource* resource = fResourceCache->findAndRefResource(key, budgeted)) {
246*c8dee2aaSAndroid Build Coastguard Worker         resource->setLabel(std::move(label));
247*c8dee2aaSAndroid Build Coastguard Worker         return sk_sp<Buffer>(static_cast<Buffer*>(resource));
248*c8dee2aaSAndroid Build Coastguard Worker     }
249*c8dee2aaSAndroid Build Coastguard Worker     auto buffer = this->createBuffer(size, type, accessPattern);
250*c8dee2aaSAndroid Build Coastguard Worker     if (!buffer) {
251*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
252*c8dee2aaSAndroid Build Coastguard Worker     }
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker     buffer->setKey(key);
255*c8dee2aaSAndroid Build Coastguard Worker     buffer->setLabel(std::move(label));
256*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->insertResource(buffer.get());
257*c8dee2aaSAndroid Build Coastguard Worker     return buffer;
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker 
260*c8dee2aaSAndroid Build Coastguard Worker namespace {
dimensions_are_valid(const int maxTextureSize,const SkISize & dimensions)261*c8dee2aaSAndroid Build Coastguard Worker bool dimensions_are_valid(const int maxTextureSize, const SkISize& dimensions) {
262*c8dee2aaSAndroid Build Coastguard Worker     if (dimensions.isEmpty() ||
263*c8dee2aaSAndroid Build Coastguard Worker         dimensions.width()  > maxTextureSize ||
264*c8dee2aaSAndroid Build Coastguard Worker         dimensions.height() > maxTextureSize) {
265*c8dee2aaSAndroid Build Coastguard Worker         SKGPU_LOG_W("Call to createBackendTexture has requested dimensions (%d, %d) larger than the"
266*c8dee2aaSAndroid Build Coastguard Worker                     " supported gpu max texture size: %d. Or the dimensions are empty.",
267*c8dee2aaSAndroid Build Coastguard Worker                     dimensions.fWidth, dimensions.fHeight, maxTextureSize);
268*c8dee2aaSAndroid Build Coastguard Worker         return false;
269*c8dee2aaSAndroid Build Coastguard Worker     }
270*c8dee2aaSAndroid Build Coastguard Worker     return true;
271*c8dee2aaSAndroid Build Coastguard Worker }
272*c8dee2aaSAndroid Build Coastguard Worker }
273*c8dee2aaSAndroid Build Coastguard Worker 
createBackendTexture(SkISize dimensions,const TextureInfo & info)274*c8dee2aaSAndroid Build Coastguard Worker BackendTexture ResourceProvider::createBackendTexture(SkISize dimensions, const TextureInfo& info) {
275*c8dee2aaSAndroid Build Coastguard Worker     if (!dimensions_are_valid(fSharedContext->caps()->maxTextureSize(), dimensions)) {
276*c8dee2aaSAndroid Build Coastguard Worker         return {};
277*c8dee2aaSAndroid Build Coastguard Worker     }
278*c8dee2aaSAndroid Build Coastguard Worker     return this->onCreateBackendTexture(dimensions, info);
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_ANDROID
createBackendTexture(AHardwareBuffer * hardwareBuffer,bool isRenderable,bool isProtectedContent,SkISize dimensions,bool fromAndroidWindow) const282*c8dee2aaSAndroid Build Coastguard Worker BackendTexture ResourceProvider::createBackendTexture(AHardwareBuffer* hardwareBuffer,
283*c8dee2aaSAndroid Build Coastguard Worker                                                       bool isRenderable,
284*c8dee2aaSAndroid Build Coastguard Worker                                                       bool isProtectedContent,
285*c8dee2aaSAndroid Build Coastguard Worker                                                       SkISize dimensions,
286*c8dee2aaSAndroid Build Coastguard Worker                                                       bool fromAndroidWindow) const {
287*c8dee2aaSAndroid Build Coastguard Worker     if (!dimensions_are_valid(fSharedContext->caps()->maxTextureSize(), dimensions)) {
288*c8dee2aaSAndroid Build Coastguard Worker         return {};
289*c8dee2aaSAndroid Build Coastguard Worker     }
290*c8dee2aaSAndroid Build Coastguard Worker     return this->onCreateBackendTexture(hardwareBuffer,
291*c8dee2aaSAndroid Build Coastguard Worker                                         isRenderable,
292*c8dee2aaSAndroid Build Coastguard Worker                                         isProtectedContent,
293*c8dee2aaSAndroid Build Coastguard Worker                                         dimensions,
294*c8dee2aaSAndroid Build Coastguard Worker                                         fromAndroidWindow);
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker 
onCreateBackendTexture(AHardwareBuffer *,bool isRenderable,bool isProtectedContent,SkISize dimensions,bool fromAndroidWindow) const297*c8dee2aaSAndroid Build Coastguard Worker BackendTexture ResourceProvider::onCreateBackendTexture(AHardwareBuffer*,
298*c8dee2aaSAndroid Build Coastguard Worker                                                         bool isRenderable,
299*c8dee2aaSAndroid Build Coastguard Worker                                                         bool isProtectedContent,
300*c8dee2aaSAndroid Build Coastguard Worker                                                         SkISize dimensions,
301*c8dee2aaSAndroid Build Coastguard Worker                                                         bool fromAndroidWindow) const {
302*c8dee2aaSAndroid Build Coastguard Worker     return {};
303*c8dee2aaSAndroid Build Coastguard Worker }
304*c8dee2aaSAndroid Build Coastguard Worker #endif
305*c8dee2aaSAndroid Build Coastguard Worker 
deleteBackendTexture(const BackendTexture & texture)306*c8dee2aaSAndroid Build Coastguard Worker void ResourceProvider::deleteBackendTexture(const BackendTexture& texture) {
307*c8dee2aaSAndroid Build Coastguard Worker     this->onDeleteBackendTexture(texture);
308*c8dee2aaSAndroid Build Coastguard Worker }
309*c8dee2aaSAndroid Build Coastguard Worker 
freeGpuResources()310*c8dee2aaSAndroid Build Coastguard Worker void ResourceProvider::freeGpuResources() {
311*c8dee2aaSAndroid Build Coastguard Worker     this->onFreeGpuResources();
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Are there Resources that are ref'd by the ResourceProvider or its subclasses that need
314*c8dee2aaSAndroid Build Coastguard Worker     // be released? If we ever find that we're holding things directly on the ResourceProviders we
315*c8dee2aaSAndroid Build Coastguard Worker     // call down into the subclasses to allow them to release things.
316*c8dee2aaSAndroid Build Coastguard Worker 
317*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->purgeResources();
318*c8dee2aaSAndroid Build Coastguard Worker }
319*c8dee2aaSAndroid Build Coastguard Worker 
purgeResourcesNotUsedSince(StdSteadyClock::time_point purgeTime)320*c8dee2aaSAndroid Build Coastguard Worker void ResourceProvider::purgeResourcesNotUsedSince(StdSteadyClock::time_point purgeTime) {
321*c8dee2aaSAndroid Build Coastguard Worker     this->onPurgeResourcesNotUsedSince(purgeTime);
322*c8dee2aaSAndroid Build Coastguard Worker     fResourceCache->purgeResourcesNotUsedSince(purgeTime);
323*c8dee2aaSAndroid Build Coastguard Worker }
324*c8dee2aaSAndroid Build Coastguard Worker 
325*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::graphite
326