1ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon/* 2ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon * Copyright 2015 Google Inc. 3ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon * 4ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon * Use of this source code is governed by a BSD-style license that can be 5ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon * found in the LICENSE file. 6ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon */ 7ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 8ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrResourceProvider.h" 9ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 10ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrGpu.h" 11cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#include "GrIndexBuffer.h" 12cabe20cafd5f091a68bbc2c0c48755ba9b61b0b7kkinnunen#include "GrPathRendering.h" 13ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel#include "GrRenderTarget.h" 14ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel#include "GrRenderTargetPriv.h" 15ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrResourceCache.h" 16ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrResourceKey.h" 17ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel#include "GrStencilAttachment.h" 18ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrVertexBuffer.h" 19ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 20ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonGR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); 21ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 226d0872d9bd97de5301214a258e141dd5fbeecffcjoshualittGrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner) 236d0872d9bd97de5301214a258e141dd5fbeecffcjoshualitt : INHERITED(gpu, cache, owner) { 24ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); 25ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon fQuadIndexBufferKey = gQuadIndexBufferKey; 26ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon} 27ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 28ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonconst GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern, 29ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon int patternSize, 30ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon int reps, 31ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon int vertCount, 32ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon const GrUniqueKey& key) { 33ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon size_t bufferSize = patternSize * reps * sizeof(uint16_t); 34ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 35eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon // This is typically used in GrBatchs, so we assume kNoPendingIO. 36eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon GrIndexBuffer* buffer = this->createIndexBuffer(bufferSize, kStatic_BufferUsage, 37eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon kNoPendingIO_Flag); 38ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (!buffer) { 3996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 40ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 41ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon uint16_t* data = (uint16_t*) buffer->map(); 4296fcdcc219d2a0d3579719b84b28bede76efba64halcanary bool useTempData = (nullptr == data); 43ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (useTempData) { 44385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary data = new uint16_t[reps * patternSize]; 45ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 46ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon for (int i = 0; i < reps; ++i) { 47ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon int baseIdx = i * patternSize; 48ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon uint16_t baseVert = (uint16_t)(i * vertCount); 49ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon for (int j = 0; j < patternSize; ++j) { 50ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon data[baseIdx+j] = baseVert + pattern[j]; 51ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 52ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 53ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (useTempData) { 54ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (!buffer->updateData(data, bufferSize)) { 55ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon buffer->unref(); 5696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 57ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 58385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete[] data; 59ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } else { 60ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon buffer->unmap(); 61ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 62ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon this->assignUniqueKeyToResource(key, buffer); 63ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return buffer; 64ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon} 65ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 66ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonconst GrIndexBuffer* GrResourceProvider::createQuadIndexBuffer() { 67ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1; 68ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_STATIC_ASSERT(4 * kMaxQuads <= 65535); 69ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 }; 70ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 71ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return this->createInstancedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey); 72ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon} 73ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 74706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomonGrPath* GrResourceProvider::createPath(const SkPath& path, const GrStrokeInfo& stroke) { 75706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon SkASSERT(this->gpu()->pathRendering()); 76706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon return this->gpu()->pathRendering()->createPath(path, stroke); 77706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon} 78706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon 79706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomonGrPathRange* GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen, 80706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon const GrStrokeInfo& stroke) { 81706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon SkASSERT(this->gpu()->pathRendering()); 82706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon return this->gpu()->pathRendering()->createPathRange(gen, stroke); 83706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon} 84706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon 85706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomonGrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDescriptor* desc, 86706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon const GrStrokeInfo& stroke) { 87706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon 88706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon SkASSERT(this->gpu()->pathRendering()); 89706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke); 90706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon} 91706f08fbcb7f5275235784f67bd7d188ad04eef2bsalomon 92eae6200acbec2255ac00ab363ffbe16758ec9076bsalomonGrIndexBuffer* GrResourceProvider::createIndexBuffer(size_t size, BufferUsage usage, 93eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon uint32_t flags) { 941b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (this->isAbandoned()) { 9596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 961b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 971b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips 98eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag); 99eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon bool dynamic = kDynamic_BufferUsage == usage; 1001b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (dynamic) { 1011b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips // bin by pow2 with a reasonable min 1021b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips static const uint32_t MIN_SIZE = 1 << 12; 1031b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size))); 1041b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips 1051b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips GrScratchKey key; 106eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon GrIndexBuffer::ComputeScratchKey(size, true, &key); 1071b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips uint32_t scratchFlags = 0; 108eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon if (noPendingIO) { 1091b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; 1101b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } else { 1111b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag; 1121b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1136e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, size, scratchFlags); 1141b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (resource) { 1151b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips return static_cast<GrIndexBuffer*>(resource); 1161b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1171b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 118eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon return this->gpu()->createIndexBuffer(size, dynamic); 1191b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips} 1201b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips 121eae6200acbec2255ac00ab363ffbe16758ec9076bsalomonGrVertexBuffer* GrResourceProvider::createVertexBuffer(size_t size, BufferUsage usage, 122eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon uint32_t flags) { 1231b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (this->isAbandoned()) { 12496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1251b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1261b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips 127eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag); 128eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon bool dynamic = kDynamic_BufferUsage == usage; 1291b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (dynamic) { 1301b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips // bin by pow2 with a reasonable min 131eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon static const uint32_t MIN_SIZE = 1 << 12; 1321b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size))); 1331b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips 1341b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips GrScratchKey key; 135eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon GrVertexBuffer::ComputeScratchKey(size, true, &key); 1361b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips uint32_t scratchFlags = 0; 137eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon if (noPendingIO) { 1381b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag; 1391b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } else { 1401b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag; 1411b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1426e83ac778f8f90939abe3aee3ea865428dff592frobertphillips GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, size, scratchFlags); 1431b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips if (resource) { 1441b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips return static_cast<GrVertexBuffer*>(resource); 1451b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1461b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips } 1471b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips return this->gpu()->createVertexBuffer(size, dynamic); 1481b8e1b5c499e31a671232c8ccb10e778e0d8b154robertphillips} 149b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt 15017aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverthGrTransferBuffer* GrResourceProvider::createTransferBuffer(size_t size, TransferType type, 15117aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth uint32_t flags) { 15217aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth if (this->isAbandoned()) { 15317aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return nullptr; 15417aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth } 15517aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 15617aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth //bool noPendingIO = SkToBool(flags & kNoPendingIO_Flag); 15717aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth return this->gpu()->createTransferBuffer(size, type); 15817aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth} 15917aa047066eaaa56637c4c2b93c8c4c374127dbfjvanverth 160b356cbc765468e2594fca9ec6e5476a3da145d26joshualittGrBatchAtlas* GrResourceProvider::createAtlas(GrPixelConfig config, 161b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt int width, int height, 162b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt int numPlotsX, int numPlotsY, 163b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt GrBatchAtlas::EvictionFunc func, void* data) { 164b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt GrSurfaceDesc desc; 165b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt desc.fFlags = kNone_GrSurfaceFlags; 166b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt desc.fWidth = width; 167b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt desc.fHeight = height; 168b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt desc.fConfig = config; 169b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt 170b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt // We don't want to flush the context so we claim we're in the middle of flushing so as to 171b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt // guarantee we do not recieve a texture with pending IO 1726950de6c4166fabb35e6c756fc009e0cf1c47819halcanary // TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156) 173b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag; 174b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt GrTexture* texture = this->createApproxTexture(desc, kFlags); 175b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt if (!texture) { 17696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 177b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt } 1788377e80951326f94714b31ede711cd0757d37fcdjoshualitt GrBatchAtlas* atlas = new GrBatchAtlas(texture, numPlotsX, numPlotsY); 1798377e80951326f94714b31ede711cd0757d37fcdjoshualitt atlas->registerEvictionCallback(func, data); 1808377e80951326f94714b31ede711cd0757d37fcdjoshualitt return atlas; 181b356cbc765468e2594fca9ec6e5476a3da145d26joshualitt} 182ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel 183ec00d94199fad7723b5987b86c1abef8ddafe2d8egdanielGrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) { 184ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel SkASSERT(rt); 185ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (rt->renderTargetPriv().getStencilAttachment()) { 186ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel return rt->renderTargetPriv().getStencilAttachment(); 187ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 188ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel 189ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) { 190ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel GrUniqueKey sbKey; 191ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel 192ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel int width = rt->width(); 193ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel int height = rt->height(); 194ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel#if 0 195ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (this->caps()->oversizedStencilSupport()) { 196ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel width = SkNextPow2(width); 197ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel height = SkNextPow2(height); 198ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 199ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel#endif 200ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel bool newStencil = false; 201ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height, 202ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel rt->numStencilSamples(), &sbKey); 203ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>( 204ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel this->findAndRefResourceByUniqueKey(sbKey)); 205ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (!stencil) { 206ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // Need to try and create a new stencil 207ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height); 208ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (stencil) { 209ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel stencil->resourcePriv().setUniqueKey(sbKey); 210ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel newStencil = true; 211ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 212ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 213ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (rt->renderTargetPriv().attachStencilAttachment(stencil)) { 214ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel if (newStencil) { 215ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // Right now we're clearing the stencil attachment here after it is 2167ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon // attached to a RT for the first time. When we start matching 217ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // stencil buffers with smaller color targets this will no longer 218ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // be correct because it won't be guaranteed to clear the entire 219ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // sb. 220ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // We used to clear down in the GL subclass using a special purpose 221ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported 222ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel // FBO status. 223ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel this->gpu()->clearStencil(rt); 224ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 225ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 226ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel } 227ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel return rt->renderTargetPriv().getStencilAttachment(); 228ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel} 229ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel 230f7b8b8affec91fcfab0d79199e466c16c254fe56ericrkGrRenderTarget* GrResourceProvider::wrapBackendTextureAsRenderTarget( 231f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk const GrBackendTextureDesc& desc, GrWrapOwnership ownership) { 232f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk if (this->isAbandoned()) { 233f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk return nullptr; 234f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk } 235f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk return this->gpu()->wrapBackendTextureAsRenderTarget(desc, ownership); 236f7b8b8affec91fcfab0d79199e466c16c254fe56ericrk} 237ec00d94199fad7723b5987b86c1abef8ddafe2d8egdaniel 238