blob: 3c447bded6d3d173610352e66e2638db455c7a66 [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
10#include "GrGpu.h"
kkinnunencabe20c2015-06-01 01:37:26 -070011#include "GrIndexBuffer.h"
12#include "GrPathRendering.h"
bsalomoned0bcad2015-05-04 10:36:42 -070013#include "GrResourceCache.h"
14#include "GrResourceKey.h"
15#include "GrVertexBuffer.h"
16
17GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
18
19GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache) : INHERITED(gpu, cache) {
20 GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey);
21 fQuadIndexBufferKey = gQuadIndexBufferKey;
22}
23
24const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
25 int patternSize,
26 int reps,
27 int vertCount,
28 const GrUniqueKey& key) {
29 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
30
robertphillips1b8e1b52015-06-24 06:54:10 -070031 GrIndexBuffer* buffer = this->getIndexBuffer(bufferSize, /* dynamic = */ false, true);
bsalomoned0bcad2015-05-04 10:36:42 -070032 if (!buffer) {
33 return NULL;
34 }
35 uint16_t* data = (uint16_t*) buffer->map();
36 bool useTempData = (NULL == data);
37 if (useTempData) {
38 data = SkNEW_ARRAY(uint16_t, reps * patternSize);
39 }
40 for (int i = 0; i < reps; ++i) {
41 int baseIdx = i * patternSize;
42 uint16_t baseVert = (uint16_t)(i * vertCount);
43 for (int j = 0; j < patternSize; ++j) {
44 data[baseIdx+j] = baseVert + pattern[j];
45 }
46 }
47 if (useTempData) {
48 if (!buffer->updateData(data, bufferSize)) {
49 buffer->unref();
50 return NULL;
51 }
52 SkDELETE_ARRAY(data);
53 } else {
54 buffer->unmap();
55 }
56 this->assignUniqueKeyToResource(key, buffer);
57 return buffer;
58}
59
60const GrIndexBuffer* GrResourceProvider::createQuadIndexBuffer() {
61 static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1;
62 GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
63 static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
64
65 return this->createInstancedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
66}
67
bsalomon706f08f2015-05-22 07:35:58 -070068GrPath* GrResourceProvider::createPath(const SkPath& path, const GrStrokeInfo& stroke) {
69 SkASSERT(this->gpu()->pathRendering());
70 return this->gpu()->pathRendering()->createPath(path, stroke);
71}
72
73GrPathRange* GrResourceProvider::createPathRange(GrPathRange::PathGenerator* gen,
74 const GrStrokeInfo& stroke) {
75 SkASSERT(this->gpu()->pathRendering());
76 return this->gpu()->pathRendering()->createPathRange(gen, stroke);
77}
78
79GrPathRange* GrResourceProvider::createGlyphs(const SkTypeface* tf, const SkDescriptor* desc,
80 const GrStrokeInfo& stroke) {
81
82 SkASSERT(this->gpu()->pathRendering());
83 return this->gpu()->pathRendering()->createGlyphs(tf, desc, stroke);
84}
85
robertphillips1b8e1b52015-06-24 06:54:10 -070086GrIndexBuffer* GrResourceProvider::getIndexBuffer(size_t size, bool dynamic,
87 bool calledDuringFlush) {
88 if (this->isAbandoned()) {
89 return NULL;
90 }
91
92 if (dynamic) {
93 // bin by pow2 with a reasonable min
94 static const uint32_t MIN_SIZE = 1 << 12;
95 size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
96
97 GrScratchKey key;
98 GrIndexBuffer::ComputeScratchKey(size, dynamic, &key);
99 uint32_t scratchFlags = 0;
100 if (calledDuringFlush) {
101 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
102 } else {
103 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
104 }
105 GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, scratchFlags);
106 if (resource) {
107 return static_cast<GrIndexBuffer*>(resource);
108 }
109 }
110
111 return this->gpu()->createIndexBuffer(size, dynamic);
112}
113
114GrVertexBuffer* GrResourceProvider::getVertexBuffer(size_t size, bool dynamic,
115 bool calledDuringFlush) {
116 if (this->isAbandoned()) {
117 return NULL;
118 }
119
120 if (dynamic) {
121 // bin by pow2 with a reasonable min
122 static const uint32_t MIN_SIZE = 1 << 15;
123 size = SkTMax(MIN_SIZE, GrNextPow2(SkToUInt(size)));
124
125 GrScratchKey key;
126 GrVertexBuffer::ComputeScratchKey(size, dynamic, &key);
127 uint32_t scratchFlags = 0;
128 if (calledDuringFlush) {
129 scratchFlags = GrResourceCache::kRequireNoPendingIO_ScratchFlag;
130 } else {
131 scratchFlags = GrResourceCache::kPreferNoPendingIO_ScratchFlag;
132 }
133 GrGpuResource* resource = this->cache()->findAndRefScratchResource(key, scratchFlags);
134 if (resource) {
135 return static_cast<GrVertexBuffer*>(resource);
136 }
137 }
138
139 return this->gpu()->createVertexBuffer(size, dynamic);
140}