blob: 5efac0ebbb48705dec70cb3ae86b5fff2034b294 [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 Craik2ab95d72015-02-06 15:25:51 -080040 std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[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, kMaxNumberOfQuads * 6 * sizeof(uint16_t),
54 regionIndices.get(), GL_STATIC_DRAW);
55 mCurrentIndicesBuffer = mQuadListIndices;
56
Chris Craik6c15ffa2015-02-02 13:50:55 -080057 // position attribute always enabled
58 glEnableVertexAttribArray(Program::kBindingPosition);
Chris Craik96a5c4c2015-01-27 15:46:35 -080059}
60
61MeshState::~MeshState() {
Chris Craik03188872015-02-02 18:39:33 -080062 glDeleteBuffers(1, &mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080063 mCurrentBuffer = 0;
64
65 glDeleteBuffers(1, &mQuadListIndices);
66 mQuadListIndices = 0;
Chris Craik117bdbc2015-02-05 10:12:38 -080067}
Chris Craik96a5c4c2015-01-27 15:46:35 -080068
Chris Craik117bdbc2015-02-05 10:12:38 -080069void MeshState::dump() {
70 ALOGD("MeshState vertices: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080071}
72
73///////////////////////////////////////////////////////////////////////////////
74// Buffer Objects
75///////////////////////////////////////////////////////////////////////////////
76
77bool MeshState::bindMeshBuffer() {
Chris Craik03188872015-02-02 18:39:33 -080078 return bindMeshBuffer(mUnitQuadBuffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080079}
80
81bool MeshState::bindMeshBuffer(GLuint buffer) {
Chris Craik03188872015-02-02 18:39:33 -080082 if (!buffer) buffer = mUnitQuadBuffer;
Chris Craik117bdbc2015-02-05 10:12:38 -080083 return bindMeshBufferInternal(buffer);
Chris Craik96a5c4c2015-01-27 15:46:35 -080084}
85
86bool MeshState::unbindMeshBuffer() {
Chris Craik117bdbc2015-02-05 10:12:38 -080087 return bindMeshBufferInternal(0);
88}
89
90bool MeshState::bindMeshBufferInternal(GLuint buffer) {
91 if (mCurrentBuffer != buffer) {
92 glBindBuffer(GL_ARRAY_BUFFER, buffer);
93 mCurrentBuffer = buffer;
Chris Craik96a5c4c2015-01-27 15:46:35 -080094 return true;
95 }
96 return false;
97}
98
99///////////////////////////////////////////////////////////////////////////////
100// Vertices
101///////////////////////////////////////////////////////////////////////////////
102
Chris Craik6c15ffa2015-02-02 13:50:55 -0800103void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800104 if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -0800105 glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -0800106 mCurrentPositionPointer = vertices;
107 mCurrentPositionStride = stride;
108 }
109}
110
Chris Craik6c15ffa2015-02-02 13:50:55 -0800111void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800112 if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
Chris Craik6c15ffa2015-02-02 13:50:55 -0800113 glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
Chris Craik96a5c4c2015-01-27 15:46:35 -0800114 mCurrentTexCoordsPointer = vertices;
115 mCurrentTexCoordsStride = stride;
116 }
117}
118
119void MeshState::resetVertexPointers() {
120 mCurrentPositionPointer = this;
121 mCurrentTexCoordsPointer = this;
122}
123
124void MeshState::resetTexCoordsVertexPointer() {
125 mCurrentTexCoordsPointer = this;
126}
127
128void MeshState::enableTexCoordsVertexArray() {
129 if (!mTexCoordsArrayEnabled) {
130 glEnableVertexAttribArray(Program::kBindingTexCoords);
131 mCurrentTexCoordsPointer = this;
132 mTexCoordsArrayEnabled = true;
133 }
134}
135
136void MeshState::disableTexCoordsVertexArray() {
137 if (mTexCoordsArrayEnabled) {
138 glDisableVertexAttribArray(Program::kBindingTexCoords);
139 mTexCoordsArrayEnabled = false;
140 }
141}
142
143///////////////////////////////////////////////////////////////////////////////
144// Indices
145///////////////////////////////////////////////////////////////////////////////
146
147bool MeshState::bindIndicesBufferInternal(const GLuint buffer) {
148 if (mCurrentIndicesBuffer != buffer) {
149 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
150 mCurrentIndicesBuffer = buffer;
151 return true;
152 }
153 return false;
154}
155
156bool MeshState::bindQuadIndicesBuffer() {
Chris Craik96a5c4c2015-01-27 15:46:35 -0800157 return bindIndicesBufferInternal(mQuadListIndices);
158}
159
Chris Craik96a5c4c2015-01-27 15:46:35 -0800160bool MeshState::unbindIndicesBuffer() {
161 if (mCurrentIndicesBuffer) {
162 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
163 mCurrentIndicesBuffer = 0;
164 return true;
165 }
166 return false;
167}
168
169} /* namespace uirenderer */
170} /* namespace android */
171