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
MeshState()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
~MeshState()60 MeshState::~MeshState() {
61 glDeleteBuffers(1, &mUnitQuadBuffer);
62 mCurrentBuffer = 0;
63
64 glDeleteBuffers(1, &mQuadListIndices);
65 mQuadListIndices = 0;
66 }
67
dump()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
bindMeshBuffer()81 bool MeshState::bindMeshBuffer() {
82 return bindMeshBuffer(mUnitQuadBuffer);
83 }
84
bindMeshBuffer(GLuint buffer)85 bool MeshState::bindMeshBuffer(GLuint buffer) {
86 if (!buffer) buffer = mUnitQuadBuffer;
87 return bindMeshBufferInternal(buffer);
88 }
89
unbindMeshBuffer()90 bool MeshState::unbindMeshBuffer() {
91 return bindMeshBufferInternal(0);
92 }
93
bindMeshBufferInternal(GLuint buffer)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
bindPositionVertexPointer(bool force,const GLvoid * vertices,GLsizei stride)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
bindTexCoordsVertexPointer(bool force,const GLvoid * vertices,GLsizei stride)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
resetVertexPointers()123 void MeshState::resetVertexPointers() {
124 mCurrentPositionPointer = this;
125 mCurrentTexCoordsPointer = this;
126 }
127
resetTexCoordsVertexPointer()128 void MeshState::resetTexCoordsVertexPointer() {
129 mCurrentTexCoordsPointer = this;
130 }
131
enableTexCoordsVertexArray()132 void MeshState::enableTexCoordsVertexArray() {
133 if (!mTexCoordsArrayEnabled) {
134 glEnableVertexAttribArray(Program::kBindingTexCoords);
135 mCurrentTexCoordsPointer = this;
136 mTexCoordsArrayEnabled = true;
137 }
138 }
139
disableTexCoordsVertexArray()140 void MeshState::disableTexCoordsVertexArray() {
141 if (mTexCoordsArrayEnabled) {
142 glDisableVertexAttribArray(Program::kBindingTexCoords);
143 mTexCoordsArrayEnabled = false;
144 }
145 }
146
147 ///////////////////////////////////////////////////////////////////////////////
148 // Indices
149 ///////////////////////////////////////////////////////////////////////////////
150
bindIndicesBufferInternal(const GLuint buffer)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
bindQuadIndicesBuffer()160 bool MeshState::bindQuadIndicesBuffer() {
161 return bindIndicesBufferInternal(mQuadListIndices);
162 }
163
unbindIndicesBuffer()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