blob: 03cb5ce8ce2e9e95fec814cb3c3405108f513ad9 [file] [log] [blame]
Chris Craik96a5c4c2015-01-27 15:46:35 -08001/*
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
22namespace android {
23namespace uirenderer {
24
25MeshState::MeshState()
Chris Craik117bdbc2015-02-05 10:12:38 -080026 : mCurrentIndicesBuffer(0)
27 , mCurrentPixelBuffer(0)
28 , mCurrentPositionPointer(this)
Chris Craik96a5c4c2015-01-27 15:46:35 -080029 , mCurrentPositionStride(0)
30 , mCurrentTexCoordsPointer(this)
31 , mCurrentTexCoordsStride(0)
Chris Craik117bdbc2015-02-05 10:12:38 -080032 , mTexCoordsArrayEnabled(false)
33 , mQuadListIndices(0) {
Chris Craik03188872015-02-02 18:39:33 -080034 glGenBuffers(1, &mUnitQuadBuffer);
35 glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
36 glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
Chris Craik96a5c4c2015-01-27 15:46:35 -080037
Chris Craik03188872015-02-02 18:39:33 -080038 mCurrentBuffer = mUnitQuadBuffer;
Chris Craik6c15ffa2015-02-02 13:50:55 -080039
Chris Craik182952f2015-03-09 14:17:29 -070040 uint16_t regionIndices[kMaxNumberOfQuads * 6];
Chris Craik2ab95d72015-02-06 15:25:51 -080041 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);
Chris Craik182952f2015-03-09 14:17:29 -070053 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW);
Chris Craik2ab95d72015-02-06 15:25:51 -080054 mCurrentIndicesBuffer = mQuadListIndices;
55
Chris Craik6c15ffa2015-02-02 13:50:55 -080056 // position attribute always enabled
57 glEnableVertexAttribArray(Program::kBindingPosition);
Chris Craik96a5c4c2015-01-27 15:46:35 -080058}
59
60MeshState::~MeshState() {
Chris Craik03188872015-02-02 18:39:33 -080061 glDeleteBuffers(1, &mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080062 mCurrentBuffer = 0;
63
64 glDeleteBuffers(1, &mQuadListIndices);
65 mQuadListIndices = 0;
Chris Craik117bdbc2015-02-05 10:12:38 -080066}
Chris Craik96a5c4c2015-01-27 15:46:35 -080067
Chris Craik117bdbc2015-02-05 10:12:38 -080068void MeshState::dump() {
Chris Craik08fa43f2015-02-09 18:58:32 -080069 ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
Chris Craikf27133d2015-02-19 09:51:53 -080070 ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer);
Chris Craik08fa43f2015-02-09 18:58:32 -080071 ALOGD("MeshState vertices: vertex data %p, stride %d",
72 mCurrentPositionPointer, mCurrentPositionStride);
73 ALOGD("MeshState texCoord: data %p, stride %d",
74 mCurrentTexCoordsPointer, mCurrentTexCoordsStride);
Chris Craik96a5c4c2015-01-27 15:46:35 -080075}
76
77///////////////////////////////////////////////////////////////////////////////
78// Buffer Objects
79///////////////////////////////////////////////////////////////////////////////
80
81bool MeshState::bindMeshBuffer() {
Chris Craik03188872015-02-02 18:39:33 -080082 return bindMeshBuffer(mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080083}
84
85bool MeshState::bindMeshBuffer(GLuint buffer) {
Chris Craik03188872015-02-02 18:39:33 -080086 if (!buffer) buffer = mUnitQuadBuffer;
Chris Craik117bdbc2015-02-05 10:12:38 -080087 return bindMeshBufferInternal(buffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080088}
89
90bool MeshState::unbindMeshBuffer() {
Chris Craik117bdbc2015-02-05 10:12:38 -080091 return bindMeshBufferInternal(0);
92}
93
94bool MeshState::bindMeshBufferInternal(GLuint buffer) {
95 if (mCurrentBuffer != buffer) {
96 glBindBuffer(GL_ARRAY_BUFFER, buffer);
97 mCurrentBuffer = buffer;
Chris Craik96a5c4c2015-01-27 15:46:35 -080098 return true;
99 }
100 return false;
101}
102
Chris Craik8d2cf942015-11-02 14:52:21 -0800103void MeshState::genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size,
104 const void* data, GLenum usage) {
105 if (!*buffer) {
106 glGenBuffers(1, buffer);
107 }
108 bindMeshBuffer(*buffer);
109 glBufferData(GL_ARRAY_BUFFER, size, data, usage);
110}
111
112void MeshState::deleteMeshBuffer(GLuint buffer) {
113 if (buffer == mCurrentBuffer) {
114 // GL defines that deleting the currently bound VBO rebinds to 0 (no VBO).
115 // Reflect this in our cached value.
116 mCurrentBuffer = 0;
117 }
118 glDeleteBuffers(1, &buffer);
119}
120
Chris Craik96a5c4c2015-01-27 15:46:35 -0800121///////////////////////////////////////////////////////////////////////////////
122// Vertices
123///////////////////////////////////////////////////////////////////////////////
124
Chris Craik6c15ffa2015-02-02 13:50:55 -0800125void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800126 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -0800127 glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -0800128 mCurrentPositionPointer = vertices;
129 mCurrentPositionStride = stride;
130 }
131}
132
Chris Craik6c15ffa2015-02-02 13:50:55 -0800133void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800134 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -0800135 glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -0800136 mCurrentTexCoordsPointer = vertices;
137 mCurrentTexCoordsStride = stride;
138 }
139}
140
141void MeshState::resetVertexPointers() {
142 mCurrentPositionPointer = this;
143 mCurrentTexCoordsPointer = this;
144}
145
146void MeshState::resetTexCoordsVertexPointer() {
147 mCurrentTexCoordsPointer = this;
148}
149
150void MeshState::enableTexCoordsVertexArray() {
151 if (!mTexCoordsArrayEnabled) {
152 glEnableVertexAttribArray(Program::kBindingTexCoords);
153 mCurrentTexCoordsPointer = this;
154 mTexCoordsArrayEnabled = true;
155 }
156}
157
158void MeshState::disableTexCoordsVertexArray() {
159 if (mTexCoordsArrayEnabled) {
160 glDisableVertexAttribArray(Program::kBindingTexCoords);
161 mTexCoordsArrayEnabled = false;
162 }
163}
164
165///////////////////////////////////////////////////////////////////////////////
166// Indices
167///////////////////////////////////////////////////////////////////////////////
168
169bool MeshState::bindIndicesBufferInternal(const GLuint buffer) {
170 if (mCurrentIndicesBuffer != buffer) {
171 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
172 mCurrentIndicesBuffer = buffer;
173 return true;
174 }
175 return false;
176}
177
178bool MeshState::bindQuadIndicesBuffer() {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800179 return bindIndicesBufferInternal(mQuadListIndices);
180}
181
Chris Craik96a5c4c2015-01-27 15:46:35 -0800182bool MeshState::unbindIndicesBuffer() {
183 if (mCurrentIndicesBuffer) {
184 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
185 mCurrentIndicesBuffer = 0;
186 return true;
187 }
188 return false;
189}
190
191} /* namespace uirenderer */
192} /* namespace android */
193