blob: 10ceefb4cbcd727b54a7a2c0fdfeef7db3533a53 [file] [log] [blame]
bsalomoned0bcad2015-05-04 10:36:42 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrResourceProvider.h"
Brian Salomondbf70722019-02-07 11:31:24 -05009#include "../private/GrSingleOwner.h"
Greg Daniela5cb7812017-06-16 09:45:32 -040010#include "GrBackendSemaphore.h"
robertphillips5fa7f302016-07-21 09:21:04 -070011#include "GrCaps.h"
Robert Phillips26c90e02017-03-14 14:39:29 -040012#include "GrContext.h"
Robert Phillipse78b7252017-04-06 07:59:41 -040013#include "GrContextPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070014#include "GrGpu.h"
Brian Salomondbf70722019-02-07 11:31:24 -050015#include "GrGpuBuffer.h"
Robert Phillips67d52cf2017-06-05 13:38:13 -040016#include "GrPath.h"
kkinnunencabe20c2015-06-01 01:37:26 -070017#include "GrPathRendering.h"
Robert Phillips0bd24dc2018-01-16 08:06:32 -050018#include "GrProxyProvider.h"
egdanielec00d942015-09-14 12:56:10 -070019#include "GrRenderTargetPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070020#include "GrResourceCache.h"
21#include "GrResourceKey.h"
Greg Danield85f97d2017-03-07 13:37:21 -050022#include "GrSemaphore.h"
egdanielec00d942015-09-14 12:56:10 -070023#include "GrStencilAttachment.h"
Brian Osman32342f02017-03-04 08:12:46 -050024#include "GrTexturePriv.h"
Robert Phillips45fdae12017-04-17 12:57:27 -040025#include "SkGr.h"
halcanary4dbbd042016-06-07 17:21:10 -070026#include "SkMathPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070027
28GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
29
Robert Phillips1bfece82017-06-01 13:56:52 -040030const uint32_t GrResourceProvider::kMinScratchTextureSize = 16;
Brian Osman32342f02017-03-04 08:12:46 -050031
Robert Phillipsa3f70262018-02-08 10:59:38 -050032#ifdef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION
33static const bool kDefaultExplicitlyAllocateGPUResources = false;
34#else
35static const bool kDefaultExplicitlyAllocateGPUResources = true;
36#endif
37
Brian Osman32342f02017-03-04 08:12:46 -050038#define ASSERT_SINGLE_OWNER \
39 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
40
Robert Phillips4150eea2018-02-07 17:08:21 -050041GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner,
Robert Phillipsa3f70262018-02-08 10:59:38 -050042 GrContextOptions::Enable explicitlyAllocateGPUResources)
Brian Osman32342f02017-03-04 08:12:46 -050043 : fCache(cache)
44 , fGpu(gpu)
45#ifdef SK_DEBUG
46 , fSingleOwner(owner)
47#endif
Robert Phillips4150eea2018-02-07 17:08:21 -050048{
Robert Phillipsa3f70262018-02-08 10:59:38 -050049 if (GrContextOptions::Enable::kNo == explicitlyAllocateGPUResources) {
50 fExplicitlyAllocateGPUResources = false;
51 } else if (GrContextOptions::Enable::kYes == explicitlyAllocateGPUResources) {
52 fExplicitlyAllocateGPUResources = true;
53 } else {
54 fExplicitlyAllocateGPUResources = kDefaultExplicitlyAllocateGPUResources;
55 }
56
Robert Phillips26c90e02017-03-14 14:39:29 -040057 fCaps = sk_ref_sp(fGpu->caps());
58
bsalomoned0bcad2015-05-04 10:36:42 -070059 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
60 fQuadIndexBufferKey = gQuadIndexBufferKey;
61}
62
Robert Phillips8e8c7552017-07-10 12:06:05 -040063sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Brian Osman2b23c4b2018-06-01 12:25:08 -040064 const GrMipLevel texels[], int mipLevelCount) {
Brian Osman32342f02017-03-04 08:12:46 -050065 ASSERT_SINGLE_OWNER
66
Robert Phillips7f1b4f82017-11-28 07:38:39 -050067 SkASSERT(mipLevelCount > 0);
Robert Phillips1119dc32017-04-11 12:54:57 -040068
Brian Osman32342f02017-03-04 08:12:46 -050069 if (this->isAbandoned()) {
70 return nullptr;
71 }
Robert Phillips1119dc32017-04-11 12:54:57 -040072
Brian Salomonbdecacf2018-02-02 20:32:49 -050073 GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
74 if (!fCaps->validateSurfaceDesc(desc, mipMapped)) {
Brian Osman32342f02017-03-04 08:12:46 -050075 return nullptr;
76 }
Brian Osman32342f02017-03-04 08:12:46 -050077
Brian Osman2b23c4b2018-06-01 12:25:08 -040078 return fGpu->createTexture(desc, budgeted, texels, mipLevelCount);
Brian Osman32342f02017-03-04 08:12:46 -050079}
80
Robert Phillips45fdae12017-04-17 12:57:27 -040081sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
Chris Daltond004e0b2018-09-27 09:28:03 -060082 SkBudgeted budgeted, Flags flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -040083 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
84 if (tex && SkBudgeted::kNo == budgeted) {
85 tex->resourcePriv().makeUnbudgeted();
86 }
87
88 return tex;
89}
90
Robert Phillips1afd4cd2018-01-08 13:40:32 -050091sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
92 SkBudgeted budgeted,
Greg Danielfb3abcd2018-02-02 15:48:33 -050093 SkBackingFit fit,
Chris Daltond004e0b2018-09-27 09:28:03 -060094 const GrMipLevel& mipLevel,
95 Flags flags) {
Robert Phillips774831a2017-04-20 10:19:33 -040096 ASSERT_SINGLE_OWNER
97
98 if (this->isAbandoned()) {
99 return nullptr;
100 }
101
Robert Phillips45fdae12017-04-17 12:57:27 -0400102 if (!mipLevel.fPixels) {
103 return nullptr;
104 }
105
Brian Salomonbdecacf2018-02-02 20:32:49 -0500106 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400107 return nullptr;
108 }
109
Robert Phillips45fdae12017-04-17 12:57:27 -0400110 GrContext* context = fGpu->getContext();
Robert Phillips9da87e02019-02-04 13:26:26 -0500111 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Robert Phillips45fdae12017-04-17 12:57:27 -0400112
Brian Salomon1fcac052018-05-09 16:33:09 -0400113 SkColorType colorType;
114 if (GrPixelConfigToColorType(desc.fConfig, &colorType)) {
Chris Daltond004e0b2018-09-27 09:28:03 -0600115 sk_sp<GrTexture> tex = (SkBackingFit::kApprox == fit)
116 ? this->createApproxTexture(desc, flags)
117 : this->createTexture(desc, budgeted, flags);
118 if (!tex) {
119 return nullptr;
120 }
121
122 sk_sp<GrTextureProxy> proxy = proxyProvider->createWrapped(std::move(tex),
123 kTopLeft_GrSurfaceOrigin);
Brian Salomon1fcac052018-05-09 16:33:09 -0400124 if (!proxy) {
125 return nullptr;
Robert Phillips45fdae12017-04-17 12:57:27 -0400126 }
Brian Salomon1fcac052018-05-09 16:33:09 -0400127 auto srcInfo = SkImageInfo::Make(desc.fWidth, desc.fHeight, colorType,
Brian Osman9363ac42018-06-01 16:10:53 -0400128 kUnknown_SkAlphaType);
Robert Phillips9da87e02019-02-04 13:26:26 -0500129 sk_sp<GrSurfaceContext> sContext = context->priv().makeWrappedSurfaceContext(
Brian Osman9363ac42018-06-01 16:10:53 -0400130 std::move(proxy));
Brian Salomon1fcac052018-05-09 16:33:09 -0400131 if (!sContext) {
132 return nullptr;
133 }
134 SkAssertResult(sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0));
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400135 return sk_ref_sp(sContext->asTextureProxy()->peekTexture());
Brian Salomon1fcac052018-05-09 16:33:09 -0400136 } else {
137 return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
Robert Phillips45fdae12017-04-17 12:57:27 -0400138 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400139}
140
Robert Phillipse78b7252017-04-06 07:59:41 -0400141sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Chris Daltond004e0b2018-09-27 09:28:03 -0600142 Flags flags) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400143 ASSERT_SINGLE_OWNER
Robert Phillipse78b7252017-04-06 07:59:41 -0400144 if (this->isAbandoned()) {
145 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500146 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400147
Brian Salomonbdecacf2018-02-02 20:32:49 -0500148 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400149 return nullptr;
150 }
151
Jim Van Verth1676cb92019-01-15 13:24:45 -0500152 // Compressed textures are read-only so they don't support re-use for scratch.
153 if (!GrPixelConfigIsCompressed(desc.fConfig)) {
154 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
155 if (tex) {
156 return tex;
157 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400158 }
159
Robert Phillips67d52cf2017-06-05 13:38:13 -0400160 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500161}
162
Robert Phillips67d52cf2017-06-05 13:38:13 -0400163sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
Chris Daltond004e0b2018-09-27 09:28:03 -0600164 Flags flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500165 ASSERT_SINGLE_OWNER
Chris Daltond004e0b2018-09-27 09:28:03 -0600166 SkASSERT(Flags::kNone == flags || Flags::kNoPendingIO == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500167
Brian Osman32342f02017-03-04 08:12:46 -0500168 if (this->isAbandoned()) {
169 return nullptr;
170 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400171
Jim Van Verth1676cb92019-01-15 13:24:45 -0500172 // Currently we don't recycle compressed textures as scratch.
173 if (GrPixelConfigIsCompressed(desc.fConfig)) {
174 return nullptr;
175 }
176
Brian Salomonbdecacf2018-02-02 20:32:49 -0500177 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400178 return nullptr;
179 }
180
Greg Daniel6b60b6e2017-09-26 16:37:12 -0400181 if (auto tex = this->refScratchTexture(desc, flags)) {
182 return tex;
183 }
184
Greg Daniel29bf84f2017-09-25 12:25:12 -0400185 SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
186
187 // bin by pow2 with a reasonable min
188 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
189 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
190 GrSurfaceDesc* wdesc = copyDesc.writable();
191 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
192 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
193 }
194
195 if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
196 return tex;
197 }
198
199 return fGpu->createTexture(*copyDesc, SkBudgeted::kYes);
Brian Osman32342f02017-03-04 08:12:46 -0500200}
201
Chris Daltond004e0b2018-09-27 09:28:03 -0600202sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc, Flags flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500203 ASSERT_SINGLE_OWNER
204 SkASSERT(!this->isAbandoned());
Jim Van Verth1676cb92019-01-15 13:24:45 -0500205 SkASSERT(!GrPixelConfigIsCompressed(desc.fConfig));
Brian Salomonbdecacf2018-02-02 20:32:49 -0500206 SkASSERT(fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo));
Brian Osman32342f02017-03-04 08:12:46 -0500207
Brian Salomond17b4a62017-05-23 16:53:47 -0400208 // We could make initial clears work with scratch textures but it is a rare case so we just opt
209 // to fall back to making a new texture.
Greg Daniel29bf84f2017-09-25 12:25:12 -0400210 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
211 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500212
213 GrScratchKey key;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400214 GrTexturePriv::ComputeScratchKey(desc, &key);
Chris Daltond004e0b2018-09-27 09:28:03 -0600215 auto scratchFlags = GrResourceCache::ScratchFlags::kNone;
216 if (Flags::kNoPendingIO & flags) {
217 scratchFlags |= GrResourceCache::ScratchFlags::kRequireNoPendingIO;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400218 } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
Brian Osman32342f02017-03-04 08:12:46 -0500219 // If it is not a render target then it will most likely be populated by
220 // writePixels() which will trigger a flush if the texture has pending IO.
Chris Daltond004e0b2018-09-27 09:28:03 -0600221 scratchFlags |= GrResourceCache::ScratchFlags::kPreferNoPendingIO;
Brian Osman32342f02017-03-04 08:12:46 -0500222 }
223 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
Greg Daniel29bf84f2017-09-25 12:25:12 -0400224 GrSurface::WorstCaseSize(desc),
225 scratchFlags);
Brian Osman32342f02017-03-04 08:12:46 -0500226 if (resource) {
227 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400228 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500229 }
230 }
231
Brian Osman32342f02017-03-04 08:12:46 -0500232 return nullptr;
233}
234
Greg Daniel7ef28f32017-04-20 16:41:55 +0000235sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Greg Daniel2268ad22018-11-15 09:27:38 -0500236 GrWrapOwnership ownership,
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500237 GrWrapCacheable cacheable,
238 GrIOType ioType) {
Brian Osman32342f02017-03-04 08:12:46 -0500239 ASSERT_SINGLE_OWNER
240 if (this->isAbandoned()) {
241 return nullptr;
242 }
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500243 return fGpu->wrapBackendTexture(tex, ownership, cacheable, ioType);
Brian Salomond17f6582017-07-19 18:28:58 -0400244}
245
246sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Brian Salomond17f6582017-07-19 18:28:58 -0400247 int sampleCnt,
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500248 GrWrapOwnership ownership,
249 GrWrapCacheable cacheable) {
Brian Salomond17f6582017-07-19 18:28:58 -0400250 ASSERT_SINGLE_OWNER
251 if (this->isAbandoned()) {
252 return nullptr;
253 }
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500254 return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership, cacheable);
Brian Osman32342f02017-03-04 08:12:46 -0500255}
256
257sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400258 const GrBackendRenderTarget& backendRT)
Brian Osman32342f02017-03-04 08:12:46 -0500259{
260 ASSERT_SINGLE_OWNER
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400261 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT);
Brian Osman32342f02017-03-04 08:12:46 -0500262}
263
Greg Danielb46add82019-01-02 14:51:29 -0500264sk_sp<GrRenderTarget> GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget(
265 const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo) {
266 ASSERT_SINGLE_OWNER
267 return this->isAbandoned() ? nullptr : fGpu->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
268 vkInfo);
269
270}
271
Brian Osman32342f02017-03-04 08:12:46 -0500272void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
273 GrGpuResource* resource) {
274 ASSERT_SINGLE_OWNER
275 if (this->isAbandoned() || !resource) {
276 return;
277 }
278 resource->resourcePriv().setUniqueKey(key);
279}
280
Brian Salomond28a79d2017-10-16 13:01:07 -0400281sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
Brian Osman32342f02017-03-04 08:12:46 -0500282 ASSERT_SINGLE_OWNER
Brian Salomond28a79d2017-10-16 13:01:07 -0400283 return this->isAbandoned() ? nullptr
284 : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
Brian Osman32342f02017-03-04 08:12:46 -0500285}
286
Brian Salomondbf70722019-02-07 11:31:24 -0500287sk_sp<const GrGpuBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrGpuBufferType intendedType,
288 size_t size,
289 const void* data,
290 const GrUniqueKey& key) {
291 if (auto buffer = this->findByUniqueKey<GrGpuBuffer>(key)) {
Kevin Lubickf7621cb2018-04-16 15:51:44 -0400292 return std::move(buffer);
Chris Dalton5d2de082017-12-19 10:40:23 -0700293 }
Brian Salomondbf70722019-02-07 11:31:24 -0500294 if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, data)) {
Chris Dalton133944a2018-11-16 23:30:29 -0500295 // We shouldn't bin and/or cache static buffers.
Brian Salomondbf70722019-02-07 11:31:24 -0500296 SkASSERT(buffer->size() == size);
Chris Dalton5d2de082017-12-19 10:40:23 -0700297 SkASSERT(!buffer->resourcePriv().getScratchKey().isValid());
298 SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly());
299 buffer->resourcePriv().setUniqueKey(key);
Brian Salomondbf70722019-02-07 11:31:24 -0500300 return sk_sp<const GrGpuBuffer>(buffer);
Chris Dalton5d2de082017-12-19 10:40:23 -0700301 }
302 return nullptr;
303}
304
Brian Salomondbf70722019-02-07 11:31:24 -0500305sk_sp<const GrGpuBuffer> GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
306 int patternSize,
307 int reps,
308 int vertCount,
309 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700310 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
311
Brian Salomon09d994e2016-12-21 11:14:46 -0500312 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
Brian Salomondbf70722019-02-07 11:31:24 -0500313 sk_sp<GrGpuBuffer> buffer(
314 this->createBuffer(bufferSize, GrGpuBufferType::kIndex, kStatic_GrAccessPattern));
bsalomoned0bcad2015-05-04 10:36:42 -0700315 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700316 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700317 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400318 uint16_t* data = (uint16_t*) buffer->map();
319 SkAutoTArray<uint16_t> temp;
320 if (!data) {
321 temp.reset(reps * patternSize);
322 data = temp.get();
323 }
bsalomoned0bcad2015-05-04 10:36:42 -0700324 for (int i = 0; i < reps; ++i) {
325 int baseIdx = i * patternSize;
326 uint16_t baseVert = (uint16_t)(i * vertCount);
327 for (int j = 0; j < patternSize; ++j) {
328 data[baseIdx+j] = baseVert + pattern[j];
329 }
330 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400331 if (temp.get()) {
332 if (!buffer->updateData(data, bufferSize)) {
333 return nullptr;
334 }
335 } else {
336 buffer->unmap();
bsalomoned0bcad2015-05-04 10:36:42 -0700337 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400338 this->assignUniqueKeyToResource(key, buffer.get());
Brian Salomond28a79d2017-10-16 13:01:07 -0400339 return std::move(buffer);
bsalomoned0bcad2015-05-04 10:36:42 -0700340}
341
Brian Salomon34169692017-08-28 15:32:01 -0400342static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
343
Brian Salomondbf70722019-02-07 11:31:24 -0500344sk_sp<const GrGpuBuffer> GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700345 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
Brian Salomon57caa662017-10-18 12:21:05 +0000346 static const uint16_t kPattern[] = { 0, 1, 2, 2, 1, 3 };
Chris Daltonff926502017-05-03 14:36:54 -0400347 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700348}
349
Brian Salomon763abf02018-05-01 18:49:38 +0000350int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
Brian Salomon34169692017-08-28 15:32:01 -0400351
Robert Phillips67d52cf2017-06-05 13:38:13 -0400352sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400353 if (this->isAbandoned()) {
354 return nullptr;
355 }
356
bsalomon706f08f2015-05-22 07:35:58 -0700357 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700358 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700359}
360
Brian Salomondbf70722019-02-07 11:31:24 -0500361sk_sp<GrGpuBuffer> GrResourceProvider::createBuffer(size_t size, GrGpuBufferType intendedType,
362 GrAccessPattern accessPattern,
363 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700364 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700365 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700366 }
cdaltond37fe762016-04-21 07:41:50 -0700367 if (kDynamic_GrAccessPattern != accessPattern) {
368 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
369 }
cdaltond37fe762016-04-21 07:41:50 -0700370 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400371 static const size_t MIN_SIZE = 1 << 12;
372 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700373
cdaltond37fe762016-04-21 07:41:50 -0700374 GrScratchKey key;
Brian Salomondbf70722019-02-07 11:31:24 -0500375 GrGpuBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
376 auto buffer =
377 sk_sp<GrGpuBuffer>(static_cast<GrGpuBuffer*>(this->cache()->findAndRefScratchResource(
378 key, allocSize, GrResourceCache::ScratchFlags::kNone)));
cdaltond37fe762016-04-21 07:41:50 -0700379 if (!buffer) {
380 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
381 if (!buffer) {
382 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700383 }
384 }
cdaltond37fe762016-04-21 07:41:50 -0700385 if (data) {
386 buffer->updateData(data, size);
387 }
388 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800389}
390
Robert Phillipsc0192e32017-09-21 12:00:26 -0400391bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
egdanielec00d942015-09-14 12:56:10 -0700392 SkASSERT(rt);
393 if (rt->renderTargetPriv().getStencilAttachment()) {
Robert Phillipsc0192e32017-09-21 12:00:26 -0400394 return true;
egdanielec00d942015-09-14 12:56:10 -0700395 }
396
397 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
398 GrUniqueKey sbKey;
399
400 int width = rt->width();
401 int height = rt->height();
402#if 0
403 if (this->caps()->oversizedStencilSupport()) {
404 width = SkNextPow2(width);
405 height = SkNextPow2(height);
406 }
407#endif
egdanielec00d942015-09-14 12:56:10 -0700408 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
409 rt->numStencilSamples(), &sbKey);
Brian Salomond28a79d2017-10-16 13:01:07 -0400410 auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey);
egdanielec00d942015-09-14 12:56:10 -0700411 if (!stencil) {
412 // Need to try and create a new stencil
Brian Salomond28a79d2017-10-16 13:01:07 -0400413 stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
Robert Phillips01a91282018-07-26 08:03:04 -0400414 if (!stencil) {
415 return false;
egdanielec00d942015-09-14 12:56:10 -0700416 }
Robert Phillips01a91282018-07-26 08:03:04 -0400417 this->assignUniqueKeyToResource(sbKey, stencil.get());
egdanielec00d942015-09-14 12:56:10 -0700418 }
Greg Danielcfa39352018-10-05 12:01:59 -0400419 rt->renderTargetPriv().attachStencilAttachment(std::move(stencil));
egdanielec00d942015-09-14 12:56:10 -0700420 }
Robert Phillipsc0192e32017-09-21 12:00:26 -0400421 return SkToBool(rt->renderTargetPriv().getStencilAttachment());
egdanielec00d942015-09-14 12:56:10 -0700422}
423
bungeman6bd52842016-10-27 09:30:08 -0700424sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400425 const GrBackendTexture& tex, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700426{
ericrkf7b8b8a2016-02-24 14:49:51 -0800427 if (this->isAbandoned()) {
428 return nullptr;
429 }
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500430 return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800431}
Greg Danield85f97d2017-03-07 13:37:21 -0500432
Greg Daniela5cb7812017-06-16 09:45:32 -0400433sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
434 return fGpu->makeSemaphore(isOwned);
435}
436
437sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
Greg Daniel17b7c052018-01-09 13:55:33 -0500438 SemaphoreWrapType wrapType,
Greg Daniela5cb7812017-06-16 09:45:32 -0400439 GrWrapOwnership ownership) {
440 ASSERT_SINGLE_OWNER
Greg Daniel17b7c052018-01-09 13:55:33 -0500441 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore,
442 wrapType,
443 ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500444}