blob: c9575b26dcc44ce670b404209f65c2e4f0c9c832 [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
33#define ASSERT_SINGLE_OWNER \
34 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
35
Robert Phillips4150eea2018-02-07 17:08:21 -050036GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner,
37 bool explicitlyAllocateGPUResources)
Brian Osman32342f02017-03-04 08:12:46 -050038 : fCache(cache)
39 , fGpu(gpu)
Robert Phillips4150eea2018-02-07 17:08:21 -050040 , fExplicitlyAllocateGPUResources(explicitlyAllocateGPUResources)
Brian Osman32342f02017-03-04 08:12:46 -050041#ifdef SK_DEBUG
42 , fSingleOwner(owner)
43#endif
Robert Phillips4150eea2018-02-07 17:08:21 -050044{
Robert Phillips26c90e02017-03-14 14:39:29 -040045 fCaps = sk_ref_sp(fGpu->caps());
46
bsalomoned0bcad2015-05-04 10:36:42 -070047 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
48 fQuadIndexBufferKey = gQuadIndexBufferKey;
49}
50
Robert Phillips8e8c7552017-07-10 12:06:05 -040051sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Robert Phillips590533f2017-07-11 14:22:35 -040052 const GrMipLevel texels[], int mipLevelCount,
Robert Phillips8e8c7552017-07-10 12:06:05 -040053 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050054 ASSERT_SINGLE_OWNER
55
Robert Phillips7f1b4f82017-11-28 07:38:39 -050056 SkASSERT(mipLevelCount > 0);
Robert Phillips1119dc32017-04-11 12:54:57 -040057
Brian Osman32342f02017-03-04 08:12:46 -050058 if (this->isAbandoned()) {
59 return nullptr;
60 }
Robert Phillips1119dc32017-04-11 12:54:57 -040061
Brian Salomonbdecacf2018-02-02 20:32:49 -050062 GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
63 if (!fCaps->validateSurfaceDesc(desc, mipMapped)) {
Brian Osman32342f02017-03-04 08:12:46 -050064 return nullptr;
65 }
Brian Osman32342f02017-03-04 08:12:46 -050066
Robert Phillips590533f2017-07-11 14:22:35 -040067 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
Robert Phillipse78b7252017-04-06 07:59:41 -040068 if (tex) {
69 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -040070 }
Robert Phillipse78b7252017-04-06 07:59:41 -040071
Robert Phillips8e8c7552017-07-10 12:06:05 -040072 return tex;
Brian Osman32342f02017-03-04 08:12:46 -050073}
74
Robert Phillips45fdae12017-04-17 12:57:27 -040075sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -040076 SkBudgeted budgeted, uint32_t flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -040077 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
78 if (tex && SkBudgeted::kNo == budgeted) {
79 tex->resourcePriv().makeUnbudgeted();
80 }
81
82 return tex;
83}
84
85static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
86 SkColorType colorType;
87 if (!GrPixelConfigToColorType(config, &colorType)) {
88 return false;
89 }
90
91 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
92 return true;
93}
94
Robert Phillips1afd4cd2018-01-08 13:40:32 -050095sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
96 SkBudgeted budgeted,
Greg Danielfb3abcd2018-02-02 15:48:33 -050097 SkBackingFit fit,
Robert Phillips1afd4cd2018-01-08 13:40:32 -050098 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -040099 ASSERT_SINGLE_OWNER
100
101 if (this->isAbandoned()) {
102 return nullptr;
103 }
104
Robert Phillips45fdae12017-04-17 12:57:27 -0400105 if (!mipLevel.fPixels) {
106 return nullptr;
107 }
108
Brian Salomonbdecacf2018-02-02 20:32:49 -0500109 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400110 return nullptr;
111 }
112
Robert Phillips45fdae12017-04-17 12:57:27 -0400113 GrContext* context = fGpu->getContext();
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500114 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillips45fdae12017-04-17 12:57:27 -0400115
Robert Phillips92de6312017-05-23 07:43:48 -0400116 SkImageInfo srcInfo;
Robert Phillips45fdae12017-04-17 12:57:27 -0400117
Robert Phillips92de6312017-05-23 07:43:48 -0400118 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500119 // DDL TODO: remove this use of createInstantiatedProxy and convert it to a testing-only
120 // method.
121 sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc,
Greg Danielfb3abcd2018-02-02 15:48:33 -0500122 fit,
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500123 budgeted);
Robert Phillipsfe50d962017-06-01 10:22:03 -0400124 if (proxy) {
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500125 sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
126 std::move(proxy));
Robert Phillipsfe50d962017-06-01 10:22:03 -0400127 if (sContext) {
128 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500129 return sk_ref_sp(sContext->asTextureProxy()->priv().peekTexture());
Robert Phillipsfe50d962017-06-01 10:22:03 -0400130 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400131 }
132 }
133 }
134
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500135 return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
Robert Phillips45fdae12017-04-17 12:57:27 -0400136}
137
Robert Phillipse78b7252017-04-06 07:59:41 -0400138sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
139 uint32_t flags) {
140 ASSERT_SINGLE_OWNER
Robert Phillipse78b7252017-04-06 07:59:41 -0400141 if (this->isAbandoned()) {
142 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500143 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400144
Brian Salomonbdecacf2018-02-02 20:32:49 -0500145 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400146 return nullptr;
147 }
148
Greg Daniel21918232017-09-08 14:46:23 -0400149 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
Robert Phillips92de6312017-05-23 07:43:48 -0400150 if (tex) {
151 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400152 }
153
Robert Phillips67d52cf2017-06-05 13:38:13 -0400154 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500155}
156
Robert Phillips67d52cf2017-06-05 13:38:13 -0400157sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
158 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500159 ASSERT_SINGLE_OWNER
160 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500161
Brian Osman32342f02017-03-04 08:12:46 -0500162 if (this->isAbandoned()) {
163 return nullptr;
164 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400165
Brian Salomonbdecacf2018-02-02 20:32:49 -0500166 if (!fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo)) {
Brian Salomond34edf32017-05-19 15:45:48 -0400167 return nullptr;
168 }
169
Greg Daniel6b60b6e2017-09-26 16:37:12 -0400170 if (auto tex = this->refScratchTexture(desc, flags)) {
171 return tex;
172 }
173
Greg Daniel29bf84f2017-09-25 12:25:12 -0400174 SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
175
176 // bin by pow2 with a reasonable min
177 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
178 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
179 GrSurfaceDesc* wdesc = copyDesc.writable();
180 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
181 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
182 }
183
184 if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
185 return tex;
186 }
187
188 return fGpu->createTexture(*copyDesc, SkBudgeted::kYes);
Brian Osman32342f02017-03-04 08:12:46 -0500189}
190
Greg Daniel29bf84f2017-09-25 12:25:12 -0400191sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -0400192 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500193 ASSERT_SINGLE_OWNER
194 SkASSERT(!this->isAbandoned());
Brian Salomonbdecacf2018-02-02 20:32:49 -0500195 SkASSERT(fCaps->validateSurfaceDesc(desc, GrMipMapped::kNo));
Brian Osman32342f02017-03-04 08:12:46 -0500196
Brian Salomond17b4a62017-05-23 16:53:47 -0400197 // We could make initial clears work with scratch textures but it is a rare case so we just opt
198 // to fall back to making a new texture.
Greg Daniel29bf84f2017-09-25 12:25:12 -0400199 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
200 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500201
202 GrScratchKey key;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400203 GrTexturePriv::ComputeScratchKey(desc, &key);
Brian Osman32342f02017-03-04 08:12:46 -0500204 uint32_t scratchFlags = 0;
205 if (kNoPendingIO_Flag & flags) {
206 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400207 } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
Brian Osman32342f02017-03-04 08:12:46 -0500208 // If it is not a render target then it will most likely be populated by
209 // writePixels() which will trigger a flush if the texture has pending IO.
210 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
211 }
212 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
Greg Daniel29bf84f2017-09-25 12:25:12 -0400213 GrSurface::WorstCaseSize(desc),
214 scratchFlags);
Brian Osman32342f02017-03-04 08:12:46 -0500215 if (resource) {
216 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400217 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500218 }
219 }
220
Brian Osman32342f02017-03-04 08:12:46 -0500221 return nullptr;
222}
223
Greg Daniel7ef28f32017-04-20 16:41:55 +0000224sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Brian Osman32342f02017-03-04 08:12:46 -0500225 GrWrapOwnership ownership) {
226 ASSERT_SINGLE_OWNER
227 if (this->isAbandoned()) {
228 return nullptr;
229 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400230 return fGpu->wrapBackendTexture(tex, ownership);
Brian Salomond17f6582017-07-19 18:28:58 -0400231}
232
233sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Brian Salomond17f6582017-07-19 18:28:58 -0400234 int sampleCnt,
235 GrWrapOwnership ownership) {
236 ASSERT_SINGLE_OWNER
237 if (this->isAbandoned()) {
238 return nullptr;
239 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400240 return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500241}
242
243sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400244 const GrBackendRenderTarget& backendRT)
Brian Osman32342f02017-03-04 08:12:46 -0500245{
246 ASSERT_SINGLE_OWNER
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400247 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT);
Brian Osman32342f02017-03-04 08:12:46 -0500248}
249
250void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
251 GrGpuResource* resource) {
252 ASSERT_SINGLE_OWNER
253 if (this->isAbandoned() || !resource) {
254 return;
255 }
256 resource->resourcePriv().setUniqueKey(key);
257}
258
Brian Salomond28a79d2017-10-16 13:01:07 -0400259sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
Brian Osman32342f02017-03-04 08:12:46 -0500260 ASSERT_SINGLE_OWNER
Brian Salomond28a79d2017-10-16 13:01:07 -0400261 return this->isAbandoned() ? nullptr
262 : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
Brian Osman32342f02017-03-04 08:12:46 -0500263}
264
Chris Dalton5d2de082017-12-19 10:40:23 -0700265sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType,
266 size_t size,
267 const void* data,
268 const GrUniqueKey& key) {
269 if (auto buffer = this->findByUniqueKey<GrBuffer>(key)) {
270 return buffer;
271 }
272 if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, 0,
273 data)) {
274 // We shouldn't bin and/or cachestatic buffers.
275 SkASSERT(buffer->sizeInBytes() == size);
276 SkASSERT(!buffer->resourcePriv().getScratchKey().isValid());
277 SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly());
278 buffer->resourcePriv().setUniqueKey(key);
279 return sk_sp<const GrBuffer>(buffer);
280 }
281 return nullptr;
282}
283
Brian Salomond28a79d2017-10-16 13:01:07 -0400284sk_sp<const GrBuffer> GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
285 int patternSize,
286 int reps,
287 int vertCount,
288 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700289 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
290
Brian Salomon09d994e2016-12-21 11:14:46 -0500291 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400292 sk_sp<GrBuffer> buffer(this->createBuffer(bufferSize, kIndex_GrBufferType,
293 kStatic_GrAccessPattern, kNoPendingIO_Flag));
bsalomoned0bcad2015-05-04 10:36:42 -0700294 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700295 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700296 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400297 uint16_t* data = (uint16_t*) buffer->map();
298 SkAutoTArray<uint16_t> temp;
299 if (!data) {
300 temp.reset(reps * patternSize);
301 data = temp.get();
302 }
bsalomoned0bcad2015-05-04 10:36:42 -0700303 for (int i = 0; i < reps; ++i) {
304 int baseIdx = i * patternSize;
305 uint16_t baseVert = (uint16_t)(i * vertCount);
306 for (int j = 0; j < patternSize; ++j) {
307 data[baseIdx+j] = baseVert + pattern[j];
308 }
309 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400310 if (temp.get()) {
311 if (!buffer->updateData(data, bufferSize)) {
312 return nullptr;
313 }
314 } else {
315 buffer->unmap();
bsalomoned0bcad2015-05-04 10:36:42 -0700316 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400317 this->assignUniqueKeyToResource(key, buffer.get());
Brian Salomond28a79d2017-10-16 13:01:07 -0400318 return std::move(buffer);
bsalomoned0bcad2015-05-04 10:36:42 -0700319}
320
Brian Salomon34169692017-08-28 15:32:01 -0400321static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
322
Brian Salomond28a79d2017-10-16 13:01:07 -0400323sk_sp<const GrBuffer> GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700324 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
Brian Salomon57caa662017-10-18 12:21:05 +0000325 static const uint16_t kPattern[] = { 0, 1, 2, 2, 1, 3 };
Chris Daltonff926502017-05-03 14:36:54 -0400326 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700327}
328
Brian Salomon34169692017-08-28 15:32:01 -0400329int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
330
Robert Phillips67d52cf2017-06-05 13:38:13 -0400331sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400332 if (this->isAbandoned()) {
333 return nullptr;
334 }
335
bsalomon706f08f2015-05-22 07:35:58 -0700336 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700337 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700338}
339
Robert Phillips67d52cf2017-06-05 13:38:13 -0400340sk_sp<GrPathRange> GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
341 const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400342 if (this->isAbandoned()) {
343 return nullptr;
344 }
345
bsalomon706f08f2015-05-22 07:35:58 -0700346 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700347 return this->gpu()->pathRendering()->createPathRange(gen, style);
bsalomon706f08f2015-05-22 07:35:58 -0700348}
349
Robert Phillips67d52cf2017-06-05 13:38:13 -0400350sk_sp<GrPathRange> GrResourceProvider::createGlyphs(const SkTypeface* tf,
351 const SkScalerContextEffects& effects,
352 const SkDescriptor* desc,
353 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700354
355 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700356 return this->gpu()->pathRendering()->createGlyphs(tf, effects, desc, style);
bsalomon706f08f2015-05-22 07:35:58 -0700357}
358
cdaltone2e71c22016-04-07 18:13:29 -0700359GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700360 GrAccessPattern accessPattern, uint32_t flags,
361 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700362 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700363 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700364 }
cdaltond37fe762016-04-21 07:41:50 -0700365 if (kDynamic_GrAccessPattern != accessPattern) {
366 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
367 }
csmartdalton485a1202016-07-13 10:16:32 -0700368 if (!(flags & kRequireGpuMemory_Flag) &&
369 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
370 GrBufferTypeIsVertexOrIndex(intendedType) &&
371 kDynamic_GrAccessPattern == accessPattern) {
372 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
373 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700374
cdaltond37fe762016-04-21 07:41:50 -0700375 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400376 static const size_t MIN_SIZE = 1 << 12;
377 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700378
cdaltond37fe762016-04-21 07:41:50 -0700379 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700380 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700381 uint32_t scratchFlags = 0;
382 if (flags & kNoPendingIO_Flag) {
383 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
384 } else {
385 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
386 }
387 GrBuffer* buffer = static_cast<GrBuffer*>(
388 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
389 if (!buffer) {
390 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
391 if (!buffer) {
392 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700393 }
394 }
cdaltond37fe762016-04-21 07:41:50 -0700395 if (data) {
396 buffer->updateData(data, size);
397 }
csmartdalton485a1202016-07-13 10:16:32 -0700398 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700399 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800400}
401
Robert Phillipsc0192e32017-09-21 12:00:26 -0400402bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
egdanielec00d942015-09-14 12:56:10 -0700403 SkASSERT(rt);
404 if (rt->renderTargetPriv().getStencilAttachment()) {
Robert Phillipsc0192e32017-09-21 12:00:26 -0400405 return true;
egdanielec00d942015-09-14 12:56:10 -0700406 }
407
408 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
409 GrUniqueKey sbKey;
410
411 int width = rt->width();
412 int height = rt->height();
413#if 0
414 if (this->caps()->oversizedStencilSupport()) {
415 width = SkNextPow2(width);
416 height = SkNextPow2(height);
417 }
418#endif
Robert Phillipscb2e2352017-08-30 16:44:40 -0400419 SkDEBUGCODE(bool newStencil = false;)
egdanielec00d942015-09-14 12:56:10 -0700420 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
421 rt->numStencilSamples(), &sbKey);
Brian Salomond28a79d2017-10-16 13:01:07 -0400422 auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey);
egdanielec00d942015-09-14 12:56:10 -0700423 if (!stencil) {
424 // Need to try and create a new stencil
Brian Salomond28a79d2017-10-16 13:01:07 -0400425 stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
egdanielec00d942015-09-14 12:56:10 -0700426 if (stencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400427 this->assignUniqueKeyToResource(sbKey, stencil.get());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400428 SkDEBUGCODE(newStencil = true;)
egdanielec00d942015-09-14 12:56:10 -0700429 }
430 }
Brian Salomond28a79d2017-10-16 13:01:07 -0400431 if (rt->renderTargetPriv().attachStencilAttachment(std::move(stencil))) {
Robert Phillips95214472017-08-08 18:00:03 -0400432#ifdef SK_DEBUG
433 // Fill the SB with an inappropriate value. opLists that use the
434 // SB should clear it properly.
Robert Phillipscb2e2352017-08-30 16:44:40 -0400435 if (newStencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400436 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400437 this->gpu()->clearStencil(rt, 0xFFFF);
Brian Salomond28a79d2017-10-16 13:01:07 -0400438 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400439 }
Robert Phillips95214472017-08-08 18:00:03 -0400440#endif
egdanielec00d942015-09-14 12:56:10 -0700441 }
442 }
Robert Phillipsc0192e32017-09-21 12:00:26 -0400443 return SkToBool(rt->renderTargetPriv().getStencilAttachment());
egdanielec00d942015-09-14 12:56:10 -0700444}
445
bungeman6bd52842016-10-27 09:30:08 -0700446sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400447 const GrBackendTexture& tex, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700448{
ericrkf7b8b8a2016-02-24 14:49:51 -0800449 if (this->isAbandoned()) {
450 return nullptr;
451 }
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500452 return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800453}
Greg Danield85f97d2017-03-07 13:37:21 -0500454
Greg Daniela5cb7812017-06-16 09:45:32 -0400455sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
456 return fGpu->makeSemaphore(isOwned);
457}
458
459sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
Greg Daniel17b7c052018-01-09 13:55:33 -0500460 SemaphoreWrapType wrapType,
Greg Daniela5cb7812017-06-16 09:45:32 -0400461 GrWrapOwnership ownership) {
462 ASSERT_SINGLE_OWNER
Greg Daniel17b7c052018-01-09 13:55:33 -0500463 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore,
464 wrapType,
465 ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500466}
467
468void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
469 semaphore->resetGpu(fGpu);
470}
471
472void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
473 semaphore->resetGpu(nullptr);
474}