blob: a903e7d2f18fc58693ab58cab57c4f6e5dda4b07 [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:
31 return {false, 1, GR_GL_FLOAT};
32 case kHalf2_GrVertexAttribType:
33 return {false, 2, GR_GL_FLOAT};
34 case kHalf3_GrVertexAttribType:
35 return {false, 3, GR_GL_FLOAT};
36 case kHalf4_GrVertexAttribType:
37 return {false, 4, GR_GL_FLOAT};
38 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};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040044 case kUByte_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050045 return {true, 1, GR_GL_UNSIGNED_BYTE};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040046 case kUByte4_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050047 return {true, 4, GR_GL_UNSIGNED_BYTE};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040048 case kUShort2_norm_GrVertexAttribType:
csmartdaltonb37cb232017-02-08 14:56:27 -050049 return {true, 2, GR_GL_UNSIGNED_SHORT};
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040050 case kUShort2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040051 return {false, 2, GR_GL_UNSIGNED_SHORT};
csmartdaltonb37cb232017-02-08 14:56:27 -050052 case kInt_GrVertexAttribType:
53 return {false, 1, GR_GL_INT};
54 case kUint_GrVertexAttribType:
55 return {false, 1, GR_GL_UNSIGNED_INT};
56 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040057 SK_ABORT("Unknown vertex attrib type");
csmartdaltonb37cb232017-02-08 14:56:27 -050058 return {false, 0, 0};
59};
bsalomon6df86402015-06-01 10:41:49 -070060
Robert Phillips8296e752017-08-25 08:45:21 -040061static bool GrVertexAttribTypeIsIntType(const GrShaderCaps* shaderCaps,
62 GrVertexAttribType type) {
63 switch (type) {
64 case kFloat_GrVertexAttribType:
65 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040066 case kFloat2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040067 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040068 case kFloat3_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040069 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040070 case kFloat4_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040071 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040072 case kHalf_GrVertexAttribType:
73 return false;
74 case kHalf2_GrVertexAttribType:
75 return false;
76 case kHalf3_GrVertexAttribType:
77 return false;
78 case kHalf4_GrVertexAttribType:
79 return false;
80 case kInt2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040081 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040082 case kInt3_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040083 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040084 case kInt4_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040085 return true;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040086 case kUByte_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040087 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040088 case kUByte4_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040089 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040090 case kUShort2_norm_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040091 return false;
Ethan Nicholasfa7ee242017-09-25 09:52:04 -040092 case kUShort2_GrVertexAttribType:
Robert Phillips8296e752017-08-25 08:45:21 -040093 return shaderCaps->integerSupport();
94 case kInt_GrVertexAttribType:
95 return true;
96 case kUint_GrVertexAttribType:
97 return true;
98 }
99 SK_ABORT("Unexpected attribute type");
100 return false;
101}
102
bsalomon6df86402015-06-01 10:41:49 -0700103void GrGLAttribArrayState::set(GrGLGpu* gpu,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000104 int index,
csmartdalton485a1202016-07-13 10:16:32 -0700105 const GrBuffer* vertexBuffer,
cdalton793dc262016-02-08 10:11:47 -0800106 GrVertexAttribType type,
bsalomon@google.com6918d482013-03-07 19:09:11 +0000107 GrGLsizei stride,
Chris Dalton1d616352017-05-31 12:51:23 -0600108 size_t offsetInBytes,
109 int divisor) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000110 SkASSERT(index >= 0 && index < fAttribArrayStates.count());
Chris Dalton1d616352017-05-31 12:51:23 -0600111 SkASSERT(0 == divisor || gpu->caps()->instanceAttribSupport());
bsalomon@google.com6918d482013-03-07 19:09:11 +0000112 AttribArrayState* array = &fAttribArrayStates[index];
robertphillips8abb3702016-08-31 14:04:06 -0700113 if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() ||
cdalton793dc262016-02-08 10:11:47 -0800114 array->fType != type ||
bsalomon@google.com6918d482013-03-07 19:09:11 +0000115 array->fStride != stride ||
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400116 array->fOffset != offsetInBytes) {
cdaltone2e71c22016-04-07 18:13:29 -0700117 gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer);
csmartdaltonb37cb232017-02-08 14:56:27 -0500118 const AttribLayout& layout = attrib_layout(type);
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400119 const GrGLvoid* offsetAsPtr = reinterpret_cast<const GrGLvoid*>(offsetInBytes);
Robert Phillips8296e752017-08-25 08:45:21 -0400120 if (!GrVertexAttribTypeIsIntType(gpu->caps()->shaderCaps(), type)) {
cdalton793dc262016-02-08 10:11:47 -0800121 GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
122 layout.fCount,
123 layout.fType,
124 layout.fNormalized,
125 stride,
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400126 offsetAsPtr));
cdalton793dc262016-02-08 10:11:47 -0800127 } else {
128 SkASSERT(gpu->caps()->shaderCaps()->integerSupport());
129 SkASSERT(!layout.fNormalized);
130 GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index,
131 layout.fCount,
132 layout.fType,
133 stride,
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400134 offsetAsPtr));
cdalton793dc262016-02-08 10:11:47 -0800135 }
robertphillips8abb3702016-08-31 14:04:06 -0700136 array->fVertexBufferUniqueID = vertexBuffer->uniqueID();
cdalton793dc262016-02-08 10:11:47 -0800137 array->fType = type;
dchengc4d196c2016-02-06 15:08:54 -0800138 array->fStride = stride;
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400139 array->fOffset = offsetInBytes;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000140 }
Chris Dalton1d616352017-05-31 12:51:23 -0600141 if (gpu->caps()->instanceAttribSupport() && array->fDivisor != divisor) {
142 SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect.
143 GR_GL_CALL(gpu->glInterface(), VertexAttribDivisor(index, divisor));
144 array->fDivisor = divisor;
145 }
bsalomon@google.com6918d482013-03-07 19:09:11 +0000146}
147
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400148void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount) {
149 SkASSERT(enabledCount <= fAttribArrayStates.count());
Chris Dalton1d616352017-05-31 12:51:23 -0600150 if (fEnabledCountIsValid && enabledCount == fNumEnabledArrays) {
151 return;
152 }
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400153
154 int firstIdxToEnable = fEnabledCountIsValid ? fNumEnabledArrays : 0;
155 for (int i = firstIdxToEnable; i < enabledCount; ++i) {
156 GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i));
bsalomon@google.com6918d482013-03-07 19:09:11 +0000157 }
Chris Dalton8e45b4f2017-05-05 14:00:56 -0400158
159 int endIdxToDisable = fEnabledCountIsValid ? fNumEnabledArrays : fAttribArrayStates.count();
160 for (int i = enabledCount; i < endIdxToDisable; ++i) {
161 GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
162 }
163
164 fNumEnabledArrays = enabledCount;
165 fEnabledCountIsValid = true;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000166}
167
168///////////////////////////////////////////////////////////////////////////////////////////////////
169
bsalomon8780bc62015-05-13 09:56:37 -0700170GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount)
171 : fID(id)
bsalomon@google.com6918d482013-03-07 19:09:11 +0000172 , fAttribArrays(attribCount)
cdaltone2e71c22016-04-07 18:13:29 -0700173 , fIndexBufferUniqueID(SK_InvalidUniqueID) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000174}
175
bsalomon8780bc62015-05-13 09:56:37 -0700176GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) {
bsalomon@google.com6918d482013-03-07 19:09:11 +0000177 if (0 == fID) {
halcanary96fcdcc2015-08-27 07:41:13 -0700178 return nullptr;
bsalomon@google.com6918d482013-03-07 19:09:11 +0000179 }
bsalomon8780bc62015-05-13 09:56:37 -0700180 gpu->bindVertexArray(fID);
bsalomon@google.com6918d482013-03-07 19:09:11 +0000181 return &fAttribArrays;
182}
skia.committer@gmail.com754a3eb2013-03-08 07:01:25 +0000183
csmartdalton485a1202016-07-13 10:16:32 -0700184GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) {
bsalomon8780bc62015-05-13 09:56:37 -0700185 GrGLAttribArrayState* state = this->bind(gpu);
robertphillips8abb3702016-08-31 14:04:06 -0700186 if (state && fIndexBufferUniqueID != ibuff->uniqueID()) {
csmartdalton485a1202016-07-13 10:16:32 -0700187 if (ibuff->isCPUBacked()) {
188 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0));
189 } else {
190 const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff);
191 GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
192 glBuffer->bufferID()));
193 }
robertphillips8abb3702016-08-31 14:04:06 -0700194 fIndexBufferUniqueID = ibuff->uniqueID();
bsalomon@google.com6918d482013-03-07 19:09:11 +0000195 }
196 return state;
197}
198
bsalomon@google.com6918d482013-03-07 19:09:11 +0000199void GrGLVertexArray::invalidateCachedState() {
commit-bot@chromium.orgce6da4d2013-09-09 14:55:37 +0000200 fAttribArrays.invalidate();
Robert Phillips294870f2016-11-11 12:38:40 -0500201 fIndexBufferUniqueID.makeInvalid();
bsalomon@google.com6918d482013-03-07 19:09:11 +0000202}