blob: d7b90873edcd9f8d13d7023ce5fe0cdd8f7b40b9 [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"
kkinnunencabe20c2015-06-01 01:37:26 -070015#include "GrPathRendering.h"
egdanielec00d942015-09-14 12:56:10 -070016#include "GrRenderTarget.h"
17#include "GrRenderTargetPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070018#include "GrResourceCache.h"
19#include "GrResourceKey.h"
Greg Danield85f97d2017-03-07 13:37:21 -050020#include "GrSemaphore.h"
egdanielec00d942015-09-14 12:56:10 -070021#include "GrStencilAttachment.h"
Robert Phillipsb66b42f2017-03-14 08:53:02 -040022#include "GrSurfaceProxyPriv.h"
Brian Osman32342f02017-03-04 08:12:46 -050023#include "GrTexturePriv.h"
24#include "../private/GrSingleOwner.h"
Robert Phillips45fdae12017-04-17 12:57:27 -040025#include "SkGr.h"
halcanary4dbbd042016-06-07 17:21:10 -070026#include "SkMathPriv.h"
bsalomoned0bcad2015-05-04 10:36:42 -070027
28GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
29
Brian Osman32342f02017-03-04 08:12:46 -050030const int GrResourceProvider::kMinScratchTextureSize = 16;
31
32#define ASSERT_SINGLE_OWNER \
33 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
34
joshualitt6d0872d2016-01-11 08:27:48 -080035GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner)
Brian Osman32342f02017-03-04 08:12:46 -050036 : fCache(cache)
37 , fGpu(gpu)
38#ifdef SK_DEBUG
39 , fSingleOwner(owner)
40#endif
41 {
Robert Phillips26c90e02017-03-14 14:39:29 -040042 fCaps = sk_ref_sp(fGpu->caps());
43
bsalomoned0bcad2015-05-04 10:36:42 -070044 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
45 fQuadIndexBufferKey = gQuadIndexBufferKey;
46}
47
Robert Phillipsf7a72612017-03-31 10:03:45 -040048bool GrResourceProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
Robert Phillipsb66b42f2017-03-14 08:53:02 -040049 return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
50}
Brian Osman32342f02017-03-04 08:12:46 -050051
Robert Phillipse78b7252017-04-06 07:59:41 -040052// MDB TODO: this should probably be a factory on GrSurfaceProxy
53sk_sp<GrTextureProxy> GrResourceProvider::createMipMappedTexture(
54 const GrSurfaceDesc& desc,
55 SkBudgeted budgeted,
56 const GrMipLevel* texels,
57 int mipLevelCount,
Robert Phillipsa4c41b32017-03-15 13:02:45 -040058 SkDestinationSurfaceColorMode mipColorMode) {
Brian Osman32342f02017-03-04 08:12:46 -050059 ASSERT_SINGLE_OWNER
60
Robert Phillips1119dc32017-04-11 12:54:57 -040061 if (!mipLevelCount) {
62 if (texels) {
63 return nullptr;
64 }
65 return GrSurfaceProxy::MakeDeferred(this, desc, budgeted, nullptr, 0);
Robert Phillips45fdae12017-04-17 12:57:27 -040066 } else if (1 == mipLevelCount) {
67 if (!texels) {
68 return nullptr;
69 }
70 return this->createTextureProxy(desc, budgeted, texels[0]);
Robert Phillips1119dc32017-04-11 12:54:57 -040071 }
72
Brian Osman32342f02017-03-04 08:12:46 -050073 if (this->isAbandoned()) {
74 return nullptr;
75 }
Robert Phillips1119dc32017-04-11 12:54:57 -040076
Brian Osman32342f02017-03-04 08:12:46 -050077 if (mipLevelCount > 1 && GrPixelConfigIsSint(desc.fConfig)) {
78 return nullptr;
79 }
80 if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) &&
81 !fGpu->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
82 return nullptr;
83 }
Brian Osman32342f02017-03-04 08:12:46 -050084
85 SkTArray<GrMipLevel> texelsShallowCopy(mipLevelCount);
86 for (int i = 0; i < mipLevelCount; ++i) {
Robert Phillips45fdae12017-04-17 12:57:27 -040087 if (!texels[i].fPixels) {
88 return nullptr;
89 }
90
Brian Osman32342f02017-03-04 08:12:46 -050091 texelsShallowCopy.push_back(texels[i]);
92 }
Robert Phillipse78b7252017-04-06 07:59:41 -040093 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texelsShallowCopy));
94 if (tex) {
95 tex->texturePriv().setMipColorMode(mipColorMode);
Robert Phillipsa4c41b32017-03-15 13:02:45 -040096 }
Robert Phillipse78b7252017-04-06 07:59:41 -040097
98 return GrSurfaceProxy::MakeWrapped(std::move(tex));
Brian Osman32342f02017-03-04 08:12:46 -050099}
100
Robert Phillips45fdae12017-04-17 12:57:27 -0400101sk_sp<GrTexture> GrResourceProvider::getExactScratch(const GrSurfaceDesc& desc,
102 SkBudgeted budgeted, uint32_t flags) {
103
104 flags |= kExact_Flag | kNoCreate_Flag;
105 sk_sp<GrTexture> tex(this->refScratchTexture(desc, flags));
106 if (tex && SkBudgeted::kNo == budgeted) {
107 tex->resourcePriv().makeUnbudgeted();
108 }
109
110 return tex;
111}
112
113static bool make_info(int w, int h, GrPixelConfig config, SkImageInfo* ii) {
114 SkColorType colorType;
115 if (!GrPixelConfigToColorType(config, &colorType)) {
116 return false;
117 }
118
119 *ii = SkImageInfo::Make(w, h, colorType, kUnknown_SkAlphaType, nullptr);
120 return true;
121}
122
123sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
124 SkBudgeted budgeted,
125 const GrMipLevel& mipLevel) {
Robert Phillips774831a2017-04-20 10:19:33 -0400126 ASSERT_SINGLE_OWNER
127
128 if (this->isAbandoned()) {
129 return nullptr;
130 }
131
Robert Phillips45fdae12017-04-17 12:57:27 -0400132 if (!mipLevel.fPixels) {
133 return nullptr;
134 }
135
136 GrContext* context = fGpu->getContext();
137
138 if (!GrPixelConfigIsCompressed(desc.fConfig)) {
139 SkImageInfo srcInfo;
140
141 if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
142 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
143 sk_sp<GrSurfaceContext> sContext =
144 context->contextPriv().makeWrappedSurfaceContext(std::move(tex));
145 if (sContext) {
146 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
147 return sContext->asTextureProxyRef();
148 }
149 }
150 }
151 }
152
153 SkTArray<GrMipLevel> texels(1);
154 texels.push_back(mipLevel);
155
156 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, texels));
157 return GrSurfaceProxy::MakeWrapped(std::move(tex));
158}
159
160
Robert Phillipse78b7252017-04-06 07:59:41 -0400161sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
162 uint32_t flags) {
163 ASSERT_SINGLE_OWNER
164
165 if (this->isAbandoned()) {
166 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500167 }
Robert Phillipse78b7252017-04-06 07:59:41 -0400168
169 if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) &&
170 !fGpu->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
171 return nullptr;
172 }
173
174 if (!GrPixelConfigIsCompressed(desc.fConfig)) {
Robert Phillips45fdae12017-04-17 12:57:27 -0400175 sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, flags);
Robert Phillipse78b7252017-04-06 07:59:41 -0400176 if (tex) {
Robert Phillipse78b7252017-04-06 07:59:41 -0400177 return tex;
178 }
179 }
180
181 sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted));
182 return tex;
Brian Osman32342f02017-03-04 08:12:46 -0500183}
184
185GrTexture* GrResourceProvider::createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
186 ASSERT_SINGLE_OWNER
187 SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
Brian Osman32342f02017-03-04 08:12:46 -0500188
Brian Osman32342f02017-03-04 08:12:46 -0500189 if (this->isAbandoned()) {
190 return nullptr;
191 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400192
Brian Osman32342f02017-03-04 08:12:46 -0500193 // Currently we don't recycle compressed textures as scratch.
194 if (GrPixelConfigIsCompressed(desc.fConfig)) {
195 return nullptr;
Brian Osman32342f02017-03-04 08:12:46 -0500196 }
Robert Phillips1119dc32017-04-11 12:54:57 -0400197
198 return this->refScratchTexture(desc, flags);
Brian Osman32342f02017-03-04 08:12:46 -0500199}
200
201GrTexture* GrResourceProvider::refScratchTexture(const GrSurfaceDesc& inDesc,
202 uint32_t flags) {
203 ASSERT_SINGLE_OWNER
204 SkASSERT(!this->isAbandoned());
205 SkASSERT(!GrPixelConfigIsCompressed(inDesc.fConfig));
Robert Phillips78de2122017-04-26 07:44:26 -0400206 SkASSERT(inDesc.fWidth > 0 && inDesc.fHeight > 0);
Brian Osman32342f02017-03-04 08:12:46 -0500207
208 SkTCopyOnFirstWrite<GrSurfaceDesc> desc(inDesc);
209
210 if (fGpu->caps()->reuseScratchTextures() || (desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
211 if (!(kExact_Flag & flags)) {
212 // bin by pow2 with a reasonable min
213 GrSurfaceDesc* wdesc = desc.writable();
214 wdesc->fWidth = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fWidth));
215 wdesc->fHeight = SkTMax(kMinScratchTextureSize, GrNextPow2(desc->fHeight));
216 }
217
218 GrScratchKey key;
219 GrTexturePriv::ComputeScratchKey(*desc, &key);
220 uint32_t scratchFlags = 0;
221 if (kNoPendingIO_Flag & flags) {
222 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
223 } else if (!(desc->fFlags & kRenderTarget_GrSurfaceFlag)) {
224 // If it is not a render target then it will most likely be populated by
225 // writePixels() which will trigger a flush if the texture has pending IO.
226 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
227 }
228 GrGpuResource* resource = fCache->findAndRefScratchResource(key,
229 GrSurface::WorstCaseSize(*desc),
230 scratchFlags);
231 if (resource) {
232 GrSurface* surface = static_cast<GrSurface*>(resource);
Brian Osman32342f02017-03-04 08:12:46 -0500233 return surface->asTexture();
234 }
235 }
236
237 if (!(kNoCreate_Flag & flags)) {
238 return fGpu->createTexture(*desc, SkBudgeted::kYes);
239 }
240
241 return nullptr;
242}
243
Greg Daniel7ef28f32017-04-20 16:41:55 +0000244sk_sp<GrTexture> GrResourceProvider::wrapBackendTexture(const GrBackendTexture& tex,
245 GrSurfaceOrigin origin,
246 GrBackendTextureFlags flags,
247 int sampleCnt,
Brian Osman32342f02017-03-04 08:12:46 -0500248 GrWrapOwnership ownership) {
249 ASSERT_SINGLE_OWNER
250 if (this->isAbandoned()) {
251 return nullptr;
252 }
Greg Daniel7ef28f32017-04-20 16:41:55 +0000253 return fGpu->wrapBackendTexture(tex, origin, flags, sampleCnt, ownership);
Brian Osman32342f02017-03-04 08:12:46 -0500254}
255
256sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendRenderTarget(
Greg Danielbcf612b2017-05-01 13:50:58 +0000257 const GrBackendRenderTarget& backendRT, GrSurfaceOrigin origin)
Brian Osman32342f02017-03-04 08:12:46 -0500258{
259 ASSERT_SINGLE_OWNER
Greg Danielbcf612b2017-05-01 13:50:58 +0000260 return this->isAbandoned() ? nullptr : fGpu->wrapBackendRenderTarget(backendRT, origin);
Brian Osman32342f02017-03-04 08:12:46 -0500261}
262
263void GrResourceProvider::assignUniqueKeyToResource(const GrUniqueKey& key,
264 GrGpuResource* resource) {
265 ASSERT_SINGLE_OWNER
266 if (this->isAbandoned() || !resource) {
267 return;
268 }
269 resource->resourcePriv().setUniqueKey(key);
270}
271
272GrGpuResource* GrResourceProvider::findAndRefResourceByUniqueKey(const GrUniqueKey& key) {
273 ASSERT_SINGLE_OWNER
274 return this->isAbandoned() ? nullptr : fCache->findAndRefUniqueResource(key);
275}
276
277GrTexture* GrResourceProvider::findAndRefTextureByUniqueKey(const GrUniqueKey& key) {
278 ASSERT_SINGLE_OWNER
279 GrGpuResource* resource = this->findAndRefResourceByUniqueKey(key);
280 if (resource) {
281 GrTexture* texture = static_cast<GrSurface*>(resource)->asTexture();
282 SkASSERT(texture);
283 return texture;
284 }
285 return NULL;
286}
287
Robert Phillipsd3749482017-03-14 09:17:43 -0400288// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
289void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
290 ASSERT_SINGLE_OWNER
291 SkASSERT(key.isValid());
292 if (this->isAbandoned() || !proxy) {
293 return;
294 }
295
296 GrTexture* texture = proxy->instantiate(this);
297 if (!texture) {
298 return;
299 }
300
301 this->assignUniqueKeyToResource(key, texture);
302}
303
304// MDB TODO (caching): this side-steps the issue of texture proxies with unique IDs
305sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key) {
306 ASSERT_SINGLE_OWNER
307
308 sk_sp<GrTexture> texture(this->findAndRefTextureByUniqueKey(key));
309 if (!texture) {
310 return nullptr;
311 }
312
313 return GrSurfaceProxy::MakeWrapped(std::move(texture));
314}
315
cdalton397536c2016-03-25 12:15:03 -0700316const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
317 int patternSize,
318 int reps,
319 int vertCount,
320 const GrUniqueKey& key) {
bsalomoned0bcad2015-05-04 10:36:42 -0700321 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
322
Brian Salomon09d994e2016-12-21 11:14:46 -0500323 // This is typically used in GrMeshDrawOps, so we assume kNoPendingIO.
cdaltone2e71c22016-04-07 18:13:29 -0700324 GrBuffer* buffer = this->createBuffer(bufferSize, kIndex_GrBufferType, kStatic_GrAccessPattern,
cdalton397536c2016-03-25 12:15:03 -0700325 kNoPendingIO_Flag);
bsalomoned0bcad2015-05-04 10:36:42 -0700326 if (!buffer) {
halcanary96fcdcc2015-08-27 07:41:13 -0700327 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700328 }
329 uint16_t* data = (uint16_t*) buffer->map();
halcanary96fcdcc2015-08-27 07:41:13 -0700330 bool useTempData = (nullptr == data);
bsalomoned0bcad2015-05-04 10:36:42 -0700331 if (useTempData) {
halcanary385fe4d2015-08-26 13:07:48 -0700332 data = new uint16_t[reps * patternSize];
bsalomoned0bcad2015-05-04 10:36:42 -0700333 }
334 for (int i = 0; i < reps; ++i) {
335 int baseIdx = i * patternSize;
336 uint16_t baseVert = (uint16_t)(i * vertCount);
337 for (int j = 0; j < patternSize; ++j) {
338 data[baseIdx+j] = baseVert + pattern[j];
339 }
340 }
341 if (useTempData) {
342 if (!buffer->updateData(data, bufferSize)) {
343 buffer->unref();
halcanary96fcdcc2015-08-27 07:41:13 -0700344 return nullptr;
bsalomoned0bcad2015-05-04 10:36:42 -0700345 }
halcanary385fe4d2015-08-26 13:07:48 -0700346 delete[] data;
bsalomoned0bcad2015-05-04 10:36:42 -0700347 } else {
348 buffer->unmap();
349 }
350 this->assignUniqueKeyToResource(key, buffer);
351 return buffer;
352}
353
cdalton397536c2016-03-25 12:15:03 -0700354const GrBuffer* GrResourceProvider::createQuadIndexBuffer() {
bsalomoned0bcad2015-05-04 10:36:42 -0700355 static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
356 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
357 static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
358
359 return this->createInstancedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
360}
361
bsalomon6663acf2016-05-10 09:14:17 -0700362GrPath* GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700363 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700364 return this->gpu()->pathRendering()->createPath(path, style);
bsalomon706f08f2015-05-22 07:35:58 -0700365}
366
367GrPathRange* GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
bsalomon6663acf2016-05-10 09:14:17 -0700368 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700369 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700370 return this->gpu()->pathRendering()->createPathRange(gen, style);
bsalomon706f08f2015-05-22 07:35:58 -0700371}
372
reeda9322c22016-04-12 06:47:05 -0700373GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf,
374 const SkScalerContextEffects& effects,
375 const SkDescriptor* desc,
bsalomon6663acf2016-05-10 09:14:17 -0700376 const GrStyle& style) {
bsalomon706f08f2015-05-22 07:35:58 -0700377
378 SkASSERT(this->gpu()->pathRendering());
bsalomon6663acf2016-05-10 09:14:17 -0700379 return this->gpu()->pathRendering()->createGlyphs(tf, effects, desc, style);
bsalomon706f08f2015-05-22 07:35:58 -0700380}
381
cdaltone2e71c22016-04-07 18:13:29 -0700382GrBuffer* GrResourceProvider::createBuffer(size_t size, GrBufferType intendedType,
cdalton1bf3e712016-04-19 10:00:02 -0700383 GrAccessPattern accessPattern, uint32_t flags,
384 const void* data) {
robertphillips1b8e1b52015-06-24 06:54:10 -0700385 if (this->isAbandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700386 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700387 }
cdaltond37fe762016-04-21 07:41:50 -0700388 if (kDynamic_GrAccessPattern != accessPattern) {
389 return this->gpu()->createBuffer(size, intendedType, accessPattern, data);
390 }
csmartdalton485a1202016-07-13 10:16:32 -0700391 if (!(flags & kRequireGpuMemory_Flag) &&
392 this->gpu()->caps()->preferClientSideDynamicBuffers() &&
393 GrBufferTypeIsVertexOrIndex(intendedType) &&
394 kDynamic_GrAccessPattern == accessPattern) {
395 return GrBuffer::CreateCPUBacked(this->gpu(), size, intendedType, data);
396 }
robertphillips1b8e1b52015-06-24 06:54:10 -0700397
cdaltond37fe762016-04-21 07:41:50 -0700398 // bin by pow2 with a reasonable min
Robert Phillips9e380472016-10-28 12:15:03 -0400399 static const size_t MIN_SIZE = 1 << 12;
400 size_t allocSize = SkTMax(MIN_SIZE, GrNextSizePow2(size));
robertphillips1b8e1b52015-06-24 06:54:10 -0700401
cdaltond37fe762016-04-21 07:41:50 -0700402 GrScratchKey key;
csmartdalton485a1202016-07-13 10:16:32 -0700403 GrBuffer::ComputeScratchKeyForDynamicVBO(allocSize, intendedType, &key);
cdaltond37fe762016-04-21 07:41:50 -0700404 uint32_t scratchFlags = 0;
405 if (flags & kNoPendingIO_Flag) {
406 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
407 } else {
408 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
409 }
410 GrBuffer* buffer = static_cast<GrBuffer*>(
411 this->cache()->findAndRefScratchResource(key, allocSize, scratchFlags));
412 if (!buffer) {
413 buffer = this->gpu()->createBuffer(allocSize, intendedType, kDynamic_GrAccessPattern);
414 if (!buffer) {
415 return nullptr;
robertphillips1b8e1b52015-06-24 06:54:10 -0700416 }
417 }
cdaltond37fe762016-04-21 07:41:50 -0700418 if (data) {
419 buffer->updateData(data, size);
420 }
csmartdalton485a1202016-07-13 10:16:32 -0700421 SkASSERT(!buffer->isCPUBacked()); // We should only cache real VBOs.
cdaltond37fe762016-04-21 07:41:50 -0700422 return buffer;
jvanverth17aa0472016-01-05 10:41:27 -0800423}
424
egdanielec00d942015-09-14 12:56:10 -0700425GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
426 SkASSERT(rt);
427 if (rt->renderTargetPriv().getStencilAttachment()) {
428 return rt->renderTargetPriv().getStencilAttachment();
429 }
430
431 if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
432 GrUniqueKey sbKey;
433
434 int width = rt->width();
435 int height = rt->height();
436#if 0
437 if (this->caps()->oversizedStencilSupport()) {
438 width = SkNextPow2(width);
439 height = SkNextPow2(height);
440 }
441#endif
442 bool newStencil = false;
443 GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
444 rt->numStencilSamples(), &sbKey);
445 GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>(
446 this->findAndRefResourceByUniqueKey(sbKey));
447 if (!stencil) {
448 // Need to try and create a new stencil
449 stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height);
450 if (stencil) {
Robert Phillipsf7cf81a2017-03-02 10:23:52 -0500451 this->assignUniqueKeyToResource(sbKey, stencil);
egdanielec00d942015-09-14 12:56:10 -0700452 newStencil = true;
453 }
454 }
455 if (rt->renderTargetPriv().attachStencilAttachment(stencil)) {
456 if (newStencil) {
457 // Right now we're clearing the stencil attachment here after it is
bsalomon7ea33f52015-11-22 14:51:00 -0800458 // attached to a RT for the first time. When we start matching
egdanielec00d942015-09-14 12:56:10 -0700459 // stencil buffers with smaller color targets this will no longer
460 // be correct because it won't be guaranteed to clear the entire
461 // sb.
462 // We used to clear down in the GL subclass using a special purpose
463 // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
464 // FBO status.
465 this->gpu()->clearStencil(rt);
466 }
467 }
468 }
469 return rt->renderTargetPriv().getStencilAttachment();
470}
471
bungeman6bd52842016-10-27 09:30:08 -0700472sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000473 const GrBackendTexture& tex, GrSurfaceOrigin origin, int sampleCnt)
bungeman6bd52842016-10-27 09:30:08 -0700474{
ericrkf7b8b8a2016-02-24 14:49:51 -0800475 if (this->isAbandoned()) {
476 return nullptr;
477 }
Greg Daniel7ef28f32017-04-20 16:41:55 +0000478 return this->gpu()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt);
ericrkf7b8b8a2016-02-24 14:49:51 -0800479}
Greg Danield85f97d2017-03-07 13:37:21 -0500480
481sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore() {
482 return fGpu->makeSemaphore();
483}
484
485void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
486 semaphore->resetGpu(fGpu);
487}
488
489void GrResourceProvider::releaseOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
490 semaphore->resetGpu(nullptr);
491}