blob: 6dcc1497e8bd9f690d2a5577ac99d5d07eb2529a [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 "GrRenderTarget.h"
19#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"
Robert Phillipsb66b42f2017-03-14 08:53:02 -040024#include "GrSurfaceProxyPriv.h"
Brian Osman32342f02017-03-04 08:12:46 -050025#include "GrTexturePriv.h"
26#include "../private/GrSingleOwner.h"
Robert Phillips45fdae12017-04-17 12:57:27 -040027#include "SkGr.h"
halcanary4dbbd042016-06-07 17:21:10 -070028#include "SkMathPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070029
30GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
31
Robert Phillips1bfece82017-06-01 13:56:52 -040032const uint32_t GrResourceProvider::kMinScratchTextureSize = 16;
Brian Osman32342f02017-03-04 08:12:46 -050033
34#define ASSERT_SINGLE_OWNER \
35 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
36
joshualitt6d0872d2016-01-11 08:27:48 -080037GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner)
Brian Osman32342f02017-03-04 08:12:46 -050038 : fCache(cache)
39 , fGpu(gpu)
40#ifdef SK_DEBUG
41 , fSingleOwner(owner)
42#endif
43 {
Robert Phillips26c90e02017-03-14 14:39:29 -040044 fCaps = sk_ref_sp(fGpu->caps());
45
bsalomoned0bcad2015-05-04 10:36:42 -070046 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
47 fQuadIndexBufferKey = gQuadIndexBufferKey;
48}
49
Robert Phillipsf7a72612017-03-31 10:03:45 -040050bool GrResourceProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
Robert Phillipsb66b42f2017-03-14 08:53:02 -040051 return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
52}
Brian Osman32342f02017-03-04 08:12:46 -050053
Brian Salomond34edf32017-05-19 15:45:48 -040054bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount = 0) {
55 if (desc.fWidth <= 0 || desc.fHeight <= 0) {
56 return false;
57 }
58 if (!caps.isConfigTexturable(desc.fConfig)) {
59 return false;
60 }
61 if (desc.fFlags & kRenderTarget_GrSurfaceFlag) {
62 if (!caps.isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
63 return false;
64 }
65 } else {
66 if (desc.fSampleCnt) {
67 return false;
68 }
69 }
Brian Osman48c99192017-06-02 08:45:06 -040070 if (levelCount > 1 && (GrPixelConfigIsSint(desc.fConfig) || !caps.mipMapSupport())) {
Brian Salomond34edf32017-05-19 15:45:48 -040071 return false;
72 }
73 return true;
74}
75
Robert Phillips8e8c7552017-07-10 12:06:05 -040076sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
Robert Phillips590533f2017-07-11 14:22:35 -040077 const GrMipLevel texels[], int mipLevelCount,
Robert Phillips8e8c7552017-07-10 12:06:05 -040078 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050079 ASSERT_SINGLE_OWNER
80
Robert Phillips590533f2017-07-11 14:22:35 -040081 SkASSERT(mipLevelCount >= 1);
Robert Phillips1119dc32017-04-11 12:54:57 -040082
Brian Osman32342f02017-03-04 08:12:46 -050083 if (this->isAbandoned()) {
84 return nullptr;
85 }
Robert Phillips1119dc32017-04-11 12:54:57 -040086
Robert Phillips590533f2017-07-11 14:22:35 -040087 if (!validate_desc(desc, *fCaps, mipLevelCount)) {
Brian Osman32342f02017-03-04 08:12:46 -050088 return nullptr;
89 }
Brian Osman32342f02017-03-04 08:12:46 -050090
Robert Phillips590533f2017-07-11 14:22:35 -040091 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels, mipLevelCount));
Robert Phillipse78b7252017-04-06 07:59:41 -040092 if (tex) {
93 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -040094 }
Robert Phillipse78b7252017-04-06 07:59:41 -040095
Robert Phillips8e8c7552017-07-10 12:06:05 -040096 return tex;
Brian Osman32342f02017-03-04 08:12:46 -050097}
98
Robert Phillips45fdae12017-04-17 12:57:27 -040099sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
100 SkBudgeted budgeted, uint32_t flags) {
Robert Phillips45fdae12017-04-17 12:57:27 -0400101 flags |= kExact_Flag | kNoCreate_Flag;
102 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
103 if (tex && SkBudgeted::kNo == budgeted) {
104 tex->resourcePriv().makeUnbudgeted();
105 }
106
107 return tex;
108}
109
110static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
111 SkColorType colorType;
112 if (!GrPixelConfigToColorType(config, &colorType)) {
113 return false;
114 }
115
116 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
117 return true;
118}
119
120sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
121 SkBudgeted budgeted,
122 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -0400123 ASSERT_SINGLE_OWNER
124
125 if (this->isAbandoned()) {
126 return nullptr;
127 }
128
Robert Phillips45fdae12017-04-17 12:57:27 -0400129 if (!mipLevel.fPixels) {
130 return nullptr;
131 }
132
Brian Salomond34edf32017-05-19 15:45:48 -0400133 if (!validate_desc(desc, *fCaps)) {
134 return nullptr;
135 }
136
Robert Phillips45fdae12017-04-17 12:57:27 -0400137 GrContext* context = fGpu->getContext();
138
Robert Phillips92de6312017-05-23 07:43:48 -0400139 SkImageInfo srcInfo;
Robert Phillips45fdae12017-04-17 12:57:27 -0400140
Robert Phillips92de6312017-05-23 07:43:48 -0400141 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
142 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
Robert Phillips066f0202017-07-25 10:16:35 -0400143 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
Robert Phillipsfe50d962017-06-01 10:22:03 -0400144 if (proxy) {
145 sk_sp<GrSurfaceContext> sContext =
146 context->contextPriv().makeWrappedSurfaceContext(std::move(proxy), nullptr);
147 if (sContext) {
148 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
149 return sContext->asTextureProxyRef();
150 }
Robert Phillips45fdae12017-04-17 12:57:27 -0400151 }
152 }
153 }
154
Robert Phillips590533f2017-07-11 14:22:35 -0400155 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, &mipLevel, 1));
Robert Phillips066f0202017-07-25 10:16:35 -0400156 return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
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
162
163 if (this->isAbandoned()) {
164 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500165 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400166
Brian Salomond34edf32017-05-19 15:45:48 -0400167 if (!validate_desc(desc, *fCaps)) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400168 return nullptr;
169 }
170
Robert Phillips92de6312017-05-23 07:43:48 -0400171 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
172 if (tex) {
173 return tex;
Robert Phillipse78b7252017-04-06 07:59:41 -0400174 }
175
Robert Phillips67d52cf2017-06-05 13:38:13 -0400176 return fGpu->createTexture(desc, budgeted);
Brian Osman32342f02017-03-04 08:12:46 -0500177}
178
Robert Phillips67d52cf2017-06-05 13:38:13 -0400179sk_sp<GrTexture> GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc,
180 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500181 ASSERT_SINGLE_OWNER
182 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500183
Brian Osman32342f02017-03-04 08:12:46 -0500184 if (this->isAbandoned()) {
185 return nullptr;
186 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400187
Brian Salomond34edf32017-05-19 15:45:48 -0400188 if (!validate_desc(desc, *fCaps)) {
189 return nullptr;
190 }
191
Robert Phillips1119dc32017-04-11 12:54:57 -0400192 return this->refScratchTexture(desc, flags);
Brian Osman32342f02017-03-04 08:12:46 -0500193}
194
Robert Phillips67d52cf2017-06-05 13:38:13 -0400195sk_sp<GrTexture> GrResourceProvider::refScratchTexture(const GrSurfaceDesc& inDesc,
196 uint32_t flags) {
Brian Osman32342f02017-03-04 08:12:46 -0500197 ASSERT_SINGLE_OWNER
198 SkASSERT(!this->isAbandoned());
Brian Salomond34edf32017-05-19 15:45:48 -0400199 SkASSERT(validate_desc(inDesc, *fCaps));
Brian Osman32342f02017-03-04 08:12:46 -0500200
201 SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
202
Brian Salomond17b4a62017-05-23 16:53:47 -0400203 // We could make initial clears work with scratch textures but it is a rare case so we just opt
204 // to fall back to making a new texture.
205 if (!SkToBool(inDesc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
206 (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag))) {
Brian Osman32342f02017-03-04 08:12:46 -0500207 if (!(kExact_Flag & flags)) {
208 // bin by pow2 with a reasonable min
209 GrSurfaceDesc* wdesc = desc.writable();
210 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fWidth));
211 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fHeight));
212 }
213
214 GrScratchKey key;
215 GrTexturePriv::ComputeScratchKey(*desc, &key);
216 uint32_t scratchFlags = 0;
217 if (kNoPendingIO_Flag & flags) {
218 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
219 } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
220 // If it is not a render target then it will most likely be populated by
221 // writePixels() which will trigger a flush if the texture has pending IO.
222 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
223 }
224 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
225 GrSurface::WorstCaseSize(*desc),
226 scratchFlags);
227 if (resource) {
228 GrSurface* surface = static_cast<GrSurface*>(resource);
Robert Phillips67d52cf2017-06-05 13:38:13 -0400229 return sk_sp<GrTexture>(surface->asTexture());
Brian Osman32342f02017-03-04 08:12:46 -0500230 }
231 }
232
233 if (!(kNoCreate_Flag & flags)) {
234 return fGpu->createTexture(*desc, SkBudgeted::kYes);
235 }
236
237 return nullptr;
238}
239
Greg Daniel7ef28f32017-04-20 16:41:55 +0000240sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
Robert Phillips7294b852017-08-01 13:51:44 +0000241 GrSurfaceOrigin origin,
Brian Osman32342f02017-03-04 08:12:46 -0500242 GrWrapOwnership ownership) {
243 ASSERT_SINGLE_OWNER
244 if (this->isAbandoned()) {
245 return nullptr;
246 }
Robert Phillips7294b852017-08-01 13:51:44 +0000247 return fGpu->wrapBackendTexture(tex, origin, ownership);
Brian Salomond17f6582017-07-19 18:28:58 -0400248}
249
250sk_sp<GrTexture> GrResourceProvider::wrapRenderableBackendTexture(const GrBackendTexture& tex,
Robert Phillips7294b852017-08-01 13:51:44 +0000251 GrSurfaceOrigin origin,
Brian Salomond17f6582017-07-19 18:28:58 -0400252 int sampleCnt,
253 GrWrapOwnership ownership) {
254 ASSERT_SINGLE_OWNER
255 if (this->isAbandoned()) {
256 return nullptr;
257 }
Robert Phillips7294b852017-08-01 13:51:44 +0000258 return fGpu->wrapRenderableBackendTexture(tex, origin, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500259}
260
261sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Robert Phillips7294b852017-08-01 13:51:44 +0000262 const GrBackendRenderTarget& backendRT, GrSurfaceOrigin origin)
Brian Osman32342f02017-03-04 08:12:46 -0500263{
264 ASSERT_SINGLE_OWNER
Robert Phillips7294b852017-08-01 13:51:44 +0000265 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT, origin);
Brian Osman32342f02017-03-04 08:12:46 -0500266}
267
268void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
269 GrGpuResource* resource) {
270 ASSERT_SINGLE_OWNER
271 if (this->isAbandoned() || !resource) {
272 return;
273 }
274 resource->resourcePriv().setUniqueKey(key);
275}
276
277GrGpuResource* GrResourceProvider::findAndRefResourceByUniqueKey(const GrUniqueKey& key) {
278 ASSERT_SINGLE_OWNER
279 return this->isAbandoned() ? nullptr : fCache->findAndRefUniqueResource(key);
280}
281
282GrTexture* GrResourceProvider::findAndRefTextureByUniqueKey(const GrUniqueKey& key) {
283 ASSERT_SINGLE_OWNER
284 GrGpuResource* resource = this->findAndRefResourceByUniqueKey(key);
285 if (resource) {
286 GrTexture* texture = static_cast<GrSurface*>(resource)->asTexture();
287 SkASSERT(texture);
288 return texture;
289 }
Ben Wagnera93a14a2017-08-28 10:34:05 -0400290 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500291}
292
Robert Phillips646e4292017-06-13 12:44:56 -0400293void GrResourceProvider::assignUniqueKeyToTexture(const GrUniqueKey& key, GrTexture* texture) {
294 SkASSERT(key.isValid());
295 this->assignUniqueKeyToResource(key, texture);
296}
297
Robert Phillipsd3749482017-03-14 09:17:43 -0400298// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
299void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
300 ASSERT_SINGLE_OWNER
301 SkASSERT(key.isValid());
302 if (this->isAbandoned() || !proxy) {
303 return;
304 }
305
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400306 if (!proxy->instantiate(this)) {
Robert Phillipsd3749482017-03-14 09:17:43 -0400307 return;
308 }
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400309 GrTexture* texture = proxy->priv().peekTexture();
Robert Phillipsd3749482017-03-14 09:17:43 -0400310
311 this->assignUniqueKeyToResource(key, texture);
312}
313
314// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
Robert Phillips066f0202017-07-25 10:16:35 -0400315sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key,
316 GrSurfaceOrigin origin) {
Robert Phillipsd3749482017-03-14 09:17:43 -0400317 ASSERT_SINGLE_OWNER
318
319 sk_sp<GrTexture> texture(this->findAndRefTextureByUniqueKey(key));
320 if (!texture) {
321 return nullptr;
322 }
323
Robert Phillips066f0202017-07-25 10:16:35 -0400324 return GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
Robert Phillipsd3749482017-03-14 09:17:43 -0400325}
326
Chris Daltonff926502017-05-03 14:36:54 -0400327const GrBuffer* GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
cdalton397536c2016-03-25 12:15:03 -0700328 int patternSize,
329 int reps,
330 int vertCount,
331 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700332 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
333
Brian Salomon09d994e2016-12-21 11:14:46 -0500334 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
cdaltone2e71c22016-04-07 18:13:29 -0700335 GrBuffer* buffer = this->createBuffer(bufferSize, kIndex_GrBufferType, kStatic_GrAccessPattern,
cdalton397536c2016-03-25 12:15:03 -0700336 kNoPendingIO_Flag);
bsalomoned0bcad2015-05-04 10:36:42 -0700337 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700338 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700339 }
340 uint16_t* data = (uint16_t*) buffer->map();
halcanary96fcdcc2015-08-27 07:41:13 -0700341 bool useTempData = (nullptr == data);
bsalomoned0bcad2015-05-04 10:36:42 -0700342 if (useTempData) {
halcanary385fe4d2015-08-26 13:07:48 -0700343 data = new uint16_t[reps * patternSize];
bsalomoned0bcad2015-05-04 10:36:42 -0700344 }
345 for (int i = 0; i < reps; ++i) {
346 int baseIdx = i * patternSize;
347 uint16_t baseVert = (uint16_t)(i * vertCount);
348 for (int j = 0; j < patternSize; ++j) {
349 data[baseIdx+j] = baseVert + pattern[j];
350 }
351 }
352 if (useTempData) {
353 if (!buffer->updateData(data, bufferSize)) {
354 buffer->unref();
halcanary96fcdcc2015-08-27 07:41:13 -0700355 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700356 }
halcanary385fe4d2015-08-26 13:07:48 -0700357 delete[] data;
bsalomoned0bcad2015-05-04 10:36:42 -0700358 } else {
359 buffer->unmap();
360 }
361 this->assignUniqueKeyToResource(key, buffer);
362 return buffer;
363}
364
Brian Salomon34169692017-08-28 15:32:01 -0400365static constexpr int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
366
cdalton397536c2016-03-25 12:15:03 -0700367const GrBuffer* GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700368 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
369 static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
370
Chris Daltonff926502017-05-03 14:36:54 -0400371 return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
bsalomoned0bcad2015-05-04 10:36:42 -0700372}
373
Brian Salomon34169692017-08-28 15:32:01 -0400374int GrResourceProvider::QuadCountOfQuadBuffer() { return kMaxQuads; }
375
Robert Phillips67d52cf2017-06-05 13:38:13 -0400376sk_sp<GrPath> GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700377 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700378 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700379}
380
Robert Phillips67d52cf2017-06-05 13:38:13 -0400381sk_sp<GrPathRange> GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
382 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700383 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700384 return this->gpu()->pathRendering()->createPathRange(gen, style);
bsalomon706f08f2015-05-22 07:35:58 -0700385}
386
Robert Phillips67d52cf2017-06-05 13:38:13 -0400387sk_sp<GrPathRange> GrResourceProvider::createGlyphs(const SkTypeface* tf,
388 const SkScalerContextEffects& effects,
389 const SkDescriptor* desc,
390 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700391
392 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700393 return this->gpu()->pathRendering()->createGlyphs(tf, effects, desc, style);
bsalomon706f08f2015-05-22 07:35:58 -0700394}
395
cdaltone2e71c22016-04-07 18:13:29 -0700396GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700397 GrAccessPattern accessPattern, uint32_t flags,
398 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700399 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700400 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700401 }
cdaltond37fe762016-04-21 07:41:50 -0700402 if (kDynamic_GrAccessPattern != accessPattern) {
403 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
404 }
csmartdalton485a1202016-07-13 10:16:32 -0700405 if (!(flags & kRequireGpuMemory_Flag) &&
406 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
407 GrBufferTypeIsVertexOrIndex(intendedType) &&
408 kDynamic_GrAccessPattern == accessPattern) {
409 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
410 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700411
cdaltond37fe762016-04-21 07:41:50 -0700412 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400413 static const size_t MIN_SIZE = 1 << 12;
414 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700415
cdaltond37fe762016-04-21 07:41:50 -0700416 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700417 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700418 uint32_t scratchFlags = 0;
419 if (flags & kNoPendingIO_Flag) {
420 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
421 } else {
422 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
423 }
424 GrBuffer* buffer = static_cast<GrBuffer*>(
425 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
426 if (!buffer) {
427 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
428 if (!buffer) {
429 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700430 }
431 }
cdaltond37fe762016-04-21 07:41:50 -0700432 if (data) {
433 buffer->updateData(data, size);
434 }
csmartdalton485a1202016-07-13 10:16:32 -0700435 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700436 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800437}
438
egdanielec00d942015-09-14 12:56:10 -0700439GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
440 SkASSERT(rt);
441 if (rt->renderTargetPriv().getStencilAttachment()) {
442 return rt->renderTargetPriv().getStencilAttachment();
443 }
444
445 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
446 GrUniqueKey sbKey;
447
448 int width = rt->width();
449 int height = rt->height();
450#if 0
451 if (this->caps()->oversizedStencilSupport()) {
452 width = SkNextPow2(width);
453 height = SkNextPow2(height);
454 }
455#endif
egdanielec00d942015-09-14 12:56:10 -0700456 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
457 rt->numStencilSamples(), &sbKey);
458 GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>(
459 this->findAndRefResourceByUniqueKey(sbKey));
460 if (!stencil) {
461 // Need to try and create a new stencil
462 stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height);
463 if (stencil) {
Robert Phillipsf7cf81a2017-03-02 10:23:52 -0500464 this->assignUniqueKeyToResource(sbKey, stencil);
egdanielec00d942015-09-14 12:56:10 -0700465 }
466 }
467 if (rt->renderTargetPriv().attachStencilAttachment(stencil)) {
Robert Phillips95214472017-08-08 18:00:03 -0400468#ifdef SK_DEBUG
469 // Fill the SB with an inappropriate value. opLists that use the
470 // SB should clear it properly.
471 this->gpu()->clearStencil(rt, 0xFFFF);
472#endif
egdanielec00d942015-09-14 12:56:10 -0700473 }
474 }
475 return rt->renderTargetPriv().getStencilAttachment();
476}
477
bungeman6bd52842016-10-27 09:30:08 -0700478sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Robert Phillips7294b852017-08-01 13:51:44 +0000479 const GrBackendTexture& tex, GrSurfaceOrigin origin, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700480{
ericrkf7b8b8a2016-02-24 14:49:51 -0800481 if (this->isAbandoned()) {
482 return nullptr;
483 }
Robert Phillips7294b852017-08-01 13:51:44 +0000484 return this->gpu()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800485}
Greg Danield85f97d2017-03-07 13:37:21 -0500486
Greg Daniela5cb7812017-06-16 09:45:32 -0400487sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
488 return fGpu->makeSemaphore(isOwned);
489}
490
491sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
492 GrWrapOwnership ownership) {
493 ASSERT_SINGLE_OWNER
494 return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore, ownership);
Greg Danield85f97d2017-03-07 13:37:21 -0500495}
496
497void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
498 semaphore->resetGpu(fGpu);
499}
500
501void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
502 semaphore->resetGpu(nullptr);
503}