blob: 7fef3508eb4128b00d01eaf18ff58d2bb5124f7a [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"
egdanielec00d942015-09-14 12:56:10 -070018#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 Phillips8e8c7552017-07-10 12:06:05 -040075sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Robert Phillips590533f2017-07-11 14:22:35 -040076 const GrMipLevel texels[], int mipLevelCount,
Robert Phillips8e8c7552017-07-10 12:06:05 -040077 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050078 ASSERT_SINGLE_OWNER
79
Robert Phillips7f1b4f82017-11-28 07:38:39 -050080 SkASSERT(mipLevelCount > 0);
Robert Phillips1119dc32017-04-11 12:54:57 -040081
Brian Osman32342f02017-03-04 08:12:46 -050082 if (this->isAbandoned()) {
83 return nullptr;
84 }
Robert Phillips1119dc32017-04-11 12:54:57 -040085
Robert Phillips590533f2017-07-11 14:22:35 -040086 if (!validate_desc(desc, *fCaps, mipLevelCount)) {
Brian Osman32342f02017-03-04 08:12:46 -050087 return nullptr;
88 }
Brian Osman32342f02017-03-04 08:12:46 -050089
Robert Phillips590533f2017-07-11 14:22:35 -040090 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
Robert Phillipse78b7252017-04-06 07:59:41 -040091 if (tex) {
92 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -040093 }
Robert Phillipse78b7252017-04-06 07:59:41 -040094
Robert Phillips8e8c7552017-07-10 12:06:05 -040095 return tex;
Brian Osman32342f02017-03-04 08:12:46 -050096}
97
Robert Phillips45fdae12017-04-17 12:57:27 -040098sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -040099 SkBudgeted budgeted, uint32_t flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -0400100 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
101 if (tex && SkBudgeted::kNo == budgeted) {
102 tex->resourcePriv().makeUnbudgeted();
103 }
104
105 return tex;
106}
107
108static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
109 SkColorType colorType;
110 if (!GrPixelConfigToColorType(config, &colorType)) {
111 return false;
112 }
113
114 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
115 return true;
116}
117
118sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
119 SkBudgeted budgeted,
120 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -0400121 ASSERT_SINGLE_OWNER
122
123 if (this->isAbandoned()) {
124 return nullptr;
125 }
126
Robert Phillips45fdae12017-04-17 12:57:27 -0400127 if (!mipLevel.fPixels) {
128 return nullptr;
129 }
130
Brian Salomond34edf32017-05-19 15:45:48 -0400131 if (!validate_desc(desc, *fCaps)) {
132 return nullptr;
133 }
134
Robert Phillips45fdae12017-04-17 12:57:27 -0400135 GrContext* context = fGpu->getContext();
136
Robert Phillips92de6312017-05-23 07:43:48 -0400137 SkImageInfo srcInfo;
Robert Phillips45fdae12017-04-17 12:57:27 -0400138
Robert Phillips92de6312017-05-23 07:43:48 -0400139 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
Greg Daniel21918232017-09-08 14:46:23 -0400140 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
Robert Phillips066f0202017-07-25 10:16:35 -0400141 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
Robert Phillipsfe50d962017-06-01 10:22:03 -0400142 if (proxy) {
143 sk_sp<GrSurfaceContext> sContext =
144 context->contextPriv().makeWrappedSurfaceContext(std::move(proxy), nullptr);
145 if (sContext) {
146 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
147 return sContext->asTextureProxyRef();
148 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400149 }
150 }
151 }
152
Robert Phillips590533f2017-07-11 14:22:35 -0400153 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, &mipLevel, 1));
Robert Phillips066f0202017-07-25 10:16:35 -0400154 return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
Robert Phillips45fdae12017-04-17 12:57:27 -0400155}
156
Robert Phillipse78b7252017-04-06 07:59:41 -0400157sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
158 uint32_t flags) {
159 ASSERT_SINGLE_OWNER
160
161 if (this->isAbandoned()) {
162 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500163 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400164
Brian Salomond34edf32017-05-19 15:45:48 -0400165 if (!validate_desc(desc, *fCaps)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400166 return nullptr;
167 }
168
Greg Daniel21918232017-09-08 14:46:23 -0400169 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
Robert Phillips92de6312017-05-23 07:43:48 -0400170 if (tex) {
171 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400172 }
173
Robert Phillips67d52cf2017-06-05 13:38:13 -0400174 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500175}
176
Robert Phillips67d52cf2017-06-05 13:38:13 -0400177sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
178 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500179 ASSERT_SINGLE_OWNER
180 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500181
Brian Osman32342f02017-03-04 08:12:46 -0500182 if (this->isAbandoned()) {
183 return nullptr;
184 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400185
Brian Salomond34edf32017-05-19 15:45:48 -0400186 if (!validate_desc(desc, *fCaps)) {
187 return nullptr;
188 }
189
Greg Daniel6b60b6e2017-09-26 16:37:12 -0400190 if (auto tex = this->refScratchTexture(desc, flags)) {
191 return tex;
192 }
193
Greg Daniel29bf84f2017-09-25 12:25:12 -0400194 SkTCopyOnFirstWrite<GrSurfaceDesc> copyDesc(desc);
195
196 // bin by pow2 with a reasonable min
197 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
198 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
199 GrSurfaceDesc* wdesc = copyDesc.writable();
200 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fWidth));
201 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc.fHeight));
202 }
203
204 if (auto tex = this->refScratchTexture(*copyDesc, flags)) {
205 return tex;
206 }
207
208 return fGpu->createTexture(*copyDesc, SkBudgeted::kYes);
Brian Osman32342f02017-03-04 08:12:46 -0500209}
210
Greg Daniel29bf84f2017-09-25 12:25:12 -0400211sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& desc,
Greg Daniel21918232017-09-08 14:46:23 -0400212 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500213 ASSERT_SINGLE_OWNER
214 SkASSERT(!this->isAbandoned());
Greg Daniel29bf84f2017-09-25 12:25:12 -0400215 SkASSERT(validate_desc(desc, *fCaps));
Brian Osman32342f02017-03-04 08:12:46 -0500216
Brian Salomond17b4a62017-05-23 16:53:47 -0400217 // We could make initial clears work with scratch textures but it is a rare case so we just opt
218 // to fall back to making a new texture.
Greg Daniel29bf84f2017-09-25 12:25:12 -0400219 if (!SkToBool(desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
220 (fGpu->caps()->reuseScratchTextures() || (desc.fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500221
222 GrScratchKey key;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400223 GrTexturePriv::ComputeScratchKey(desc, &key);
Brian Osman32342f02017-03-04 08:12:46 -0500224 uint32_t scratchFlags = 0;
225 if (kNoPendingIO_Flag & flags) {
226 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
Greg Daniel29bf84f2017-09-25 12:25:12 -0400227 } else if (!(desc.fFlags & kRenderTarget_GrSurfaceFlag)) {
Brian Osman32342f02017-03-04 08:12:46 -0500228 // If it is not a render target then it will most likely be populated by
229 // writePixels() which will trigger a flush if the texture has pending IO.
230 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
231 }
232 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
Greg Daniel29bf84f2017-09-25 12:25:12 -0400233 GrSurface::WorstCaseSize(desc),
234 scratchFlags);
Brian Osman32342f02017-03-04 08:12:46 -0500235 if (resource) {
236 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400237 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500238 }
239 }
240
Brian Osman32342f02017-03-04 08:12:46 -0500241 return nullptr;
242}
243
Greg Daniel7ef28f32017-04-20 16:41:55 +0000244sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Brian Osman32342f02017-03-04 08:12:46 -0500245 GrWrapOwnership ownership) {
246 ASSERT_SINGLE_OWNER
247 if (this->isAbandoned()) {
248 return nullptr;
249 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400250 return fGpu->wrapBackendTexture(tex, ownership);
Brian Salomond17f6582017-07-19 18:28:58 -0400251}
252
253sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Brian Salomond17f6582017-07-19 18:28:58 -0400254 int sampleCnt,
255 GrWrapOwnership ownership) {
256 ASSERT_SINGLE_OWNER
257 if (this->isAbandoned()) {
258 return nullptr;
259 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400260 return fGpu->wrapRenderableBackendTexture(tex, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500261}
262
263sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400264 const GrBackendRenderTarget& backendRT)
Brian Osman32342f02017-03-04 08:12:46 -0500265{
266 ASSERT_SINGLE_OWNER
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400267 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT);
Brian Osman32342f02017-03-04 08:12:46 -0500268}
269
270void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
271 GrGpuResource* resource) {
272 ASSERT_SINGLE_OWNER
273 if (this->isAbandoned() || !resource) {
274 return;
275 }
276 resource->resourcePriv().setUniqueKey(key);
277}
278
Greg Danielcd871402017-09-26 12:49:26 -0400279void GrResourceProvider::removeUniqueKeyFromProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
280 ASSERT_SINGLE_OWNER
281 if (this->isAbandoned() || !proxy) {
282 return;
283 }
284 fCache->processInvalidProxyUniqueKey(key, proxy, true);
285}
286
Brian Salomond28a79d2017-10-16 13:01:07 -0400287sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
Brian Osman32342f02017-03-04 08:12:46 -0500288 ASSERT_SINGLE_OWNER
Brian Salomond28a79d2017-10-16 13:01:07 -0400289 return this->isAbandoned() ? nullptr
290 : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
Brian Osman32342f02017-03-04 08:12:46 -0500291}
292
Robert Phillipsd3749482017-03-14 09:17:43 -0400293void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
294 ASSERT_SINGLE_OWNER
295 SkASSERT(key.isValid());
296 if (this->isAbandoned() || !proxy) {
297 return;
298 }
299
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400300 fCache->assignUniqueKeyToProxy(key, proxy);
Robert Phillipsd3749482017-03-14 09:17:43 -0400301}
302
Robert Phillips066f0202017-07-25 10:16:35 -0400303sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key,
304 GrSurfaceOrigin origin) {
Robert Phillipsd3749482017-03-14 09:17:43 -0400305 ASSERT_SINGLE_OWNER
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400306 return this->isAbandoned() ? nullptr : fCache->findProxyByUniqueKey(key, origin);
Robert Phillipsd3749482017-03-14 09:17:43 -0400307}
308
Greg Danielcd871402017-09-26 12:49:26 -0400309sk_sp<GrTextureProxy> GrResourceProvider::findOrCreateProxyByUniqueKey(const GrUniqueKey& key,
310 GrSurfaceOrigin origin) {
311 ASSERT_SINGLE_OWNER
312 return this->isAbandoned() ? nullptr : fCache->findOrCreateProxyByUniqueKey(key, origin);
313}
314
Chris Dalton5d2de082017-12-19 10:40:23 -0700315sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType,
316 size_t size,
317 const void* data,
318 const GrUniqueKey& key) {
319 if (auto buffer = this->findByUniqueKey<GrBuffer>(key)) {
320 return buffer;
321 }
322 if (auto buffer = this->createBuffer(size, intendedType, kStatic_GrAccessPattern, 0,
323 data)) {
324 // We shouldn't bin and/or cachestatic buffers.
325 SkASSERT(buffer->sizeInBytes() == size);
326 SkASSERT(!buffer->resourcePriv().getScratchKey().isValid());
327 SkASSERT(!buffer->resourcePriv().hasPendingIO_debugOnly());
328 buffer->resourcePriv().setUniqueKey(key);
329 return sk_sp<const GrBuffer>(buffer);
330 }
331 return nullptr;
332}
333
Brian Salomond28a79d2017-10-16 13:01:07 -0400334sk_sp<const GrBuffer> GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
335 int patternSize,
336 int reps,
337 int vertCount,
338 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700339 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
340
Brian Salomon09d994e2016-12-21 11:14:46 -0500341 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400342 sk_sp<GrBuffer> buffer(this->createBuffer(bufferSize, kIndex_GrBufferType,
343 kStatic_GrAccessPattern, kNoPendingIO_Flag));
bsalomoned0bcad2015-05-04 10:36:42 -0700344 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700345 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700346 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400347 uint16_t* data = (uint16_t*) buffer->map();
348 SkAutoTArray<uint16_t> temp;
349 if (!data) {
350 temp.reset(reps * patternSize);
351 data = temp.get();
352 }
bsalomoned0bcad2015-05-04 10:36:42 -0700353 for (int i = 0; i < reps; ++i) {
354 int baseIdx = i * patternSize;
355 uint16_t baseVert = (uint16_t)(i * vertCount);
356 for (int j = 0; j < patternSize; ++j) {
357 data[baseIdx+j] = baseVert + pattern[j];
358 }
359 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400360 if (temp.get()) {
361 if (!buffer->updateData(data, bufferSize)) {
362 return nullptr;
363 }
364 } else {
365 buffer->unmap();
bsalomoned0bcad2015-05-04 10:36:42 -0700366 }
Brian Salomon7f56d3d2017-10-09 13:02:49 -0400367 this->assignUniqueKeyToResource(key, buffer.get());
Brian Salomond28a79d2017-10-16 13:01:07 -0400368 return std::move(buffer);
bsalomoned0bcad2015-05-04 10:36:42 -0700369}
370
Brian Salomon34169692017-08-28 15:32:01 -0400371static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
372
Brian Salomond28a79d2017-10-16 13:01:07 -0400373sk_sp<const GrBuffer> GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700374 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
Brian Salomon57caa662017-10-18 12:21:05 +0000375 static const uint16_t kPattern[] = { 0, 1, 2, 2, 1, 3 };
Chris Daltonff926502017-05-03 14:36:54 -0400376 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700377}
378
Brian Salomon34169692017-08-28 15:32:01 -0400379int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
380
Robert Phillips67d52cf2017-06-05 13:38:13 -0400381sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400382 if (this->isAbandoned()) {
383 return nullptr;
384 }
385
bsalomon706f08f2015-05-22 07:35:58 -0700386 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700387 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700388}
389
Robert Phillips67d52cf2017-06-05 13:38:13 -0400390sk_sp<GrPathRange> GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
391 const GrStyle& style) {
Robert Phillips0f171812017-09-21 14:25:31 -0400392 if (this->isAbandoned()) {
393 return nullptr;
394 }
395
bsalomon706f08f2015-05-22 07:35:58 -0700396 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700397 return this->gpu()->pathRendering()->createPathRange(gen, style);
bsalomon706f08f2015-05-22 07:35:58 -0700398}
399
Robert Phillips67d52cf2017-06-05 13:38:13 -0400400sk_sp<GrPathRange> GrResourceProvider::createGlyphs(const SkTypeface* tf,
401 const SkScalerContextEffects& effects,
402 const SkDescriptor* desc,
403 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700404
405 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700406 return this->gpu()->pathRendering()->createGlyphs(tf, effects, desc, style);
bsalomon706f08f2015-05-22 07:35:58 -0700407}
408
cdaltone2e71c22016-04-07 18:13:29 -0700409GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700410 GrAccessPattern accessPattern, uint32_t flags,
411 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700412 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700413 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700414 }
cdaltond37fe762016-04-21 07:41:50 -0700415 if (kDynamic_GrAccessPattern != accessPattern) {
416 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
417 }
csmartdalton485a1202016-07-13 10:16:32 -0700418 if (!(flags & kRequireGpuMemory_Flag) &&
419 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
420 GrBufferTypeIsVertexOrIndex(intendedType) &&
421 kDynamic_GrAccessPattern == accessPattern) {
422 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
423 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700424
cdaltond37fe762016-04-21 07:41:50 -0700425 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400426 static const size_t MIN_SIZE = 1 << 12;
427 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700428
cdaltond37fe762016-04-21 07:41:50 -0700429 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700430 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700431 uint32_t scratchFlags = 0;
432 if (flags & kNoPendingIO_Flag) {
433 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
434 } else {
435 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
436 }
437 GrBuffer* buffer = static_cast<GrBuffer*>(
438 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
439 if (!buffer) {
440 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
441 if (!buffer) {
442 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700443 }
444 }
cdaltond37fe762016-04-21 07:41:50 -0700445 if (data) {
446 buffer->updateData(data, size);
447 }
csmartdalton485a1202016-07-13 10:16:32 -0700448 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700449 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800450}
451
Robert Phillipsc0192e32017-09-21 12:00:26 -0400452bool GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
egdanielec00d942015-09-14 12:56:10 -0700453 SkASSERT(rt);
454 if (rt->renderTargetPriv().getStencilAttachment()) {
Robert Phillipsc0192e32017-09-21 12:00:26 -0400455 return true;
egdanielec00d942015-09-14 12:56:10 -0700456 }
457
458 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
459 GrUniqueKey sbKey;
460
461 int width = rt->width();
462 int height = rt->height();
463#if 0
464 if (this->caps()->oversizedStencilSupport()) {
465 width = SkNextPow2(width);
466 height = SkNextPow2(height);
467 }
468#endif
Robert Phillipscb2e2352017-08-30 16:44:40 -0400469 SkDEBUGCODE(bool newStencil = false;)
egdanielec00d942015-09-14 12:56:10 -0700470 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
471 rt->numStencilSamples(), &sbKey);
Brian Salomond28a79d2017-10-16 13:01:07 -0400472 auto stencil = this->findByUniqueKey<GrStencilAttachment>(sbKey);
egdanielec00d942015-09-14 12:56:10 -0700473 if (!stencil) {
474 // Need to try and create a new stencil
Brian Salomond28a79d2017-10-16 13:01:07 -0400475 stencil.reset(this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height));
egdanielec00d942015-09-14 12:56:10 -0700476 if (stencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400477 this->assignUniqueKeyToResource(sbKey, stencil.get());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400478 SkDEBUGCODE(newStencil = true;)
egdanielec00d942015-09-14 12:56:10 -0700479 }
480 }
Brian Salomond28a79d2017-10-16 13:01:07 -0400481 if (rt->renderTargetPriv().attachStencilAttachment(std::move(stencil))) {
Robert Phillips95214472017-08-08 18:00:03 -0400482#ifdef SK_DEBUG
483 // Fill the SB with an inappropriate value. opLists that use the
484 // SB should clear it properly.
Robert Phillipscb2e2352017-08-30 16:44:40 -0400485 if (newStencil) {
Brian Salomond28a79d2017-10-16 13:01:07 -0400486 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400487 this->gpu()->clearStencil(rt, 0xFFFF);
Brian Salomond28a79d2017-10-16 13:01:07 -0400488 SkASSERT(rt->renderTargetPriv().getStencilAttachment()->isDirty());
Robert Phillipscb2e2352017-08-30 16:44:40 -0400489 }
Robert Phillips95214472017-08-08 18:00:03 -0400490#endif
egdanielec00d942015-09-14 12:56:10 -0700491 }
492 }
Robert Phillipsc0192e32017-09-21 12:00:26 -0400493 return SkToBool(rt->renderTargetPriv().getStencilAttachment());
egdanielec00d942015-09-14 12:56:10 -0700494}
495
bungeman6bd52842016-10-27 09:30:08 -0700496sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400497 const GrBackendTexture& tex, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700498{
ericrkf7b8b8a2016-02-24 14:49:51 -0800499 if (this->isAbandoned()) {
500 return nullptr;
501 }
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400502 return this->gpu()->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800503}
Greg Danield85f97d2017-03-07 13:37:21 -0500504
Greg Daniela5cb7812017-06-16 09:45:32 -0400505sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
506 return fGpu->makeSemaphore(isOwned);
507}
508
509sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
510 GrWrapOwnership ownership) {
511 ASSERT_SINGLE_OWNER
512 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore, ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500513}
514
515void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
516 semaphore->resetGpu(fGpu);
517}
518
519void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
520 semaphore->resetGpu(nullptr);
521}