blob: df848e8d3cb4f5279aa4b4bf89374cef702a33e2 [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,
Robert Phillips590533f2017-07-11 14:22:35 -040065 const GrMipLevel texels[], int mipLevelCount,
Robert Phillips8e8c7552017-07-10 12:06:05 -040066 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050067 ASSERT_SINGLE_OWNER
68
Robert Phillips7f1b4f82017-11-28 07:38:39 -050069 SkASSERT(mipLevelCount > 0);
Robert Phillips1119dc32017-04-11 12:54:57 -040070
Brian Osman32342f02017-03-04 08:12:46 -050071 if (this->isAbandoned()) {
72 return nullptr;
73 }
Robert Phillips1119dc32017-04-11 12:54:57 -040074
Brian Salomonbdecacf2018-02-02 20:32:49 -050075 GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
76 if (!fCaps->validateSurfaceDesc(desc, mipMapped)) {
Brian Osman32342f02017-03-04 08:12:46 -050077 return nullptr;
78 }
Brian Osman32342f02017-03-04 08:12:46 -050079
Brian Salomon58389b92018-03-07 13:01:25 -050080 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
Robert Phillipse78b7252017-04-06 07:59:41 -040081 if (tex) {
82 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -040083 }
Robert Phillipse78b7252017-04-06 07:59:41 -040084
Robert Phillips8e8c7552017-07-10 12:06:05 -040085 return tex;
Brian Osman32342f02017-03-04 08:12:46 -050086}
87
Robert Phillips45fdae12017-04-17 12:57:27 -040088sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -040089 SkBudgeted budgeted, uint32_t flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -040090 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
91 if (tex && SkBudgeted::kNo == budgeted) {
92 tex->resourcePriv().makeUnbudgeted();
93 }
94
95 return tex;
96}
97
98static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
99 SkColorType colorType;
100 if (!GrPixelConfigToColorType(config, &colorType)) {
101 return false;
102 }
103
104 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
105 return true;
106}
107
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500108sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
109 SkBudgeted budgeted,
Greg Danielfb3abcd2018-02-02 15:48:33 -0500110 SkBackingFit fit,
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500111 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -0400112 ASSERT_SINGLE_OWNER
113
114 if (this->isAbandoned()) {
115 return nullptr;
116 }
117
Robert Phillips45fdae12017-04-17 12:57:27 -0400118 if (!mipLevel.fPixels) {
119 return nullptr;
120 }
121
Brian Salomonbdecacf2018-02-02 20:32:49 -0500122 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400123 return nullptr;
124 }
125
Robert Phillips45fdae12017-04-17 12:57:27 -0400126 GrContext* context = fGpu->getContext();
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500127 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips45fdae12017-04-17 12:57:27 -0400128
Robert Phillips92de6312017-05-23 07:43:48 -0400129 SkImageInfo srcInfo;
Robert Phillips45fdae12017-04-17 12:57:27 -0400130
Robert Phillips92de6312017-05-23 07:43:48 -0400131 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500132 // DDL TODO: remove this use of createInstantiatedProxy and convert it to a testing-only
133 // method.
Brian Salomon58389b92018-03-07 13:01:25 -0500134 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(
135 desc, kTopLeft_GrSurfaceOrigin, fit, budgeted);
Robert Phillipsfe50d962017-06-01 10:22:03 -0400136 if (proxy) {
Brian Salomon366093f2018-02-13 09:25:22 -0500137 // We use an ephemeral surface context to do the write pixels. Here it isn't clear what
138 // color space to tag it with. That's ok because GrSurfaceContext::writePixels doesn't
139 // do any color space conversions. Though, that is likely to change. However, if the
140 // pixel config is sRGB then the passed color space here must have sRGB gamma or
141 // GrSurfaceContext creation fails.
142 sk_sp<SkColorSpace> colorSpace;
143 if (GrPixelConfigIsSRGB(desc.fConfig)) {
144 colorSpace = SkColorSpace::MakeSRGB();
145 }
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500146 sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
Brian Salomon366093f2018-02-13 09:25:22 -0500147 std::move(proxy), std::move(colorSpace));
Robert Phillipsfe50d962017-06-01 10:22:03 -0400148 if (sContext) {
149 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500150 return sk_ref_sp(sContext->asTextureProxy()->priv().peekTexture());
Robert Phillipsfe50d962017-06-01 10:22:03 -0400151 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400152 }
153 }
154 }
155
Brian Salomon58389b92018-03-07 13:01:25 -0500156 return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
Robert Phillips45fdae12017-04-17 12:57:27 -0400157}
158
Robert Phillipse78b7252017-04-06 07:59:41 -0400159sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
160 uint32_t flags) {
161 ASSERT_SINGLE_OWNER
Robert Phillipse78b7252017-04-06 07:59:41 -0400162 if (this->isAbandoned()) {
163 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500164 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400165
Brian Salomonbdecacf2018-02-02 20:32:49 -0500166 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400167 return nullptr;
168 }
169
Greg Daniel21918232017-09-08 14:46:23 -0400170 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
Robert Phillips92de6312017-05-23 07:43:48 -0400171 if (tex) {
172 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400173 }
174
Robert Phillips67d52cf2017-06-05 13:38:13 -0400175 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500176}
177
Robert Phillips67d52cf2017-06-05 13:38:13 -0400178sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
179 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500180 ASSERT_SINGLE_OWNER
181 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500182
Brian Osman32342f02017-03-04 08:12:46 -0500183 if (this->isAbandoned()) {
184 return nullptr;
185 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400186
Brian Salomonbdecacf2018-02-02 20:32:49 -0500187 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400188 return nullptr;
189 }
190
Greg Daniel6b60b6e2017-09-26 16:37:12 -0400191 if (auto tex = this->refScratchTexture(desc, flags)) {
192 return tex;
193 }
194
Greg Daniel29bf84f2017-09-25 12:25:12 -0400195 SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
196
197 // bin by pow2 with a reasonable min
198 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
199 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
200 GrSurfaceDesc* wdesc = copyDesc.writable();
201 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
202 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
203 }
204
205 if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
206 return tex;
207 }
208
209 return fGpu->createTexture(*copyDesc, SkBudgeted::kYes);
Brian Osman32342f02017-03-04 08:12:46 -0500210}
211
Greg Daniel29bf84f2017-09-25 12:25:12 -0400212sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -0400213 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500214 ASSERT_SINGLE_OWNER
215 SkASSERT(!this->isAbandoned());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500216 SkASSERT(fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo));
Brian Osman32342f02017-03-04 08:12:46 -0500217
Brian Salomond17b4a62017-05-23 16:53:47 -0400218 // We could make initial clears work with scratch textures but it is a rare case so we just opt
219 // to fall back to making a new texture.
Greg Daniel29bf84f2017-09-25 12:25:12 -0400220 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
221 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500222
223 GrScratchKey key;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400224 GrTexturePriv::ComputeScratchKey(desc, &key);
Brian Osman32342f02017-03-04 08:12:46 -0500225 uint32_t scratchFlags = 0;
226 if (kNoPendingIO_Flag & flags) {
227 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400228 } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
Brian Osman32342f02017-03-04 08:12:46 -0500229 // If it is not a render target then it will most likely be populated by
230 // writePixels() which will trigger a flush if the texture has pending IO.
231 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
232 }
233 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
Greg Daniel29bf84f2017-09-25 12:25:12 -0400234 GrSurface::WorstCaseSize(desc),
235 scratchFlags);
Brian Osman32342f02017-03-04 08:12:46 -0500236 if (resource) {
237 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400238 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500239 }
240 }
241
Brian Osman32342f02017-03-04 08:12:46 -0500242 return nullptr;
243}
244
Greg Daniel7ef28f32017-04-20 16:41:55 +0000245sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Brian Osman32342f02017-03-04 08:12:46 -0500246 GrWrapOwnership ownership) {
247 ASSERT_SINGLE_OWNER
248 if (this->isAbandoned()) {
249 return nullptr;
250 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400251 return fGpu->wrapBackendTexture(tex, ownership);
Brian Salomond17f6582017-07-19 18:28:58 -0400252}
253
254sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Brian Salomond17f6582017-07-19 18:28:58 -0400255 int sampleCnt,
256 GrWrapOwnership ownership) {
257 ASSERT_SINGLE_OWNER
258 if (this->isAbandoned()) {
259 return nullptr;
260 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400261 return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500262}
263
264sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400265 const GrBackendRenderTarget& backendRT)
Brian Osman32342f02017-03-04 08:12:46 -0500266{
267 ASSERT_SINGLE_OWNER
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400268 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT);
Brian Osman32342f02017-03-04 08:12:46 -0500269}
270
271void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
272 GrGpuResource* resource) {
273 ASSERT_SINGLE_OWNER
274 if (this->isAbandoned() || !resource) {
275 return;
276 }
277 resource->resourcePriv().setUniqueKey(key);
278}
279
Brian Salomond28a79d2017-10-16 13:01:07 -0400280sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
Brian Osman32342f02017-03-04 08:12:46 -0500281 ASSERT_SINGLE_OWNER
Brian Salomond28a79d2017-10-16 13:01:07 -0400282 return this->isAbandoned() ? nullptr
283 : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
Brian Osman32342f02017-03-04 08:12:46 -0500284}
285
Chris Dalton5d2de082017-12-19 10:40:23 -0700286sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType,
287 size_t size,
288 const void* data,
289 const GrUniqueKey& key) {
290 if (auto buffer = this->findByUniqueKey<GrBuffer>(key)) {
291 return buffer;
292 }
293 if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, 0,
294 data)) {
295 // We shouldn't bin and/or cachestatic buffers.
296 SkASSERT(buffer->sizeInBytes() == size);
297 SkASSERT(!buffer->resourcePriv().getScratchKey().isValid());
298 SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly());
299 buffer->resourcePriv().setUniqueKey(key);
300 return sk_sp<const GrBuffer>(buffer);
301 }
302 return nullptr;
303}
304
Brian Salomond28a79d2017-10-16 13:01:07 -0400305sk_sp<const GrBuffer> 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 Salomon7f56d3d2017-10-09 13:02:49 -0400313 sk_sp<GrBuffer> buffer(this->createBuffer(bufferSize, kIndex_GrBufferType,
314 kStatic_GrAccessPattern, kNoPendingIO_Flag));
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 Salomond28a79d2017-10-16 13:01:07 -0400344sk_sp<const GrBuffer> 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 Salomon34169692017-08-28 15:32:01 -0400350int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
351
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
cdaltone2e71c22016-04-07 18:13:29 -0700361GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700362 GrAccessPattern accessPattern, uint32_t flags,
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 }
csmartdalton485a1202016-07-13 10:16:32 -0700370 if (!(flags & kRequireGpuMemory_Flag) &&
371 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
372 GrBufferTypeIsVertexOrIndex(intendedType) &&
373 kDynamic_GrAccessPattern == accessPattern) {
374 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
375 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700376
cdaltond37fe762016-04-21 07:41:50 -0700377 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400378 static const size_t MIN_SIZE = 1 << 12;
379 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700380
cdaltond37fe762016-04-21 07:41:50 -0700381 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700382 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700383 uint32_t scratchFlags = 0;
384 if (flags & kNoPendingIO_Flag) {
385 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
386 } else {
387 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
388 }
389 GrBuffer* buffer = static_cast<GrBuffer*>(
390 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
391 if (!buffer) {
392 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
393 if (!buffer) {
394 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700395 }
396 }
cdaltond37fe762016-04-21 07:41:50 -0700397 if (data) {
398 buffer->updateData(data, size);
399 }
csmartdalton485a1202016-07-13 10:16:32 -0700400 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700401 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800402}
403
Robert Phillipsc0192e32017-09-21 12:00:26 -0400404bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
egdanielec00d942015-09-14 12:56:10 -0700405 SkASSERT(rt);
406 if (rt->renderTargetPriv().getStencilAttachment()) {
Robert Phillipsc0192e32017-09-21 12:00:26 -0400407 return true;
egdanielec00d942015-09-14 12:56:10 -0700408 }
409
410 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
411 GrUniqueKey sbKey;
412
413 int width = rt->width();
414 int height = rt->height();
415#if 0
416 if (this->caps()->oversizedStencilSupport()) {
417 width = SkNextPow2(width);
418 height = SkNextPow2(height);
419 }
420#endif
Robert Phillipscb2e2352017-08-30 16:44:40 -0400421 SkDEBUGCODE(bool newStencil = false;)
egdanielec00d942015-09-14 12:56:10 -0700422 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
423 rt->numStencilSamples(), &sbKey);
Brian Salomond28a79d2017-10-16 13:01:07 -0400424 auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey);
egdanielec00d942015-09-14 12:56:10 -0700425 if (!stencil) {
426 // Need to try and create a new stencil
Brian Salomond28a79d2017-10-16 13:01:07 -0400427 stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
egdanielec00d942015-09-14 12:56:10 -0700428 if (stencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400429 this->assignUniqueKeyToResource(sbKey, stencil.get());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400430 SkDEBUGCODE(newStencil = true;)
egdanielec00d942015-09-14 12:56:10 -0700431 }
432 }
Brian Salomond28a79d2017-10-16 13:01:07 -0400433 if (rt->renderTargetPriv().attachStencilAttachment(std::move(stencil))) {
Robert Phillips95214472017-08-08 18:00:03 -0400434#ifdef SK_DEBUG
435 // Fill the SB with an inappropriate value. opLists that use the
436 // SB should clear it properly.
Robert Phillipscb2e2352017-08-30 16:44:40 -0400437 if (newStencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400438 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400439 this->gpu()->clearStencil(rt, 0xFFFF);
Brian Salomond28a79d2017-10-16 13:01:07 -0400440 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400441 }
Robert Phillips95214472017-08-08 18:00:03 -0400442#endif
egdanielec00d942015-09-14 12:56:10 -0700443 }
444 }
Robert Phillipsc0192e32017-09-21 12:00:26 -0400445 return SkToBool(rt->renderTargetPriv().getStencilAttachment());
egdanielec00d942015-09-14 12:56:10 -0700446}
447
bungeman6bd52842016-10-27 09:30:08 -0700448sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400449 const GrBackendTexture& tex, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700450{
ericrkf7b8b8a2016-02-24 14:49:51 -0800451 if (this->isAbandoned()) {
452 return nullptr;
453 }
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500454 return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800455}
Greg Danield85f97d2017-03-07 13:37:21 -0500456
Greg Daniela5cb7812017-06-16 09:45:32 -0400457sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
458 return fGpu->makeSemaphore(isOwned);
459}
460
461sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
Greg Daniel17b7c052018-01-09 13:55:33 -0500462 SemaphoreWrapType wrapType,
Greg Daniela5cb7812017-06-16 09:45:32 -0400463 GrWrapOwnership ownership) {
464 ASSERT_SINGLE_OWNER
Greg Daniel17b7c052018-01-09 13:55:33 -0500465 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore,
466 wrapType,
467 ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500468}
469
470void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
471 semaphore->resetGpu(fGpu);
472}
473
474void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
475 semaphore->resetGpu(nullptr);
476}