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