1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrResourceProvider_DEFINED
#define GrResourceProvider_DEFINED
#include "GrBuffer.h"
#include "GrDrawOpAtlas.h"
#include "GrGpu.h"
#include "GrPathRange.h"
#include "GrTextureProvider.h"
class GrDrawOpAtlas;
class GrPath;
class GrRenderTarget;
class GrSingleOwner;
class GrStencilAttachment;
class GrStyle;
class SkDescriptor;
class SkPath;
class SkTypeface;
/**
* An extension of the texture provider for arbitrary resource types. This class is intended for
* use within the Gr code base, not by clients or extensions (e.g. third party GrProcessor
* derivatives).
*
* This currently inherits from GrTextureProvider non-publically to force callers to provider
* make a flags (pendingIO) decision and not use the GrTP methods that don't take flags. This
* can be relaxed once https://bug.skia.org/4156 is fixed.
*/
class GrResourceProvider : protected GrTextureProvider {
public:
GrResourceProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* owner);
template <typename T> T* findAndRefTByUniqueKey(const GrUniqueKey& key) {
return static_cast<T*>(this->findAndRefResourceByUniqueKey(key));
}
/**
* Either finds and refs, or creates an index buffer for instanced drawing with a specific
* pattern if the index buffer is not found. If the return is non-null, the caller owns
* a ref on the returned GrBuffer.
*
* @param pattern the pattern of indices to repeat
* @param patternSize size in bytes of the pattern
* @param reps number of times to repeat the pattern
* @param vertCount number of vertices the pattern references
* @param key Key to be assigned to the index buffer.
*
* @return The index buffer if successful, otherwise nullptr.
*/
const GrBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,
int vertCount,
const GrUniqueKey& key) {
if (GrBuffer* buffer = this->findAndRefTByUniqueKey<GrBuffer>(key)) {
return buffer;
}
return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key);
}
/**
* Returns an index buffer that can be used to render quads.
* Six indices per quad: 0, 1, 2, 0, 2, 3, etc.
* The max number of quads is the buffer's index capacity divided by 6.
* Draw with kTriangles_GrPrimitiveType
* @ return the quad index buffer
*/
const GrBuffer* refQuadIndexBuffer() {
if (GrBuffer* buffer =
this->findAndRefTByUniqueKey<GrBuffer>(fQuadIndexBufferKey)) {
return buffer;
}
return this->createQuadIndexBuffer();
}
/**
* Factories for GrPath and GrPathRange objects. It's an error to call these if path rendering
* is not supported.
*/
GrPath* createPath(const SkPath&, const GrStyle&);
GrPathRange* createPathRange(GrPathRange::PathGenerator*, const GrStyle&);
GrPathRange* createGlyphs(const SkTypeface*, const SkScalerContextEffects&,
const SkDescriptor*, const GrStyle&);
using GrTextureProvider::createTexture;
using GrTextureProvider::assignUniqueKeyToResource;
using GrTextureProvider::findAndRefResourceByUniqueKey;
using GrTextureProvider::findAndRefTextureByUniqueKey;
using GrTextureProvider::abandon;
/** These flags alias/extend GrTextureProvider::ScratchTextureFlags */
enum Flags {
/** If the caller intends to do direct reads/writes to/from the CPU then this flag must be
* set when accessing resources during a GrOpList flush. This includes the execution of
* GrOp objects. The reason is that these memory operations are done immediately and
* will occur out of order WRT the operations being flushed.
* Make this automatic: https://bug.skia.org/4156
*/
kNoPendingIO_Flag = GrTextureProvider::kNoPendingIO_ScratchTextureFlag,
/** Normally the caps may indicate a preference for client-side buffers. Set this flag when
* creating a buffer to guarantee it resides in GPU memory.
*/
kRequireGpuMemory_Flag = GrTextureProvider::kLastScratchTextureFlag << 1,
};
/**
* Returns a buffer.
*
* @param size minimum size of buffer to return.
* @param intendedType hint to the graphics subsystem about what the buffer will be used for.
* @param GrAccessPattern hint to the graphics subsystem about how the data will be accessed.
* @param flags see Flags enum.
* @param data optional data with which to initialize the buffer.
*
* @return the buffer if successful, otherwise nullptr.
*/
GrBuffer* createBuffer(size_t size, GrBufferType intendedType, GrAccessPattern, uint32_t flags,
const void* data = nullptr);
GrTexture* createApproxTexture(const GrSurfaceDesc& desc, uint32_t flags) {
SkASSERT(0 == flags || kNoPendingIO_Flag == flags);
return this->internalCreateApproxTexture(desc, flags);
}
/**
* Returns a GrDrawOpAtlas. This function can be called anywhere, but the returned atlas
* should only be used inside of GrMeshDrawOp::onPrepareDraws.
* @param GrPixelConfig The pixel config which this atlas will store
* @param width width in pixels of the atlas
* @param height height in pixels of the atlas
* @param numPlotsX The number of plots the atlas should be broken up into in the X
* direction
* @param numPlotsY The number of plots the atlas should be broken up into in the Y
* direction
* @param func An eviction function which will be called whenever the atlas has to
* evict data
* @param data User supplied data which will be passed into func whenver an
* eviction occurs
* @return An initialized GrDrawOpAtlas, or nullptr if creation fails
*/
std::unique_ptr<GrDrawOpAtlas> makeAtlas(GrPixelConfig, int width, int height, int numPlotsX,
int numPlotsY, GrDrawOpAtlas::EvictionFunc func,
void* data);
/**
* If passed in render target already has a stencil buffer, return it. Otherwise attempt to
* attach one.
*/
GrStencilAttachment* attachStencilAttachment(GrRenderTarget* rt);
const GrCaps* caps() { return this->gpu()->caps(); }
/**
* Wraps an existing texture with a GrRenderTarget object. This is useful when the provided
* texture has a format that cannot be textured from by Skia, but we want to raster to it.
*
* The texture is wrapped as borrowed. The texture object will not be freed once the
* render target is destroyed.
*
* @return GrRenderTarget object or NULL on failure.
*/
sk_sp<GrRenderTarget> wrapBackendTextureAsRenderTarget(const GrBackendTextureDesc& desc);
private:
const GrBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,
int vertCount,
const GrUniqueKey& key);
const GrBuffer* createQuadIndexBuffer();
GrUniqueKey fQuadIndexBufferKey;
typedef GrTextureProvider INHERITED;
};
#endif
|