blob: 6e821db3a27be7181c8abeb56eb0cecd38951b20 [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"
9
Greg Daniela5cb7812017-06-16 09:45:32 -040010#include "GrBackendSemaphore.h"
cdalton397536c2016-03-25 12:15:03 -070011#include "GrBuffer.h"
robertphillips5fa7f302016-07-21 09:21:04 -070012#include "GrCaps.h"
Robert Phillips26c90e02017-03-14 14:39:29 -040013#include "GrContext.h"
Robert Phillipse78b7252017-04-06 07:59:41 -040014#include "GrContextPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070015#include "GrGpu.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"
25#include "../private/GrSingleOwner.h"
Robert Phillips45fdae12017-04-17 12:57:27 -040026#include "SkGr.h"
halcanary4dbbd042016-06-07 17:21:10 -070027#include "SkMathPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070028
29GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
30
Robert Phillips1bfece82017-06-01 13:56:52 -040031const uint32_t GrResourceProvider::kMinScratchTextureSize = 16;
Brian Osman32342f02017-03-04 08:12:46 -050032
Robert Phillipsa3f70262018-02-08 10:59:38 -050033#ifdef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION
34static const bool kDefaultExplicitlyAllocateGPUResources = false;
35#else
36static const bool kDefaultExplicitlyAllocateGPUResources = true;
37#endif
38
Brian Osman32342f02017-03-04 08:12:46 -050039#define ASSERT_SINGLE_OWNER \
40 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
41
Robert Phillips4150eea2018-02-07 17:08:21 -050042GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner,
Robert Phillipsa3f70262018-02-08 10:59:38 -050043 GrContextOptions::Enable explicitlyAllocateGPUResources)
Brian Osman32342f02017-03-04 08:12:46 -050044 : fCache(cache)
45 , fGpu(gpu)
46#ifdef SK_DEBUG
47 , fSingleOwner(owner)
48#endif
Robert Phillips4150eea2018-02-07 17:08:21 -050049{
Robert Phillipsa3f70262018-02-08 10:59:38 -050050 if (GrContextOptions::Enable::kNo == explicitlyAllocateGPUResources) {
51 fExplicitlyAllocateGPUResources = false;
52 } else if (GrContextOptions::Enable::kYes == explicitlyAllocateGPUResources) {
53 fExplicitlyAllocateGPUResources = true;
54 } else {
55 fExplicitlyAllocateGPUResources = kDefaultExplicitlyAllocateGPUResources;
56 }
57
Robert Phillips26c90e02017-03-14 14:39:29 -040058 fCaps = sk_ref_sp(fGpu->caps());
59
bsalomoned0bcad2015-05-04 10:36:42 -070060 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
61 fQuadIndexBufferKey = gQuadIndexBufferKey;
62}
63
Robert Phillips8e8c7552017-07-10 12:06:05 -040064sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Brian Osman2b23c4b2018-06-01 12:25:08 -040065 const GrMipLevel texels[], int mipLevelCount) {
Brian Osman32342f02017-03-04 08:12:46 -050066 ASSERT_SINGLE_OWNER
67
Robert Phillips7f1b4f82017-11-28 07:38:39 -050068 SkASSERT(mipLevelCount > 0);
Robert Phillips1119dc32017-04-11 12:54:57 -040069
Brian Osman32342f02017-03-04 08:12:46 -050070 if (this->isAbandoned()) {
71 return nullptr;
72 }
Robert Phillips1119dc32017-04-11 12:54:57 -040073
Brian Salomonbdecacf2018-02-02 20:32:49 -050074 GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
75 if (!fCaps->validateSurfaceDesc(desc, mipMapped)) {
Brian Osman32342f02017-03-04 08:12:46 -050076 return nullptr;
77 }
Brian Osman32342f02017-03-04 08:12:46 -050078
Brian Osman2b23c4b2018-06-01 12:25:08 -040079 return fGpu->createTexture(desc, budgeted, texels, mipLevelCount);
Brian Osman32342f02017-03-04 08:12:46 -050080}
81
Robert Phillips45fdae12017-04-17 12:57:27 -040082sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
Chris Daltond004e0b2018-09-27 09:28:03 -060083 SkBudgeted budgeted, Flags flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -040084 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
85 if (tex && SkBudgeted::kNo == budgeted) {
86 tex->resourcePriv().makeUnbudgeted();
87 }
88
89 return tex;
90}
91
Robert Phillips1afd4cd2018-01-08 13:40:32 -050092sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
93 SkBudgeted budgeted,
Greg Danielfb3abcd2018-02-02 15:48:33 -050094 SkBackingFit fit,
Chris Daltond004e0b2018-09-27 09:28:03 -060095 const GrMipLevel& mipLevel,
96 Flags flags) {
Robert Phillips774831a2017-04-20 10:19:33 -040097 ASSERT_SINGLE_OWNER
98
99 if (this->isAbandoned()) {
100 return nullptr;
101 }
102
Robert Phillips45fdae12017-04-17 12:57:27 -0400103 if (!mipLevel.fPixels) {
104 return nullptr;
105 }
106
Brian Salomonbdecacf2018-02-02 20:32:49 -0500107 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400108 return nullptr;
109 }
110
Robert Phillips45fdae12017-04-17 12:57:27 -0400111 GrContext* context = fGpu->getContext();
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500112 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips45fdae12017-04-17 12:57:27 -0400113
Brian Salomon1fcac052018-05-09 16:33:09 -0400114 SkColorType colorType;
115 if (GrPixelConfigToColorType(desc.fConfig, &colorType)) {
Chris Daltond004e0b2018-09-27 09:28:03 -0600116 sk_sp<GrTexture> tex = (SkBackingFit::kApprox == fit)
117 ? this->createApproxTexture(desc, flags)
118 : this->createTexture(desc, budgeted, flags);
119 if (!tex) {
120 return nullptr;
121 }
122
123 sk_sp<GrTextureProxy> proxy = proxyProvider->createWrapped(std::move(tex),
124 kTopLeft_GrSurfaceOrigin);
Brian Salomon1fcac052018-05-09 16:33:09 -0400125 if (!proxy) {
126 return nullptr;
Robert Phillips45fdae12017-04-17 12:57:27 -0400127 }
Brian Salomon1fcac052018-05-09 16:33:09 -0400128 auto srcInfo = SkImageInfo::Make(desc.fWidth, desc.fHeight, colorType,
Brian Osman9363ac42018-06-01 16:10:53 -0400129 kUnknown_SkAlphaType);
Brian Salomon1fcac052018-05-09 16:33:09 -0400130 sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
Brian Osman9363ac42018-06-01 16:10:53 -0400131 std::move(proxy));
Brian Salomon1fcac052018-05-09 16:33:09 -0400132 if (!sContext) {
133 return nullptr;
134 }
135 SkAssertResult(sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0));
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400136 return sk_ref_sp(sContext->asTextureProxy()->peekTexture());
Brian Salomon1fcac052018-05-09 16:33:09 -0400137 } else {
138 return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
Robert Phillips45fdae12017-04-17 12:57:27 -0400139 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400140}
141
Robert Phillipse78b7252017-04-06 07:59:41 -0400142sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Chris Daltond004e0b2018-09-27 09:28:03 -0600143 Flags flags) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400144 ASSERT_SINGLE_OWNER
Robert Phillipse78b7252017-04-06 07:59:41 -0400145 if (this->isAbandoned()) {
146 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500147 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400148
Brian Salomonbdecacf2018-02-02 20:32:49 -0500149 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400150 return nullptr;
151 }
152
Greg Daniel21918232017-09-08 14:46:23 -0400153 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
Robert Phillips92de6312017-05-23 07:43:48 -0400154 if (tex) {
155 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400156 }
157
Robert Phillips67d52cf2017-06-05 13:38:13 -0400158 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500159}
160
Robert Phillips67d52cf2017-06-05 13:38:13 -0400161sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
Chris Daltond004e0b2018-09-27 09:28:03 -0600162 Flags flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500163 ASSERT_SINGLE_OWNER
Chris Daltond004e0b2018-09-27 09:28:03 -0600164 SkASSERT(Flags::kNone == flags || Flags::kNoPendingIO == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500165
Brian Osman32342f02017-03-04 08:12:46 -0500166 if (this->isAbandoned()) {
167 return nullptr;
168 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400169
Brian Salomonbdecacf2018-02-02 20:32:49 -0500170 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400171 return nullptr;
172 }
173
Greg Daniel6b60b6e2017-09-26 16:37:12 -0400174 if (auto tex = this->refScratchTexture(desc, flags)) {
175 return tex;
176 }
177
Greg Daniel29bf84f2017-09-25 12:25:12 -0400178 SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
179
180 // bin by pow2 with a reasonable min
181 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
182 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
183 GrSurfaceDesc* wdesc = copyDesc.writable();
184 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
185 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
186 }
187
188 if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
189 return tex;
190 }
191
192 return fGpu->createTexture(*copyDesc, SkBudgeted::kYes);
Brian Osman32342f02017-03-04 08:12:46 -0500193}
194
Chris Daltond004e0b2018-09-27 09:28:03 -0600195sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc, Flags flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500196 ASSERT_SINGLE_OWNER
197 SkASSERT(!this->isAbandoned());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500198 SkASSERT(fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo));
Brian Osman32342f02017-03-04 08:12:46 -0500199
Brian Salomond17b4a62017-05-23 16:53:47 -0400200 // We could make initial clears work with scratch textures but it is a rare case so we just opt
201 // to fall back to making a new texture.
Greg Daniel29bf84f2017-09-25 12:25:12 -0400202 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
203 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500204
205 GrScratchKey key;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400206 GrTexturePriv::ComputeScratchKey(desc, &key);
Chris Daltond004e0b2018-09-27 09:28:03 -0600207 auto scratchFlags = GrResourceCache::ScratchFlags::kNone;
208 if (Flags::kNoPendingIO & flags) {
209 scratchFlags |= GrResourceCache::ScratchFlags::kRequireNoPendingIO;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400210 } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
Brian Osman32342f02017-03-04 08:12:46 -0500211 // If it is not a render target then it will most likely be populated by
212 // writePixels() which will trigger a flush if the texture has pending IO.
Chris Daltond004e0b2018-09-27 09:28:03 -0600213 scratchFlags |= GrResourceCache::ScratchFlags::kPreferNoPendingIO;
Brian Osman32342f02017-03-04 08:12:46 -0500214 }
215 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
Greg Daniel29bf84f2017-09-25 12:25:12 -0400216 GrSurface::WorstCaseSize(desc),
217 scratchFlags);
Brian Osman32342f02017-03-04 08:12:46 -0500218 if (resource) {
219 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400220 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500221 }
222 }
223
Brian Osman32342f02017-03-04 08:12:46 -0500224 return nullptr;
225}
226
Greg Daniel7ef28f32017-04-20 16:41:55 +0000227sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Greg Daniel2268ad22018-11-15 09:27:38 -0500228 GrWrapOwnership ownership,
Brian Salomonc67c31c2018-12-06 10:00:03 -0500229 GrIOType ioType,
Greg Daniel2268ad22018-11-15 09:27:38 -0500230 bool purgeImmediately) {
Brian Osman32342f02017-03-04 08:12:46 -0500231 ASSERT_SINGLE_OWNER
232 if (this->isAbandoned()) {
233 return nullptr;
234 }
Brian Salomonc67c31c2018-12-06 10:00:03 -0500235 return fGpu->wrapBackendTexture(tex, ownership, ioType, purgeImmediately);
Brian Salomond17f6582017-07-19 18:28:58 -0400236}
237
238sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Brian Salomond17f6582017-07-19 18:28:58 -0400239 int sampleCnt,
240 GrWrapOwnership ownership) {
241 ASSERT_SINGLE_OWNER
242 if (this->isAbandoned()) {
243 return nullptr;
244 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400245 return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500246}
247
248sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400249 const GrBackendRenderTarget& backendRT)
Brian Osman32342f02017-03-04 08:12:46 -0500250{
251 ASSERT_SINGLE_OWNER
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400252 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT);
Brian Osman32342f02017-03-04 08:12:46 -0500253}
254
Greg Danielb46add82019-01-02 14:51:29 -0500255sk_sp<GrRenderTarget> GrResourceProvider::wrapVulkanSecondaryCBAsRenderTarget(
256 const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo) {
257 ASSERT_SINGLE_OWNER
258 return this->isAbandoned() ? nullptr : fGpu->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
259 vkInfo);
260
261}
262
Brian Osman32342f02017-03-04 08:12:46 -0500263void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
264 GrGpuResource* resource) {
265 ASSERT_SINGLE_OWNER
266 if (this->isAbandoned() || !resource) {
267 return;
268 }
269 resource->resourcePriv().setUniqueKey(key);
270}
271
Brian Salomond28a79d2017-10-16 13:01:07 -0400272sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
Brian Osman32342f02017-03-04 08:12:46 -0500273 ASSERT_SINGLE_OWNER
Brian Salomond28a79d2017-10-16 13:01:07 -0400274 return this->isAbandoned() ? nullptr
275 : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
Brian Osman32342f02017-03-04 08:12:46 -0500276}
277
Chris Dalton5d2de082017-12-19 10:40:23 -0700278sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType,
279 size_t size,
280 const void* data,
281 const GrUniqueKey& key) {
282 if (auto buffer = this->findByUniqueKey<GrBuffer>(key)) {
Kevin Lubickf7621cb2018-04-16 15:51:44 -0400283 return std::move(buffer);
Chris Dalton5d2de082017-12-19 10:40:23 -0700284 }
Chris Daltond004e0b2018-09-27 09:28:03 -0600285 if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, Flags::kNone,
Chris Dalton5d2de082017-12-19 10:40:23 -0700286 data)) {
Chris Dalton133944a2018-11-16 23:30:29 -0500287 // We shouldn't bin and/or cache static buffers.
Chris Dalton5d2de082017-12-19 10:40:23 -0700288 SkASSERT(buffer->sizeInBytes() == size);
289 SkASSERT(!buffer->resourcePriv().getScratchKey().isValid());
290 SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly());
291 buffer->resourcePriv().setUniqueKey(key);
292 return sk_sp<const GrBuffer>(buffer);
293 }
294 return nullptr;
295}
296
Brian Salomond28a79d2017-10-16 13:01:07 -0400297sk_sp<const GrBuffer> GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
298 int patternSize,
299 int reps,
300 int vertCount,
301 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700302 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
303
Brian Salomon09d994e2016-12-21 11:14:46 -0500304 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400305 sk_sp<GrBuffer> buffer(this->createBuffer(bufferSize, kIndex_GrBufferType,
Chris Daltond004e0b2018-09-27 09:28:03 -0600306 kStatic_GrAccessPattern, Flags::kNoPendingIO));
bsalomoned0bcad2015-05-04 10:36:42 -0700307 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700308 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700309 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400310 uint16_t* data = (uint16_t*) buffer->map();
311 SkAutoTArray<uint16_t> temp;
312 if (!data) {
313 temp.reset(reps * patternSize);
314 data = temp.get();
315 }
bsalomoned0bcad2015-05-04 10:36:42 -0700316 for (int i = 0; i < reps; ++i) {
317 int baseIdx = i * patternSize;
318 uint16_t baseVert = (uint16_t)(i * vertCount);
319 for (int j = 0; j < patternSize; ++j) {
320 data[baseIdx+j] = baseVert + pattern[j];
321 }
322 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400323 if (temp.get()) {
324 if (!buffer->updateData(data, bufferSize)) {
325 return nullptr;
326 }
327 } else {
328 buffer->unmap();
bsalomoned0bcad2015-05-04 10:36:42 -0700329 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400330 this->assignUniqueKeyToResource(key, buffer.get());
Brian Salomond28a79d2017-10-16 13:01:07 -0400331 return std::move(buffer);
bsalomoned0bcad2015-05-04 10:36:42 -0700332}
333
Brian Salomon34169692017-08-28 15:32:01 -0400334static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
335
Brian Salomond28a79d2017-10-16 13:01:07 -0400336sk_sp<const GrBuffer> GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700337 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
Brian Salomon57caa662017-10-18 12:21:05 +0000338 static const uint16_t kPattern[] = { 0, 1, 2, 2, 1, 3 };
Chris Daltonff926502017-05-03 14:36:54 -0400339 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700340}
341
Brian Salomon763abf02018-05-01 18:49:38 +0000342int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
Brian Salomon34169692017-08-28 15:32:01 -0400343
Robert Phillips67d52cf2017-06-05 13:38:13 -0400344sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400345 if (this->isAbandoned()) {
346 return nullptr;
347 }
348
bsalomon706f08f2015-05-22 07:35:58 -0700349 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700350 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700351}
352
cdaltone2e71c22016-04-07 18:13:29 -0700353GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
Chris Daltond004e0b2018-09-27 09:28:03 -0600354 GrAccessPattern accessPattern, Flags flags,
cdalton1bf3e712016-04-19 10:00:02 -0700355 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700356 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700357 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700358 }
cdaltond37fe762016-04-21 07:41:50 -0700359 if (kDynamic_GrAccessPattern != accessPattern) {
360 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
361 }
Chris Daltond004e0b2018-09-27 09:28:03 -0600362 if (!(flags & Flags::kRequireGpuMemory) &&
csmartdalton485a1202016-07-13 10:16:32 -0700363 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
364 GrBufferTypeIsVertexOrIndex(intendedType) &&
365 kDynamic_GrAccessPattern == accessPattern) {
366 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
367 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700368
cdaltond37fe762016-04-21 07:41:50 -0700369 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400370 static const size_t MIN_SIZE = 1 << 12;
371 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700372
cdaltond37fe762016-04-21 07:41:50 -0700373 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700374 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
Chris Daltond004e0b2018-09-27 09:28:03 -0600375 auto scratchFlags = GrResourceCache::ScratchFlags::kNone;
376 if (flags & Flags::kNoPendingIO) {
377 scratchFlags = GrResourceCache::ScratchFlags::kRequireNoPendingIO;
cdaltond37fe762016-04-21 07:41:50 -0700378 } else {
Chris Daltond004e0b2018-09-27 09:28:03 -0600379 scratchFlags = GrResourceCache::ScratchFlags::kPreferNoPendingIO;
cdaltond37fe762016-04-21 07:41:50 -0700380 }
381 GrBuffer* buffer = static_cast<GrBuffer*>(
382 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
383 if (!buffer) {
384 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
385 if (!buffer) {
386 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700387 }
388 }
cdaltond37fe762016-04-21 07:41:50 -0700389 if (data) {
390 buffer->updateData(data, size);
391 }
csmartdalton485a1202016-07-13 10:16:32 -0700392 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700393 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800394}
395
Robert Phillipsc0192e32017-09-21 12:00:26 -0400396bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
egdanielec00d942015-09-14 12:56:10 -0700397 SkASSERT(rt);
398 if (rt->renderTargetPriv().getStencilAttachment()) {
Robert Phillipsc0192e32017-09-21 12:00:26 -0400399 return true;
egdanielec00d942015-09-14 12:56:10 -0700400 }
401
402 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
403 GrUniqueKey sbKey;
404
405 int width = rt->width();
406 int height = rt->height();
407#if 0
408 if (this->caps()->oversizedStencilSupport()) {
409 width = SkNextPow2(width);
410 height = SkNextPow2(height);
411 }
412#endif
egdanielec00d942015-09-14 12:56:10 -0700413 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
414 rt->numStencilSamples(), &sbKey);
Brian Salomond28a79d2017-10-16 13:01:07 -0400415 auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey);
egdanielec00d942015-09-14 12:56:10 -0700416 if (!stencil) {
417 // Need to try and create a new stencil
Brian Salomond28a79d2017-10-16 13:01:07 -0400418 stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
Robert Phillips01a91282018-07-26 08:03:04 -0400419 if (!stencil) {
420 return false;
egdanielec00d942015-09-14 12:56:10 -0700421 }
Robert Phillips01a91282018-07-26 08:03:04 -0400422 this->assignUniqueKeyToResource(sbKey, stencil.get());
egdanielec00d942015-09-14 12:56:10 -0700423 }
Greg Danielcfa39352018-10-05 12:01:59 -0400424 rt->renderTargetPriv().attachStencilAttachment(std::move(stencil));
egdanielec00d942015-09-14 12:56:10 -0700425 }
Robert Phillipsc0192e32017-09-21 12:00:26 -0400426 return SkToBool(rt->renderTargetPriv().getStencilAttachment());
egdanielec00d942015-09-14 12:56:10 -0700427}
428
bungeman6bd52842016-10-27 09:30:08 -0700429sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400430 const GrBackendTexture& tex, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700431{
ericrkf7b8b8a2016-02-24 14:49:51 -0800432 if (this->isAbandoned()) {
433 return nullptr;
434 }
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500435 return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800436}
Greg Danield85f97d2017-03-07 13:37:21 -0500437
Greg Daniela5cb7812017-06-16 09:45:32 -0400438sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
439 return fGpu->makeSemaphore(isOwned);
440}
441
442sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
Greg Daniel17b7c052018-01-09 13:55:33 -0500443 SemaphoreWrapType wrapType,
Greg Daniela5cb7812017-06-16 09:45:32 -0400444 GrWrapOwnership ownership) {
445 ASSERT_SINGLE_OWNER
Greg Daniel17b7c052018-01-09 13:55:33 -0500446 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore,
447 wrapType,
448 ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500449}