blob: 2f65ed5155e3b16ce1070329a9cc69bf6f238c86 [file] [log] [blame]
bsalomon@google.com6918d482013-03-07 19:09:11 +00001/*
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 */
7
8#include "GrGLVertexArray.h"
cdaltone2e71c22016-04-07 18:13:29 -07009#include "GrGLBuffer.h"
jvanverth39edf762014-12-22 11:44:19 -080010#include "GrGLGpu.h"
bsalomon@google.com6918d482013-03-07 19:09:11 +000011
cdalton793dc262016-02-08 10:11:47 -080012struct AttribLayout {
csmartdaltonb37cb232017-02-08 14:56:27 -050013 bool fNormalized; // Only used by floating point types.
14 uint8_t fCount;
15 uint16_t fType;
cdalton793dc262016-02-08 10:11:47 -080016};
bsalomon@google.com6918d482013-03-07 19:09:11 +000017
csmartdaltonb37cb232017-02-08 14:56:27 -050018GR_STATIC_ASSERT(4 == sizeof(AttribLayout));
cdalton793dc262016-02-08 10:11:47 -080019
csmartdaltonb37cb232017-02-08 14:56:27 -050020static AttribLayout attrib_layout(GrVertexAttribType type) {
21 switch (type) {
22 case kFloat_GrVertexAttribType:
23 return {false, 1, GR_GL_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040024 case kFloat2_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050025 return {false, 2, GR_GL_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040026 case kFloat3_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050027 return {false, 3, GR_GL_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040028 case kFloat4_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050029 return {false, 4, GR_GL_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040030 case kHalf_GrVertexAttribType:
Brian Osmand4c29702018-09-14 16:16:55 -040031 return {false, 1, GR_GL_HALF_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040032 case kHalf2_GrVertexAttribType:
Brian Osmand4c29702018-09-14 16:16:55 -040033 return {false, 2, GR_GL_HALF_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040034 case kHalf3_GrVertexAttribType:
Brian Osmand4c29702018-09-14 16:16:55 -040035 return {false, 3, GR_GL_HALF_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040036 case kHalf4_GrVertexAttribType:
Brian Osmand4c29702018-09-14 16:16:55 -040037 return {false, 4, GR_GL_HALF_FLOAT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040038 case kInt2_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050039 return {false, 2, GR_GL_INT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040040 case kInt3_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050041 return {false, 3, GR_GL_INT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040042 case kInt4_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050043 return {false, 4, GR_GL_INT};
Ruiqi Maob609e6d2018-07-17 10:19:38 -040044 case kByte_GrVertexAttribType:
45 return {false, 1, GR_GL_BYTE};
46 case kByte2_GrVertexAttribType:
47 return {false, 2, GR_GL_BYTE};
48 case kByte3_GrVertexAttribType:
49 return {false, 3, GR_GL_BYTE};
50 case kByte4_GrVertexAttribType:
51 return {false, 4, GR_GL_BYTE};
52 case kUByte_GrVertexAttribType:
53 return {false, 1, GR_GL_UNSIGNED_BYTE};
54 case kUByte2_GrVertexAttribType:
55 return {false, 2, GR_GL_UNSIGNED_BYTE};
56 case kUByte3_GrVertexAttribType:
57 return {false, 3, GR_GL_UNSIGNED_BYTE};
58 case kUByte4_GrVertexAttribType:
59 return {false, 4, GR_GL_UNSIGNED_BYTE};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040060 case kUByte_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050061 return {true, 1, GR_GL_UNSIGNED_BYTE};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040062 case kUByte4_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050063 return {true, 4, GR_GL_UNSIGNED_BYTE};
Chris Daltona045eea2017-10-24 13:22:10 -060064 case kShort2_GrVertexAttribType:
65 return {false, 2, GR_GL_SHORT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040066 case kUShort2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040067 return {false, 2, GR_GL_UNSIGNED_SHORT};
Chris Daltona045eea2017-10-24 13:22:10 -060068 case kUShort2_norm_GrVertexAttribType:
69 return {true, 2, GR_GL_UNSIGNED_SHORT};
csmartdaltonb37cb232017-02-08 14:56:27 -050070 case kInt_GrVertexAttribType:
71 return {false, 1, GR_GL_INT};
72 case kUint_GrVertexAttribType:
73 return {false, 1, GR_GL_UNSIGNED_INT};
74 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040075 SK_ABORT("Unknown vertex attrib type");
csmartdaltonb37cb232017-02-08 14:56:27 -050076 return {false, 0, 0};
77};
bsalomon6df86402015-06-01 10:41:49 -070078
Robert Phillips8296e752017-08-25 08:45:21 -040079static bool GrVertexAttribTypeIsIntType(const GrShaderCaps* shaderCaps,
80 GrVertexAttribType type) {
81 switch (type) {
82 case kFloat_GrVertexAttribType:
83 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040084 case kFloat2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040085 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040086 case kFloat3_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040087 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040088 case kFloat4_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040089 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040090 case kHalf_GrVertexAttribType:
91 return false;
92 case kHalf2_GrVertexAttribType:
93 return false;
94 case kHalf3_GrVertexAttribType:
95 return false;
96 case kHalf4_GrVertexAttribType:
97 return false;
98 case kInt2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040099 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -0400100 case kInt3_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -0400101 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -0400102 case kInt4_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -0400103 return true;
Ruiqi Maob609e6d2018-07-17 10:19:38 -0400104 case kByte_GrVertexAttribType:
105 return true;
106 case kByte2_GrVertexAttribType:
107 return true;
108 case kByte3_GrVertexAttribType:
109 return true;
110 case kByte4_GrVertexAttribType:
111 return true;
112 case kUByte_GrVertexAttribType:
113 return true;
114 case kUByte2_GrVertexAttribType:
115 return true;
116 case kUByte3_GrVertexAttribType:
117 return true;
118 case kUByte4_GrVertexAttribType:
119 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -0400120 case kUByte_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -0400121 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -0400122 case kUByte4_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -0400123 return false;
Chris Daltona045eea2017-10-24 13:22:10 -0600124 case kShort2_GrVertexAttribType:
125 return true;
126 case kUShort2_GrVertexAttribType:
127 return shaderCaps->integerSupport(); // FIXME: caller should handle this.
Ethan Nicholasfa7ee242017-09-25 09:52:04 -0400128 case kUShort2_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -0400129 return false;
Robert Phillips8296e752017-08-25 08:45:21 -0400130 case kInt_GrVertexAttribType:
131 return true;
132 case kUint_GrVertexAttribType:
133 return true;
134 }
135 SK_ABORT("Unexpected attribute type");
136 return false;
137}
138
bsalomon6df86402015-06-01 10:41:49 -0700139void GrGLAttribArrayState::set(GrGLGpu* gpu,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000140 int index,
csmartdalton485a1202016-07-13 10:16:32 -0700141 const GrBuffer* vertexBuffer,
cdalton793dc262016-02-08 10:11:47 -0800142 GrVertexAttribType type,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000143 GrGLsizei stride,
Chris Dalton1d616352017-05-31 12:51:23 -0600144 size_t offsetInBytes,
145 int divisor) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000146 SkASSERT(index >= 0 && index < fAttribArrayStates.count());
Chris Dalton1d616352017-05-31 12:51:23 -0600147 SkASSERT(0 == divisor || gpu->caps()->instanceAttribSupport());
bsalomon@google.com6918d482013-03-07 19:09:11 +0000148 AttribArrayState* array = &fAttribArrayStates[index];
robertphillips8abb3702016-08-31 14:04:06 -0700149 if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() ||
cdalton793dc262016-02-08 10:11:47 -0800150 array->fType != type ||
bsalomon@google.com6918d482013-03-07 19:09:11 +0000151 array->fStride != stride ||
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400152 array->fOffset != offsetInBytes) {
cdaltone2e71c22016-04-07 18:13:29 -0700153 gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer);
csmartdaltonb37cb232017-02-08 14:56:27 -0500154 const AttribLayout& layout = attrib_layout(type);
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400155 const GrGLvoid* offsetAsPtr = reinterpret_cast<const GrGLvoid*>(offsetInBytes);
Robert Phillips8296e752017-08-25 08:45:21 -0400156 if (!GrVertexAttribTypeIsIntType(gpu->caps()->shaderCaps(), type)) {
cdalton793dc262016-02-08 10:11:47 -0800157 GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
158 layout.fCount,
159 layout.fType,
160 layout.fNormalized,
161 stride,
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400162 offsetAsPtr));
cdalton793dc262016-02-08 10:11:47 -0800163 } else {
164 SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
165 SkASSERT(!layout.fNormalized);
166 GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
167 layout.fCount,
168 layout.fType,
169 stride,
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400170 offsetAsPtr));
cdalton793dc262016-02-08 10:11:47 -0800171 }
robertphillips8abb3702016-08-31 14:04:06 -0700172 array->fVertexBufferUniqueID = vertexBuffer->uniqueID();
cdalton793dc262016-02-08 10:11:47 -0800173 array->fType = type;
dchengc4d196c2016-02-06 15:08:54 -0800174 array->fStride = stride;
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400175 array->fOffset = offsetInBytes;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000176 }
Chris Dalton1d616352017-05-31 12:51:23 -0600177 if (gpu->caps()->instanceAttribSupport() && array->fDivisor != divisor) {
178 SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect.
179 GR_GL_CALL(gpu->glInterface(), VertexAttribDivisor(index, divisor));
180 array->fDivisor = divisor;
181 }
bsalomon@google.com6918d482013-03-07 19:09:11 +0000182}
183
Chris Dalton27059d32018-01-23 14:06:50 -0700184void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount,
Brian Salomon802cb312018-06-08 18:05:20 -0400185 GrPrimitiveRestart enablePrimitiveRestart) {
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400186 SkASSERT(enabledCount <= fAttribArrayStates.count());
Chris Dalton27059d32018-01-23 14:06:50 -0700187
188 if (!fEnableStateIsValid || enabledCount != fNumEnabledArrays) {
189 int firstIdxToEnable = fEnableStateIsValid ? fNumEnabledArrays : 0;
190 for (int i = firstIdxToEnable; i < enabledCount; ++i) {
191 GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i));
192 }
193
194 int endIdxToDisable = fEnableStateIsValid ? fNumEnabledArrays : fAttribArrayStates.count();
195 for (int i = enabledCount; i < endIdxToDisable; ++i) {
196 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
197 }
198
199 fNumEnabledArrays = enabledCount;
Chris Dalton1d616352017-05-31 12:51:23 -0600200 }
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400201
Brian Salomon802cb312018-06-08 18:05:20 -0400202 SkASSERT(GrPrimitiveRestart::kNo == enablePrimitiveRestart ||
Chris Dalton27059d32018-01-23 14:06:50 -0700203 gpu->caps()->usePrimitiveRestart());
204
205 if (gpu->caps()->usePrimitiveRestart() &&
206 (!fEnableStateIsValid || enablePrimitiveRestart != fPrimitiveRestartEnabled)) {
Brian Salomon802cb312018-06-08 18:05:20 -0400207 if (GrPrimitiveRestart::kYes == enablePrimitiveRestart) {
Chris Dalton27059d32018-01-23 14:06:50 -0700208 GR_GL_CALL(gpu->glInterface(), Enable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX));
209 } else {
210 GR_GL_CALL(gpu->glInterface(), Disable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX));
211 }
212
213 fPrimitiveRestartEnabled = enablePrimitiveRestart;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000214 }
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400215
Chris Dalton27059d32018-01-23 14:06:50 -0700216 fEnableStateIsValid = true;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000217}
218
219///////////////////////////////////////////////////////////////////////////////////////////////////
220
bsalomon8780bc62015-05-13 09:56:37 -0700221GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
222 : fID(id)
bsalomon@google.com6918d482013-03-07 19:09:11 +0000223 , fAttribArrays(attribCount)
cdaltone2e71c22016-04-07 18:13:29 -0700224 , fIndexBufferUniqueID(SK_InvalidUniqueID) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000225}
226
bsalomon8780bc62015-05-13 09:56:37 -0700227GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000228 if (0 == fID) {
halcanary96fcdcc2015-08-27 07:41:13 -0700229 return nullptr;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000230 }
bsalomon8780bc62015-05-13 09:56:37 -0700231 gpu->bindVertexArray(fID);
bsalomon@google.com6918d482013-03-07 19:09:11 +0000232 return &fAttribArrays;
233}
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000234
csmartdalton485a1202016-07-13 10:16:32 -0700235GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) {
bsalomon8780bc62015-05-13 09:56:37 -0700236 GrGLAttribArrayState* state = this->bind(gpu);
robertphillips8abb3702016-08-31 14:04:06 -0700237 if (state && fIndexBufferUniqueID != ibuff->uniqueID()) {
csmartdalton485a1202016-07-13 10:16:32 -0700238 if (ibuff->isCPUBacked()) {
239 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
240 } else {
241 const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
242 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
243 glBuffer->bufferID()));
244 }
robertphillips8abb3702016-08-31 14:04:06 -0700245 fIndexBufferUniqueID = ibuff->uniqueID();
bsalomon@google.com6918d482013-03-07 19:09:11 +0000246 }
247 return state;
248}
249
bsalomon@google.com6918d482013-03-07 19:09:11 +0000250void GrGLVertexArray::invalidateCachedState() {
commit-bot@chromium.orgce6da4d2013-09-09 14:55:37 +0000251 fAttribArrays.invalidate();
Robert Phillips294870f2016-11-11 12:38:40 -0500252 fIndexBufferUniqueID.makeInvalid();
bsalomon@google.com6918d482013-03-07 19:09:11 +0000253}