bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 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 | */ |
| 7 | |
| 8 | #include "GrGLVertexArray.h" |
cdalton | e2e71c2 | 2016-04-07 18:13:29 -0700 | [diff] [blame] | 9 | #include "GrGLBuffer.h" |
jvanverth | 39edf76 | 2014-12-22 11:44:19 -0800 | [diff] [blame] | 10 | #include "GrGLGpu.h" |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 11 | |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 12 | struct AttribLayout { |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 13 | bool fNormalized; // Only used by floating point types. |
| 14 | uint8_t fCount; |
| 15 | uint16_t fType; |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 16 | }; |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 17 | |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 18 | GR_STATIC_ASSERT(4 == sizeof(AttribLayout)); |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 19 | |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 20 | static AttribLayout attrib_layout(GrVertexAttribType type) { |
| 21 | switch (type) { |
| 22 | case kFloat_GrVertexAttribType: |
| 23 | return {false, 1, GR_GL_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 24 | case kFloat2_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 25 | return {false, 2, GR_GL_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 26 | case kFloat3_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 27 | return {false, 3, GR_GL_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 28 | case kFloat4_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 29 | return {false, 4, GR_GL_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 30 | case kHalf_GrVertexAttribType: |
Brian Osman | d4c2970 | 2018-09-14 16:16:55 -0400 | [diff] [blame] | 31 | return {false, 1, GR_GL_HALF_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 32 | case kHalf2_GrVertexAttribType: |
Brian Osman | d4c2970 | 2018-09-14 16:16:55 -0400 | [diff] [blame] | 33 | return {false, 2, GR_GL_HALF_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 34 | case kHalf3_GrVertexAttribType: |
Brian Osman | d4c2970 | 2018-09-14 16:16:55 -0400 | [diff] [blame] | 35 | return {false, 3, GR_GL_HALF_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 36 | case kHalf4_GrVertexAttribType: |
Brian Osman | d4c2970 | 2018-09-14 16:16:55 -0400 | [diff] [blame] | 37 | return {false, 4, GR_GL_HALF_FLOAT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 38 | case kInt2_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 39 | return {false, 2, GR_GL_INT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 40 | case kInt3_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 41 | return {false, 3, GR_GL_INT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 42 | case kInt4_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 43 | return {false, 4, GR_GL_INT}; |
Ruiqi Mao | b609e6d | 2018-07-17 10:19:38 -0400 | [diff] [blame] | 44 | 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 Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 60 | case kUByte_norm_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 61 | return {true, 1, GR_GL_UNSIGNED_BYTE}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 62 | case kUByte4_norm_GrVertexAttribType: |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 63 | return {true, 4, GR_GL_UNSIGNED_BYTE}; |
Chris Dalton | a045eea | 2017-10-24 13:22:10 -0600 | [diff] [blame] | 64 | case kShort2_GrVertexAttribType: |
| 65 | return {false, 2, GR_GL_SHORT}; |
Brian Osman | a5c578f | 2018-09-19 14:19:02 -0400 | [diff] [blame] | 66 | case kShort4_GrVertexAttribType: |
| 67 | return {false, 4, GR_GL_SHORT}; |
Ethan Nicholas | fa7ee24 | 2017-09-25 09:52:04 -0400 | [diff] [blame] | 68 | case kUShort2_GrVertexAttribType: |
Robert Phillips | 8296e75 | 2017-08-25 08:45:21 -0400 | [diff] [blame] | 69 | return {false, 2, GR_GL_UNSIGNED_SHORT}; |
Chris Dalton | a045eea | 2017-10-24 13:22:10 -0600 | [diff] [blame] | 70 | case kUShort2_norm_GrVertexAttribType: |
| 71 | return {true, 2, GR_GL_UNSIGNED_SHORT}; |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 72 | case kInt_GrVertexAttribType: |
| 73 | return {false, 1, GR_GL_INT}; |
| 74 | case kUint_GrVertexAttribType: |
| 75 | return {false, 1, GR_GL_UNSIGNED_INT}; |
| 76 | } |
Ben Wagner | b4aab9a | 2017-08-16 10:53:04 -0400 | [diff] [blame] | 77 | SK_ABORT("Unknown vertex attrib type"); |
csmartdalton | b37cb23 | 2017-02-08 14:56:27 -0500 | [diff] [blame] | 78 | return {false, 0, 0}; |
| 79 | }; |
bsalomon | 6df8640 | 2015-06-01 10:41:49 -0700 | [diff] [blame] | 80 | |
| 81 | void GrGLAttribArrayState::set(GrGLGpu* gpu, |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 82 | int index, |
csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 83 | const GrBuffer* vertexBuffer, |
Brian Osman | 4a3f5c8 | 2018-09-18 16:16:38 -0400 | [diff] [blame] | 84 | GrVertexAttribType cpuType, |
| 85 | GrSLType gpuType, |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 86 | GrGLsizei stride, |
Chris Dalton | 1d61635 | 2017-05-31 12:51:23 -0600 | [diff] [blame] | 87 | size_t offsetInBytes, |
| 88 | int divisor) { |
tfarina@chromium.org | f6de475 | 2013-08-17 00:02:59 +0000 | [diff] [blame] | 89 | SkASSERT(index >= 0 && index < fAttribArrayStates.count()); |
Chris Dalton | 1d61635 | 2017-05-31 12:51:23 -0600 | [diff] [blame] | 90 | SkASSERT(0 == divisor || gpu->caps()->instanceAttribSupport()); |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 91 | AttribArrayState* array = &fAttribArrayStates[index]; |
robertphillips | 8abb370 | 2016-08-31 14:04:06 -0700 | [diff] [blame] | 92 | if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() || |
Brian Osman | 4a3f5c8 | 2018-09-18 16:16:38 -0400 | [diff] [blame] | 93 | array->fCPUType != cpuType || |
| 94 | array->fGPUType != gpuType || |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 95 | array->fStride != stride || |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 96 | array->fOffset != offsetInBytes) { |
Brian Salomon | ae64c19 | 2019-02-05 09:41:37 -0500 | [diff] [blame^] | 97 | gpu->bindBuffer(GrGpuBufferType::kVertex, vertexBuffer); |
Brian Osman | 4a3f5c8 | 2018-09-18 16:16:38 -0400 | [diff] [blame] | 98 | const AttribLayout& layout = attrib_layout(cpuType); |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 99 | const GrGLvoid* offsetAsPtr = reinterpret_cast<const GrGLvoid*>(offsetInBytes); |
Brian Osman | 4a3f5c8 | 2018-09-18 16:16:38 -0400 | [diff] [blame] | 100 | if (GrSLTypeIsFloatType(gpuType)) { |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 101 | GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, |
| 102 | layout.fCount, |
| 103 | layout.fType, |
| 104 | layout.fNormalized, |
| 105 | stride, |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 106 | offsetAsPtr)); |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 107 | } else { |
| 108 | SkASSERT(gpu->caps()->shaderCaps()->integerSupport()); |
| 109 | SkASSERT(!layout.fNormalized); |
| 110 | GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index, |
| 111 | layout.fCount, |
| 112 | layout.fType, |
| 113 | stride, |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 114 | offsetAsPtr)); |
cdalton | 793dc26 | 2016-02-08 10:11:47 -0800 | [diff] [blame] | 115 | } |
robertphillips | 8abb370 | 2016-08-31 14:04:06 -0700 | [diff] [blame] | 116 | array->fVertexBufferUniqueID = vertexBuffer->uniqueID(); |
Brian Osman | 4a3f5c8 | 2018-09-18 16:16:38 -0400 | [diff] [blame] | 117 | array->fCPUType = cpuType; |
| 118 | array->fGPUType = gpuType; |
dcheng | c4d196c | 2016-02-06 15:08:54 -0800 | [diff] [blame] | 119 | array->fStride = stride; |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 120 | array->fOffset = offsetInBytes; |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 121 | } |
Chris Dalton | 1d61635 | 2017-05-31 12:51:23 -0600 | [diff] [blame] | 122 | if (gpu->caps()->instanceAttribSupport() && array->fDivisor != divisor) { |
| 123 | SkASSERT(0 == divisor || 1 == divisor); // not necessarily a requirement but what we expect. |
| 124 | GR_GL_CALL(gpu->glInterface(), VertexAttribDivisor(index, divisor)); |
| 125 | array->fDivisor = divisor; |
| 126 | } |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 127 | } |
| 128 | |
Chris Dalton | 27059d3 | 2018-01-23 14:06:50 -0700 | [diff] [blame] | 129 | void GrGLAttribArrayState::enableVertexArrays(const GrGLGpu* gpu, int enabledCount, |
Brian Salomon | 802cb31 | 2018-06-08 18:05:20 -0400 | [diff] [blame] | 130 | GrPrimitiveRestart enablePrimitiveRestart) { |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 131 | SkASSERT(enabledCount <= fAttribArrayStates.count()); |
Chris Dalton | 27059d3 | 2018-01-23 14:06:50 -0700 | [diff] [blame] | 132 | |
| 133 | if (!fEnableStateIsValid || enabledCount != fNumEnabledArrays) { |
| 134 | int firstIdxToEnable = fEnableStateIsValid ? fNumEnabledArrays : 0; |
| 135 | for (int i = firstIdxToEnable; i < enabledCount; ++i) { |
| 136 | GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(i)); |
| 137 | } |
| 138 | |
| 139 | int endIdxToDisable = fEnableStateIsValid ? fNumEnabledArrays : fAttribArrayStates.count(); |
| 140 | for (int i = enabledCount; i < endIdxToDisable; ++i) { |
| 141 | GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); |
| 142 | } |
| 143 | |
| 144 | fNumEnabledArrays = enabledCount; |
Chris Dalton | 1d61635 | 2017-05-31 12:51:23 -0600 | [diff] [blame] | 145 | } |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 146 | |
Brian Salomon | 802cb31 | 2018-06-08 18:05:20 -0400 | [diff] [blame] | 147 | SkASSERT(GrPrimitiveRestart::kNo == enablePrimitiveRestart || |
Chris Dalton | 27059d3 | 2018-01-23 14:06:50 -0700 | [diff] [blame] | 148 | gpu->caps()->usePrimitiveRestart()); |
| 149 | |
| 150 | if (gpu->caps()->usePrimitiveRestart() && |
| 151 | (!fEnableStateIsValid || enablePrimitiveRestart != fPrimitiveRestartEnabled)) { |
Brian Salomon | 802cb31 | 2018-06-08 18:05:20 -0400 | [diff] [blame] | 152 | if (GrPrimitiveRestart::kYes == enablePrimitiveRestart) { |
Chris Dalton | 27059d3 | 2018-01-23 14:06:50 -0700 | [diff] [blame] | 153 | GR_GL_CALL(gpu->glInterface(), Enable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX)); |
| 154 | } else { |
| 155 | GR_GL_CALL(gpu->glInterface(), Disable(GR_GL_PRIMITIVE_RESTART_FIXED_INDEX)); |
| 156 | } |
| 157 | |
| 158 | fPrimitiveRestartEnabled = enablePrimitiveRestart; |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 159 | } |
Chris Dalton | 8e45b4f | 2017-05-05 14:00:56 -0400 | [diff] [blame] | 160 | |
Chris Dalton | 27059d3 | 2018-01-23 14:06:50 -0700 | [diff] [blame] | 161 | fEnableStateIsValid = true; |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
| 165 | |
bsalomon | 8780bc6 | 2015-05-13 09:56:37 -0700 | [diff] [blame] | 166 | GrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount) |
| 167 | : fID(id) |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 168 | , fAttribArrays(attribCount) |
cdalton | e2e71c2 | 2016-04-07 18:13:29 -0700 | [diff] [blame] | 169 | , fIndexBufferUniqueID(SK_InvalidUniqueID) { |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 170 | } |
| 171 | |
bsalomon | 8780bc6 | 2015-05-13 09:56:37 -0700 | [diff] [blame] | 172 | GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) { |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 173 | if (0 == fID) { |
halcanary | 96fcdcc | 2015-08-27 07:41:13 -0700 | [diff] [blame] | 174 | return nullptr; |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 175 | } |
bsalomon | 8780bc6 | 2015-05-13 09:56:37 -0700 | [diff] [blame] | 176 | gpu->bindVertexArray(fID); |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 177 | return &fAttribArrays; |
| 178 | } |
skia.committer@gmail.com | 754a3eb | 2013-03-08 07:01:25 +0000 | [diff] [blame] | 179 | |
csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 180 | GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) { |
bsalomon | 8780bc6 | 2015-05-13 09:56:37 -0700 | [diff] [blame] | 181 | GrGLAttribArrayState* state = this->bind(gpu); |
robertphillips | 8abb370 | 2016-08-31 14:04:06 -0700 | [diff] [blame] | 182 | if (state && fIndexBufferUniqueID != ibuff->uniqueID()) { |
csmartdalton | 485a120 | 2016-07-13 10:16:32 -0700 | [diff] [blame] | 183 | if (ibuff->isCPUBacked()) { |
| 184 | GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0)); |
| 185 | } else { |
| 186 | const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff); |
| 187 | GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, |
| 188 | glBuffer->bufferID())); |
| 189 | } |
robertphillips | 8abb370 | 2016-08-31 14:04:06 -0700 | [diff] [blame] | 190 | fIndexBufferUniqueID = ibuff->uniqueID(); |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 191 | } |
| 192 | return state; |
| 193 | } |
| 194 | |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 195 | void GrGLVertexArray::invalidateCachedState() { |
commit-bot@chromium.org | ce6da4d | 2013-09-09 14:55:37 +0000 | [diff] [blame] | 196 | fAttribArrays.invalidate(); |
Robert Phillips | 294870f | 2016-11-11 12:38:40 -0500 | [diff] [blame] | 197 | fIndexBufferUniqueID.makeInvalid(); |
bsalomon@google.com | 6918d48 | 2013-03-07 19:09:11 +0000 | [diff] [blame] | 198 | } |