1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "renderstate/MeshState.h" 17 18 #include "Program.h" 19 20 #include "ShadowTessellator.h" 21 22 namespace android { 23 namespace uirenderer { 24 25 MeshState::MeshState() 26 : mCurrentIndicesBuffer(0) 27 , mCurrentPixelBuffer(0) 28 , mCurrentPositionPointer(this) 29 , mCurrentPositionStride(0) 30 , mCurrentTexCoordsPointer(this) 31 , mCurrentTexCoordsStride(0) 32 , mTexCoordsArrayEnabled(false) 33 , mQuadListIndices(0) { 34 glGenBuffers(1, &mUnitQuadBuffer); 35 glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer); 36 glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW); 37 38 mCurrentBuffer = mUnitQuadBuffer; 39 40 uint16_t regionIndices[kMaxNumberOfQuads * 6]; 41 for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { 42 uint16_t quad = i * 4; 43 int index = i * 6; 44 regionIndices[index ] = quad; // top-left 45 regionIndices[index + 1] = quad + 1; // top-right 46 regionIndices[index + 2] = quad + 2; // bottom-left 47 regionIndices[index + 3] = quad + 2; // bottom-left 48 regionIndices[index + 4] = quad + 1; // top-right 49 regionIndices[index + 5] = quad + 3; // bottom-right 50 } 51 glGenBuffers(1, &mQuadListIndices); 52 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices); 53 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW); 54 mCurrentIndicesBuffer = mQuadListIndices; 55 56 // position attribute always enabled 57 glEnableVertexAttribArray(Program::kBindingPosition); 58 } 59 60 MeshState::~MeshState() { 61 glDeleteBuffers(1, &mUnitQuadBuffer); 62 mCurrentBuffer = 0; 63 64 glDeleteBuffers(1, &mQuadListIndices); 65 mQuadListIndices = 0; 66 } 67 68 void MeshState::dump() { 69 ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer); 70 ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer); 71 ALOGD("MeshState vertices: vertex data %p, stride %d", 72 mCurrentPositionPointer, mCurrentPositionStride); 73 ALOGD("MeshState texCoord: data %p, stride %d", 74 mCurrentTexCoordsPointer, mCurrentTexCoordsStride); 75 } 76 77 /////////////////////////////////////////////////////////////////////////////// 78 // Buffer Objects 79 /////////////////////////////////////////////////////////////////////////////// 80 81 bool MeshState::bindMeshBuffer() { 82 return bindMeshBuffer(mUnitQuadBuffer); 83 } 84 85 bool MeshState::bindMeshBuffer(GLuint buffer) { 86 if (!buffer) buffer = mUnitQuadBuffer; 87 return bindMeshBufferInternal(buffer); 88 } 89 90 bool MeshState::unbindMeshBuffer() { 91 return bindMeshBufferInternal(0); 92 } 93 94 bool MeshState::bindMeshBufferInternal(GLuint buffer) { 95 if (mCurrentBuffer != buffer) { 96 glBindBuffer(GL_ARRAY_BUFFER, buffer); 97 mCurrentBuffer = buffer; 98 return true; 99 } 100 return false; 101 } 102 103 /////////////////////////////////////////////////////////////////////////////// 104 // Vertices 105 /////////////////////////////////////////////////////////////////////////////// 106 107 void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { 108 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { 109 glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices); 110 mCurrentPositionPointer = vertices; 111 mCurrentPositionStride = stride; 112 } 113 } 114 115 void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { 116 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { 117 glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices); 118 mCurrentTexCoordsPointer = vertices; 119 mCurrentTexCoordsStride = stride; 120 } 121 } 122 123 void MeshState::resetVertexPointers() { 124 mCurrentPositionPointer = this; 125 mCurrentTexCoordsPointer = this; 126 } 127 128 void MeshState::resetTexCoordsVertexPointer() { 129 mCurrentTexCoordsPointer = this; 130 } 131 132 void MeshState::enableTexCoordsVertexArray() { 133 if (!mTexCoordsArrayEnabled) { 134 glEnableVertexAttribArray(Program::kBindingTexCoords); 135 mCurrentTexCoordsPointer = this; 136 mTexCoordsArrayEnabled = true; 137 } 138 } 139 140 void MeshState::disableTexCoordsVertexArray() { 141 if (mTexCoordsArrayEnabled) { 142 glDisableVertexAttribArray(Program::kBindingTexCoords); 143 mTexCoordsArrayEnabled = false; 144 } 145 } 146 147 /////////////////////////////////////////////////////////////////////////////// 148 // Indices 149 /////////////////////////////////////////////////////////////////////////////// 150 151 bool MeshState::bindIndicesBufferInternal(const GLuint buffer) { 152 if (mCurrentIndicesBuffer != buffer) { 153 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); 154 mCurrentIndicesBuffer = buffer; 155 return true; 156 } 157 return false; 158 } 159 160 bool MeshState::bindQuadIndicesBuffer() { 161 return bindIndicesBufferInternal(mQuadListIndices); 162 } 163 164 bool MeshState::unbindIndicesBuffer() { 165 if (mCurrentIndicesBuffer) { 166 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 167 mCurrentIndicesBuffer = 0; 168 return true; 169 } 170 return false; 171 } 172 173 } /* namespace uirenderer */ 174 } /* namespace android */ 175 176