blob: ce6030d16ff0f8dc61f6a1ea23b83e36a3dc0dde [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 Craik96a5c4c2015-01-27 15:46:35 -080034
Chris Craik03188872015-02-02 18:39:33 -080035 glGenBuffers(1, &mUnitQuadBuffer);
36 glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
37 glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
Chris Craik96a5c4c2015-01-27 15:46:35 -080038
Chris Craik03188872015-02-02 18:39:33 -080039 mCurrentBuffer = mUnitQuadBuffer;
Chris Craik6c15ffa2015-02-02 13:50:55 -080040
41 // position attribute always enabled
42 glEnableVertexAttribArray(Program::kBindingPosition);
Chris Craik96a5c4c2015-01-27 15:46:35 -080043}
44
45MeshState::~MeshState() {
Chris Craik03188872015-02-02 18:39:33 -080046 glDeleteBuffers(1, &mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080047 mCurrentBuffer = 0;
48
49 glDeleteBuffers(1, &mQuadListIndices);
50 mQuadListIndices = 0;
Chris Craik117bdbc2015-02-05 10:12:38 -080051}
Chris Craik96a5c4c2015-01-27 15:46:35 -080052
Chris Craik117bdbc2015-02-05 10:12:38 -080053void MeshState::dump() {
54 ALOGD("MeshState vertices: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080055}
56
57///////////////////////////////////////////////////////////////////////////////
58// Buffer Objects
59///////////////////////////////////////////////////////////////////////////////
60
61bool MeshState::bindMeshBuffer() {
Chris Craik03188872015-02-02 18:39:33 -080062 return bindMeshBuffer(mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080063}
64
65bool MeshState::bindMeshBuffer(GLuint buffer) {
Chris Craik03188872015-02-02 18:39:33 -080066 if (!buffer) buffer = mUnitQuadBuffer;
Chris Craik117bdbc2015-02-05 10:12:38 -080067 return bindMeshBufferInternal(buffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080068}
69
70bool MeshState::unbindMeshBuffer() {
Chris Craik117bdbc2015-02-05 10:12:38 -080071 return bindMeshBufferInternal(0);
72}
73
74bool MeshState::bindMeshBufferInternal(GLuint buffer) {
75 if (mCurrentBuffer != buffer) {
76 glBindBuffer(GL_ARRAY_BUFFER, buffer);
77 mCurrentBuffer = buffer;
Chris Craik96a5c4c2015-01-27 15:46:35 -080078 return true;
79 }
80 return false;
81}
82
83///////////////////////////////////////////////////////////////////////////////
84// Vertices
85///////////////////////////////////////////////////////////////////////////////
86
Chris Craik6c15ffa2015-02-02 13:50:55 -080087void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -080088 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -080089 glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -080090 mCurrentPositionPointer = vertices;
91 mCurrentPositionStride = stride;
92 }
93}
94
Chris Craik6c15ffa2015-02-02 13:50:55 -080095void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -080096 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -080097 glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -080098 mCurrentTexCoordsPointer = vertices;
99 mCurrentTexCoordsStride = stride;
100 }
101}
102
103void MeshState::resetVertexPointers() {
104 mCurrentPositionPointer = this;
105 mCurrentTexCoordsPointer = this;
106}
107
108void MeshState::resetTexCoordsVertexPointer() {
109 mCurrentTexCoordsPointer = this;
110}
111
112void MeshState::enableTexCoordsVertexArray() {
113 if (!mTexCoordsArrayEnabled) {
114 glEnableVertexAttribArray(Program::kBindingTexCoords);
115 mCurrentTexCoordsPointer = this;
116 mTexCoordsArrayEnabled = true;
117 }
118}
119
120void MeshState::disableTexCoordsVertexArray() {
121 if (mTexCoordsArrayEnabled) {
122 glDisableVertexAttribArray(Program::kBindingTexCoords);
123 mTexCoordsArrayEnabled = false;
124 }
125}
126
127///////////////////////////////////////////////////////////////////////////////
128// Indices
129///////////////////////////////////////////////////////////////////////////////
130
131bool MeshState::bindIndicesBufferInternal(const GLuint buffer) {
132 if (mCurrentIndicesBuffer != buffer) {
133 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
134 mCurrentIndicesBuffer = buffer;
135 return true;
136 }
137 return false;
138}
139
140bool MeshState::bindQuadIndicesBuffer() {
141 if (!mQuadListIndices) {
142 std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]);
143 for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
144 uint16_t quad = i * 4;
145 int index = i * 6;
146 regionIndices[index ] = quad; // top-left
147 regionIndices[index + 1] = quad + 1; // top-right
148 regionIndices[index + 2] = quad + 2; // bottom-left
149 regionIndices[index + 3] = quad + 2; // bottom-left
150 regionIndices[index + 4] = quad + 1; // top-right
151 regionIndices[index + 5] = quad + 3; // bottom-right
152 }
153
154 glGenBuffers(1, &mQuadListIndices);
155 bool force = bindIndicesBufferInternal(mQuadListIndices);
156 glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t),
157 regionIndices.get(), GL_STATIC_DRAW);
158 return force;
159 }
160
161 return bindIndicesBufferInternal(mQuadListIndices);
162}
163
Chris Craik96a5c4c2015-01-27 15:46:35 -0800164bool 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