blob: ea699fbe102b2b8059a2978e673a3aa835aaf20c [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
cdalton397536c2016-03-25 12:15:03 -070010#include "GrBuffer.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"
Robert Phillips67d52cf2017-06-05 13:38:13 -040015#include "GrPath.h"
kkinnunencabe20c2015-06-01 01:37:26 -070016#include "GrPathRendering.h"
egdanielec00d942015-09-14 12:56:10 -070017#include "GrRenderTarget.h"
18#include "GrRenderTargetPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070019#include "GrResourceCache.h"
20#include "GrResourceKey.h"
Greg Danield85f97d2017-03-07 13:37:21 -050021#include "GrSemaphore.h"
egdanielec00d942015-09-14 12:56:10 -070022#include "GrStencilAttachment.h"
Robert Phillipsb66b42f2017-03-14 08:53:02 -040023#include "GrSurfaceProxyPriv.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
33#define ASSERT_SINGLE_OWNER \
34 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
35
joshualitt6d0872d2016-01-11 08:27:48 -080036GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner)
Brian Osman32342f02017-03-04 08:12:46 -050037 : fCache(cache)
38 , fGpu(gpu)
39#ifdef SK_DEBUG
40 , fSingleOwner(owner)
41#endif
42 {
Robert Phillips26c90e02017-03-14 14:39:29 -040043 fCaps = sk_ref_sp(fGpu->caps());
44
bsalomoned0bcad2015-05-04 10:36:42 -070045 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
46 fQuadIndexBufferKey = gQuadIndexBufferKey;
47}
48
Robert Phillipsf7a72612017-03-31 10:03:45 -040049bool GrResourceProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
Robert Phillipsb66b42f2017-03-14 08:53:02 -040050 return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
51}
Brian Osman32342f02017-03-04 08:12:46 -050052
Brian Salomond34edf32017-05-19 15:45:48 -040053bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount = 0) {
54 if (desc.fWidth <= 0 || desc.fHeight <= 0) {
55 return false;
56 }
57 if (!caps.isConfigTexturable(desc.fConfig)) {
58 return false;
59 }
60 if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
61 if (!caps.isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
62 return false;
63 }
64 } else {
65 if (desc.fSampleCnt) {
66 return false;
67 }
68 }
Brian Osman48c99192017-06-02 08:45:06 -040069 if (levelCount > 1 && (GrPixelConfigIsSint(desc.fConfig) || !caps.mipMapSupport())) {
Brian Salomond34edf32017-05-19 15:45:48 -040070 return false;
71 }
72 return true;
73}
74
Robert Phillipse78b7252017-04-06 07:59:41 -040075// MDB TODO: this should probably be a factory on GrSurfaceProxy
76sk_sp<GrTextureProxy> GrResourceProvider::createMipMappedTexture(
77 const GrSurfaceDesc& desc,
78 SkBudgeted budgeted,
79 const GrMipLevel* texels,
80 int mipLevelCount,
Robert Phillipsa4c41b32017-03-15 13:02:45 -040081 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050082 ASSERT_SINGLE_OWNER
83
Robert Phillips1119dc32017-04-11 12:54:57 -040084 if (!mipLevelCount) {
85 if (texels) {
86 return nullptr;
87 }
88 return GrSurfaceProxy::MakeDeferred(this, desc, budgeted, nullptr, 0);
Robert Phillips45fdae12017-04-17 12:57:27 -040089 } else if (1 == mipLevelCount) {
90 if (!texels) {
91 return nullptr;
92 }
93 return this->createTextureProxy(desc, budgeted, texels[0]);
Robert Phillips1119dc32017-04-11 12:54:57 -040094 }
95
Brian Osman32342f02017-03-04 08:12:46 -050096 if (this->isAbandoned()) {
97 return nullptr;
98 }
Robert Phillips1119dc32017-04-11 12:54:57 -040099
Brian Salomond34edf32017-05-19 15:45:48 -0400100 if (!validate_desc(desc, *fCaps, mipLevelCount)) {
Brian Osman32342f02017-03-04 08:12:46 -0500101 return nullptr;
102 }
Brian Osman32342f02017-03-04 08:12:46 -0500103
104 SkTArray<GrMipLevel> texelsShallowCopy(mipLevelCount);
105 for (int i = 0; i < mipLevelCount; ++i) {
Robert Phillips45fdae12017-04-17 12:57:27 -0400106 if (!texels[i].fPixels) {
107 return nullptr;
108 }
109
Brian Osman32342f02017-03-04 08:12:46 -0500110 texelsShallowCopy.push_back(texels[i]);
111 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400112 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texelsShallowCopy));
113 if (tex) {
114 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -0400115 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400116
117 return GrSurfaceProxy::MakeWrapped(std::move(tex));
Brian Osman32342f02017-03-04 08:12:46 -0500118}
119
Robert Phillips45fdae12017-04-17 12:57:27 -0400120sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
121 SkBudgeted budgeted, uint32_t flags) {
122
123 flags |= kExact_Flag | kNoCreate_Flag;
124 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
125 if (tex && SkBudgeted::kNo == budgeted) {
126 tex->resourcePriv().makeUnbudgeted();
127 }
128
129 return tex;
130}
131
132static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
133 SkColorType colorType;
134 if (!GrPixelConfigToColorType(config, &colorType)) {
135 return false;
136 }
137
138 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
139 return true;
140}
141
142sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
143 SkBudgeted budgeted,
144 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -0400145 ASSERT_SINGLE_OWNER
146
147 if (this->isAbandoned()) {
148 return nullptr;
149 }
150
Robert Phillips45fdae12017-04-17 12:57:27 -0400151 if (!mipLevel.fPixels) {
152 return nullptr;
153 }
154
Brian Salomond34edf32017-05-19 15:45:48 -0400155 if (!validate_desc(desc, *fCaps)) {
156 return nullptr;
157 }
158
Robert Phillips45fdae12017-04-17 12:57:27 -0400159 GrContext* context = fGpu->getContext();
160
Robert Phillips92de6312017-05-23 07:43:48 -0400161 SkImageInfo srcInfo;
Robert Phillips45fdae12017-04-17 12:57:27 -0400162
Robert Phillips92de6312017-05-23 07:43:48 -0400163 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
164 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
Robert Phillipsfe50d962017-06-01 10:22:03 -0400165 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex));
166 if (proxy) {
167 sk_sp<GrSurfaceContext> sContext =
168 context->contextPriv().makeWrappedSurfaceContext(std::move(proxy), nullptr);
169 if (sContext) {
170 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
171 return sContext->asTextureProxyRef();
172 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400173 }
174 }
175 }
176
177 SkTArray<GrMipLevel> texels(1);
178 texels.push_back(mipLevel);
179
180 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels));
181 return GrSurfaceProxy::MakeWrapped(std::move(tex));
182}
183
184
Robert Phillipse78b7252017-04-06 07:59:41 -0400185sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
186 uint32_t flags) {
187 ASSERT_SINGLE_OWNER
188
189 if (this->isAbandoned()) {
190 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500191 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400192
Brian Salomond34edf32017-05-19 15:45:48 -0400193 if (!validate_desc(desc, *fCaps)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400194 return nullptr;
195 }
196
Robert Phillips92de6312017-05-23 07:43:48 -0400197 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
198 if (tex) {
199 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400200 }
201
Robert Phillips67d52cf2017-06-05 13:38:13 -0400202 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500203}
204
Robert Phillips67d52cf2017-06-05 13:38:13 -0400205sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
206 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500207 ASSERT_SINGLE_OWNER
208 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500209
Brian Osman32342f02017-03-04 08:12:46 -0500210 if (this->isAbandoned()) {
211 return nullptr;
212 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400213
Brian Salomond34edf32017-05-19 15:45:48 -0400214 if (!validate_desc(desc, *fCaps)) {
215 return nullptr;
216 }
217
Robert Phillips1119dc32017-04-11 12:54:57 -0400218 return this->refScratchTexture(desc, flags);
Brian Osman32342f02017-03-04 08:12:46 -0500219}
220
Robert Phillips67d52cf2017-06-05 13:38:13 -0400221sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& inDesc,
222 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500223 ASSERT_SINGLE_OWNER
224 SkASSERT(!this->isAbandoned());
Brian Salomond34edf32017-05-19 15:45:48 -0400225 SkASSERT(validate_desc(inDesc, *fCaps));
Brian Osman32342f02017-03-04 08:12:46 -0500226
227 SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
228
Brian Salomond17b4a62017-05-23 16:53:47 -0400229 // We could make initial clears work with scratch textures but it is a rare case so we just opt
230 // to fall back to making a new texture.
231 if (!SkToBool(inDesc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
232 (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500233 if (!(kExact_Flag & flags)) {
234 // bin by pow2 with a reasonable min
235 GrSurfaceDesc* wdesc = desc.writable();
236 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fWidth));
237 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fHeight));
238 }
239
240 GrScratchKey key;
241 GrTexturePriv::ComputeScratchKey(*desc, &key);
242 uint32_t scratchFlags = 0;
243 if (kNoPendingIO_Flag & flags) {
244 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
245 } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
246 // If it is not a render target then it will most likely be populated by
247 // writePixels() which will trigger a flush if the texture has pending IO.
248 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
249 }
250 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
251 GrSurface::WorstCaseSize(*desc),
252 scratchFlags);
253 if (resource) {
254 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400255 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500256 }
257 }
258
259 if (!(kNoCreate_Flag & flags)) {
260 return fGpu->createTexture(*desc, SkBudgeted::kYes);
261 }
262
263 return nullptr;
264}
265
Greg Daniel7ef28f32017-04-20 16:41:55 +0000266sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
267 GrSurfaceOrigin origin,
268 GrBackendTextureFlags flags,
269 int sampleCnt,
Brian Osman32342f02017-03-04 08:12:46 -0500270 GrWrapOwnership ownership) {
271 ASSERT_SINGLE_OWNER
272 if (this->isAbandoned()) {
273 return nullptr;
274 }
Greg Daniel7ef28f32017-04-20 16:41:55 +0000275 return fGpu->wrapBackendTexture(tex, origin, flags, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500276}
277
278sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Greg Danielbcf612b2017-05-01 13:50:58 +0000279 const GrBackendRenderTarget& backendRT, GrSurfaceOrigin origin)
Brian Osman32342f02017-03-04 08:12:46 -0500280{
281 ASSERT_SINGLE_OWNER
Greg Danielbcf612b2017-05-01 13:50:58 +0000282 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT, origin);
Brian Osman32342f02017-03-04 08:12:46 -0500283}
284
285void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
286 GrGpuResource* resource) {
287 ASSERT_SINGLE_OWNER
288 if (this->isAbandoned() || !resource) {
289 return;
290 }
291 resource->resourcePriv().setUniqueKey(key);
292}
293
294GrGpuResource* GrResourceProvider::findAndRefResourceByUniqueKey(const GrUniqueKey& key) {
295 ASSERT_SINGLE_OWNER
296 return this->isAbandoned() ? nullptr : fCache->findAndRefUniqueResource(key);
297}
298
299GrTexture* GrResourceProvider::findAndRefTextureByUniqueKey(const GrUniqueKey& key) {
300 ASSERT_SINGLE_OWNER
301 GrGpuResource* resource = this->findAndRefResourceByUniqueKey(key);
302 if (resource) {
303 GrTexture* texture = static_cast<GrSurface*>(resource)->asTexture();
304 SkASSERT(texture);
305 return texture;
306 }
307 return NULL;
308}
309
Robert Phillipsd3749482017-03-14 09:17:43 -0400310// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
311void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
312 ASSERT_SINGLE_OWNER
313 SkASSERT(key.isValid());
314 if (this->isAbandoned() || !proxy) {
315 return;
316 }
317
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400318 if (!proxy->instantiate(this)) {
Robert Phillipsd3749482017-03-14 09:17:43 -0400319 return;
320 }
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400321 GrTexture* texture = proxy->priv().peekTexture();
Robert Phillipsd3749482017-03-14 09:17:43 -0400322
323 this->assignUniqueKeyToResource(key, texture);
324}
325
326// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
327sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key) {
328 ASSERT_SINGLE_OWNER
329
330 sk_sp<GrTexture> texture(this->findAndRefTextureByUniqueKey(key));
331 if (!texture) {
332 return nullptr;
333 }
334
335 return GrSurfaceProxy::MakeWrapped(std::move(texture));
336}
337
Chris Daltonff926502017-05-03 14:36:54 -0400338const GrBuffer* GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
cdalton397536c2016-03-25 12:15:03 -0700339 int patternSize,
340 int reps,
341 int vertCount,
342 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700343 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
344
Brian Salomon09d994e2016-12-21 11:14:46 -0500345 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
cdaltone2e71c22016-04-07 18:13:29 -0700346 GrBuffer* buffer = this->createBuffer(bufferSize, kIndex_GrBufferType, kStatic_GrAccessPattern,
cdalton397536c2016-03-25 12:15:03 -0700347 kNoPendingIO_Flag);
bsalomoned0bcad2015-05-04 10:36:42 -0700348 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700349 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700350 }
351 uint16_t* data = (uint16_t*) buffer->map();
halcanary96fcdcc2015-08-27 07:41:13 -0700352 bool useTempData = (nullptr == data);
bsalomoned0bcad2015-05-04 10:36:42 -0700353 if (useTempData) {
halcanary385fe4d2015-08-26 13:07:48 -0700354 data = new uint16_t[reps * patternSize];
bsalomoned0bcad2015-05-04 10:36:42 -0700355 }
356 for (int i = 0; i < reps; ++i) {
357 int baseIdx = i * patternSize;
358 uint16_t baseVert = (uint16_t)(i * vertCount);
359 for (int j = 0; j < patternSize; ++j) {
360 data[baseIdx+j] = baseVert + pattern[j];
361 }
362 }
363 if (useTempData) {
364 if (!buffer->updateData(data, bufferSize)) {
365 buffer->unref();
halcanary96fcdcc2015-08-27 07:41:13 -0700366 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700367 }
halcanary385fe4d2015-08-26 13:07:48 -0700368 delete[] data;
bsalomoned0bcad2015-05-04 10:36:42 -0700369 } else {
370 buffer->unmap();
371 }
372 this->assignUniqueKeyToResource(key, buffer);
373 return buffer;
374}
375
cdalton397536c2016-03-25 12:15:03 -0700376const GrBuffer* GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700377 static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
378 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
379 static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
380
Chris Daltonff926502017-05-03 14:36:54 -0400381 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700382}
383
Robert Phillips67d52cf2017-06-05 13:38:13 -0400384sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700385 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700386 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700387}
388
Robert Phillips67d52cf2017-06-05 13:38:13 -0400389sk_sp<GrPathRange> GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
390 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700391 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700392 return this->gpu()->pathRendering()->createPathRange(gen, style);
bsalomon706f08f2015-05-22 07:35:58 -0700393}
394
Robert Phillips67d52cf2017-06-05 13:38:13 -0400395sk_sp<GrPathRange> GrResourceProvider::createGlyphs(const SkTypeface* tf,
396 const SkScalerContextEffects& effects,
397 const SkDescriptor* desc,
398 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700399
400 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700401 return this->gpu()->pathRendering()->createGlyphs(tf, effects, desc, style);
bsalomon706f08f2015-05-22 07:35:58 -0700402}
403
cdaltone2e71c22016-04-07 18:13:29 -0700404GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700405 GrAccessPattern accessPattern, uint32_t flags,
406 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700407 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700408 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700409 }
cdaltond37fe762016-04-21 07:41:50 -0700410 if (kDynamic_GrAccessPattern != accessPattern) {
411 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
412 }
csmartdalton485a1202016-07-13 10:16:32 -0700413 if (!(flags & kRequireGpuMemory_Flag) &&
414 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
415 GrBufferTypeIsVertexOrIndex(intendedType) &&
416 kDynamic_GrAccessPattern == accessPattern) {
417 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
418 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700419
cdaltond37fe762016-04-21 07:41:50 -0700420 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400421 static const size_t MIN_SIZE = 1 << 12;
422 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700423
cdaltond37fe762016-04-21 07:41:50 -0700424 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700425 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700426 uint32_t scratchFlags = 0;
427 if (flags & kNoPendingIO_Flag) {
428 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
429 } else {
430 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
431 }
432 GrBuffer* buffer = static_cast<GrBuffer*>(
433 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
434 if (!buffer) {
435 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
436 if (!buffer) {
437 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700438 }
439 }
cdaltond37fe762016-04-21 07:41:50 -0700440 if (data) {
441 buffer->updateData(data, size);
442 }
csmartdalton485a1202016-07-13 10:16:32 -0700443 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700444 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800445}
446
egdanielec00d942015-09-14 12:56:10 -0700447GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
448 SkASSERT(rt);
449 if (rt->renderTargetPriv().getStencilAttachment()) {
450 return rt->renderTargetPriv().getStencilAttachment();
451 }
452
453 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
454 GrUniqueKey sbKey;
455
456 int width = rt->width();
457 int height = rt->height();
458#if 0
459 if (this->caps()->oversizedStencilSupport()) {
460 width = SkNextPow2(width);
461 height = SkNextPow2(height);
462 }
463#endif
464 bool newStencil = false;
465 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
466 rt->numStencilSamples(), &sbKey);
467 GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>(
468 this->findAndRefResourceByUniqueKey(sbKey));
469 if (!stencil) {
470 // Need to try and create a new stencil
471 stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height);
472 if (stencil) {
Robert Phillipsf7cf81a2017-03-02 10:23:52 -0500473 this->assignUniqueKeyToResource(sbKey, stencil);
egdanielec00d942015-09-14 12:56:10 -0700474 newStencil = true;
475 }
476 }
477 if (rt->renderTargetPriv().attachStencilAttachment(stencil)) {
478 if (newStencil) {
479 // Right now we're clearing the stencil attachment here after it is
bsalomon7ea33f52015-11-22 14:51:00 -0800480 // attached to a RT for the first time. When we start matching
egdanielec00d942015-09-14 12:56:10 -0700481 // stencil buffers with smaller color targets this will no longer
482 // be correct because it won't be guaranteed to clear the entire
483 // sb.
484 // We used to clear down in the GL subclass using a special purpose
485 // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
486 // FBO status.
487 this->gpu()->clearStencil(rt);
488 }
489 }
490 }
491 return rt->renderTargetPriv().getStencilAttachment();
492}
493
bungeman6bd52842016-10-27 09:30:08 -0700494sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000495 const GrBackendTexture& tex, GrSurfaceOrigin origin, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700496{
ericrkf7b8b8a2016-02-24 14:49:51 -0800497 if (this->isAbandoned()) {
498 return nullptr;
499 }
Greg Daniel7ef28f32017-04-20 16:41:55 +0000500 return this->gpu()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800501}
Greg Danield85f97d2017-03-07 13:37:21 -0500502
503sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore() {
504 return fGpu->makeSemaphore();
505}
506
507void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
508 semaphore->resetGpu(fGpu);
509}
510
511void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
512 semaphore->resetGpu(nullptr);
513}