Flutter Engine
The Flutter Engine
GrGLVertexArray.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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 */
8
22
23#include <cstdint>
24
26 bool fNormalized; // Only used by floating point types.
27 uint8_t fCount;
28 uint16_t fType;
29};
30
31static_assert(4 == sizeof(AttribLayout));
32
34 switch (type) {
36 return {false, 1, GR_GL_FLOAT};
38 return {false, 2, GR_GL_FLOAT};
40 return {false, 3, GR_GL_FLOAT};
42 return {false, 4, GR_GL_FLOAT};
44 return {false, 1, GR_GL_HALF_FLOAT};
46 return {false, 2, GR_GL_HALF_FLOAT};
48 return {false, 4, GR_GL_HALF_FLOAT};
50 return {false, 2, GR_GL_INT};
52 return {false, 3, GR_GL_INT};
54 return {false, 4, GR_GL_INT};
56 return {false, 1, GR_GL_BYTE};
58 return {false, 2, GR_GL_BYTE};
60 return {false, 4, GR_GL_BYTE};
62 return {false, 1, GR_GL_UNSIGNED_BYTE};
64 return {false, 2, GR_GL_UNSIGNED_BYTE};
66 return {false, 4, GR_GL_UNSIGNED_BYTE};
68 return {true, 1, GR_GL_UNSIGNED_BYTE};
70 return {true, 4, GR_GL_UNSIGNED_BYTE};
72 return {false, 2, GR_GL_SHORT};
74 return {false, 4, GR_GL_SHORT};
76 return {false, 2, GR_GL_UNSIGNED_SHORT};
78 return {true, 2, GR_GL_UNSIGNED_SHORT};
80 return {false, 1, GR_GL_INT};
82 return {false, 1, GR_GL_UNSIGNED_INT};
84 return {true, 1, GR_GL_UNSIGNED_SHORT};
86 return {true, 4, GR_GL_UNSIGNED_SHORT};
87 }
88 SK_ABORT("Unknown vertex attrib type");
89}
90
92 int index,
93 const GrBuffer* vertexBuffer,
94 GrVertexAttribType cpuType,
95 SkSLType gpuType,
96 GrGLsizei stride,
97 size_t offsetInBytes,
98 int divisor) {
99 SkASSERT(index >= 0 && index < fAttribArrayStates.size());
100 SkASSERT(0 == divisor || gpu->caps()->drawInstancedSupport());
101 AttribArrayState* array = &fAttribArrayStates[index];
102 const char* offsetAsPtr;
103 bool bufferChanged = false;
104 if (vertexBuffer->isCpuBuffer()) {
105 if (!array->fUsingCpuBuffer) {
106 bufferChanged = true;
107 array->fUsingCpuBuffer = true;
108 }
109 offsetAsPtr = static_cast<const GrCpuBuffer*>(vertexBuffer)->data() + offsetInBytes;
110 } else {
111 auto gpuBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
112 if (array->fUsingCpuBuffer || array->fVertexBufferUniqueID != gpuBuffer->uniqueID()) {
113 bufferChanged = true;
114 array->fVertexBufferUniqueID = gpuBuffer->uniqueID();
115 }
116 offsetAsPtr = reinterpret_cast<const char*>(offsetInBytes);
117 }
118 if (bufferChanged ||
119 array->fCPUType != cpuType ||
120 array->fGPUType != gpuType ||
121 array->fStride != stride ||
122 array->fOffset != offsetAsPtr) {
123 // We always have to call this if we're going to change the array pointer. 'array' is
124 // tracking the last buffer used to setup attrib pointers, not the last buffer bound.
125 // GrGLGpu will avoid redundant binds.
126 gpu->bindBuffer(GrGpuBufferType::kVertex, vertexBuffer);
127 const AttribLayout& layout = attrib_layout(cpuType);
128 if (SkSLTypeIsFloatType(gpuType)) {
129 GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
130 layout.fCount,
131 layout.fType,
132 layout.fNormalized,
133 stride,
134 offsetAsPtr));
135 } else {
137 SkASSERT(!layout.fNormalized);
138 GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
139 layout.fCount,
140 layout.fType,
141 stride,
142 offsetAsPtr));
143 }
144 array->fCPUType = cpuType;
145 array->fGPUType = gpuType;
146 array->fStride = stride;
147 array->fOffset = offsetAsPtr;
148 }
149 if (gpu->caps()->drawInstancedSupport() && array->fDivisor != divisor) {
150 SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect.
151 GR_GL_CALL(gpu->glInterface(), VertexAttribDivisor(index, divisor));
152 array->fDivisor = divisor;
153 }
154}
155
156void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount,
157 GrPrimitiveRestart enablePrimitiveRestart) {
158 SkASSERT(enabledCount <= fAttribArrayStates.size());
159
160 if (!fEnableStateIsValid || enabledCount != fNumEnabledArrays) {
161 int firstIdxToEnable = fEnableStateIsValid ? fNumEnabledArrays : 0;
162 for (int i = firstIdxToEnable; i < enabledCount; ++i) {
163 GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i));
164 }
165
166 int endIdxToDisable = fEnableStateIsValid ? fNumEnabledArrays : fAttribArrayStates.size();
167 for (int i = enabledCount; i < endIdxToDisable; ++i) {
168 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
169 }
170
171 fNumEnabledArrays = enabledCount;
172 }
173
174 SkASSERT(GrPrimitiveRestart::kNo == enablePrimitiveRestart ||
175 gpu->caps()->usePrimitiveRestart());
176
177 if (gpu->caps()->usePrimitiveRestart() &&
178 (!fEnableStateIsValid || enablePrimitiveRestart != fPrimitiveRestartEnabled)) {
179 if (GrPrimitiveRestart::kYes == enablePrimitiveRestart) {
181 } else {
183 }
184
185 fPrimitiveRestartEnabled = enablePrimitiveRestart;
186 }
187
188 fEnableStateIsValid = true;
189}
190
191///////////////////////////////////////////////////////////////////////////////////////////////////
192
194 : fID(id)
195 , fAttribArrays(attribCount)
196 , fIndexBufferUniqueID(SK_InvalidUniqueID) {
197}
198
200 if (0 == fID) {
201 return nullptr;
202 }
203 gpu->bindVertexArray(fID);
204 return &fAttribArrays;
205}
206
208 GrGLAttribArrayState* state = this->bind(gpu);
209 if (!state) {
210 return nullptr;
211 }
212 if (ibuff->isCpuBuffer()) {
213 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
214 } else {
215 const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
216 if (fIndexBufferUniqueID != glBuffer->uniqueID()) {
217 GR_GL_CALL(gpu->glInterface(),
218 BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, glBuffer->bufferID()));
219 fIndexBufferUniqueID = glBuffer->uniqueID();
220 }
221 }
222 return state;
223}
224
226 fAttribArrays.invalidate();
227 fIndexBufferUniqueID.makeInvalid();
228}
#define GR_GL_HALF_FLOAT
Definition: GrGLDefines.h:356
#define GR_GL_BYTE
Definition: GrGLDefines.h:349
#define GR_GL_UNSIGNED_SHORT
Definition: GrGLDefines.h:352
#define GR_GL_ELEMENT_ARRAY_BUFFER
Definition: GrGLDefines.h:111
#define GR_GL_INT
Definition: GrGLDefines.h:353
#define GR_GL_UNSIGNED_INT
Definition: GrGLDefines.h:354
#define GR_GL_SHORT
Definition: GrGLDefines.h:351
#define GR_GL_UNSIGNED_BYTE
Definition: GrGLDefines.h:350
#define GR_GL_PRIMITIVE_RESTART_FIXED_INDEX
Definition: GrGLDefines.h:844
#define GR_GL_FLOAT
Definition: GrGLDefines.h:355
int GrGLsizei
Definition: GrGLTypes.h:109
int GrGLint
Definition: GrGLTypes.h:108
#define GR_GL_CALL(IFACE, X)
Definition: GrGLUtil.h:381
static AttribLayout attrib_layout(GrVertexAttribType type)
GrPrimitiveRestart
Definition: GrTypesPriv.h:56
GrVertexAttribType
Definition: GrTypesPriv.h:312
@ kUShort_norm_GrVertexAttribType
Definition: GrTypesPriv.h:346
@ kFloat2_GrVertexAttribType
Definition: GrTypesPriv.h:314
@ kUShort2_GrVertexAttribType
Definition: GrTypesPriv.h:340
@ kUInt_GrVertexAttribType
Definition: GrTypesPriv.h:344
@ kUByte4_norm_GrVertexAttribType
Definition: GrTypesPriv.h:334
@ kUByte_GrVertexAttribType
Definition: GrTypesPriv.h:329
@ kShort2_GrVertexAttribType
Definition: GrTypesPriv.h:337
@ kUShort4_norm_GrVertexAttribType
Definition: GrTypesPriv.h:348
@ kInt_GrVertexAttribType
Definition: GrTypesPriv.h:343
@ kByte_GrVertexAttribType
Definition: GrTypesPriv.h:326
@ kByte4_GrVertexAttribType
Definition: GrTypesPriv.h:328
@ kFloat3_GrVertexAttribType
Definition: GrTypesPriv.h:315
@ kFloat_GrVertexAttribType
Definition: GrTypesPriv.h:313
@ kByte2_GrVertexAttribType
Definition: GrTypesPriv.h:327
@ kFloat4_GrVertexAttribType
Definition: GrTypesPriv.h:316
@ kShort4_GrVertexAttribType
Definition: GrTypesPriv.h:338
@ kUShort2_norm_GrVertexAttribType
Definition: GrTypesPriv.h:341
@ kInt3_GrVertexAttribType
Definition: GrTypesPriv.h:322
@ kHalf2_GrVertexAttribType
Definition: GrTypesPriv.h:318
@ kHalf4_GrVertexAttribType
Definition: GrTypesPriv.h:319
@ kUByte4_GrVertexAttribType
Definition: GrTypesPriv.h:331
@ kUByte2_GrVertexAttribType
Definition: GrTypesPriv.h:330
@ kInt4_GrVertexAttribType
Definition: GrTypesPriv.h:323
@ kUByte_norm_GrVertexAttribType
Definition: GrTypesPriv.h:333
@ kInt2_GrVertexAttribType
Definition: GrTypesPriv.h:321
@ kHalf_GrVertexAttribType
Definition: GrTypesPriv.h:317
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkSLType
static constexpr bool SkSLTypeIsFloatType(SkSLType type)
static constexpr uint32_t SK_InvalidUniqueID
Definition: SkTypes.h:196
GLenum type
virtual bool isCpuBuffer() const =0
const GrShaderCaps * shaderCaps() const
Definition: GrCaps.h:63
bool drawInstancedSupport() const
Definition: GrCaps.h:80
bool usePrimitiveRestart() const
Definition: GrCaps.h:112
void set(GrGLGpu *, int attribIndex, const GrBuffer *vertexBuffer, GrVertexAttribType cpuType, SkSLType gpuType, GrGLsizei stride, size_t offsetInBytes, int divisor=0)
void enableVertexArrays(const GrGLGpu *, int enabledCount, GrPrimitiveRestart=GrPrimitiveRestart::kNo)
GrGLuint bufferID() const
Definition: GrGLBuffer.h:29
void bindVertexArray(GrGLuint id)
Definition: GrGLGpu.h:117
const GrGLInterface * glInterface() const
Definition: GrGLGpu.h:103
GrGLenum bindBuffer(GrGpuBufferType type, const GrBuffer *)
Definition: GrGLGpu.cpp:2154
GrGLVertexArray(GrGLint id, int attribCount)
GrGLAttribArrayState * bind(GrGLGpu *)
GrGLAttribArrayState * bindWithIndexBuffer(GrGLGpu *gpu, const GrBuffer *indexBuffer)
UniqueID uniqueID() const
const GrCaps * caps() const
Definition: GrGpu.h:73
int size() const
Definition: SkTArray.h:421
AtkStateType state
bool fIntegerSupport
Definition: SkSLUtil.h:89
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
const uintptr_t id