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