• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace android {
21 namespace uirenderer {
22 
MeshState()23 MeshState::MeshState()
24         : mCurrentIndicesBuffer(0)
25         , mCurrentPixelBuffer(0)
26         , mCurrentPositionPointer(this)
27         , mCurrentPositionStride(0)
28         , mCurrentTexCoordsPointer(this)
29         , mCurrentTexCoordsStride(0)
30         , mTexCoordsArrayEnabled(false)
31         , mQuadListIndices(0) {
32     glGenBuffers(1, &mUnitQuadBuffer);
33     glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer);
34     glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW);
35     mCurrentBuffer = mUnitQuadBuffer;
36 
37     uint16_t regionIndices[kMaxNumberOfQuads * 6];
38     for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) {
39         uint16_t quad = i * 4;
40         int index = i * 6;
41         regionIndices[index    ] = quad;       // top-left
42         regionIndices[index + 1] = quad + 1;   // top-right
43         regionIndices[index + 2] = quad + 2;   // bottom-left
44         regionIndices[index + 3] = quad + 2;   // bottom-left
45         regionIndices[index + 4] = quad + 1;   // top-right
46         regionIndices[index + 5] = quad + 3;   // bottom-right
47     }
48     glGenBuffers(1, &mQuadListIndices);
49     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices);
50     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW);
51     mCurrentIndicesBuffer = mQuadListIndices;
52 
53     // position attribute always enabled
54     glEnableVertexAttribArray(Program::kBindingPosition);
55 }
56 
~MeshState()57 MeshState::~MeshState() {
58     glDeleteBuffers(1, &mUnitQuadBuffer);
59     mCurrentBuffer = 0;
60 
61     glDeleteBuffers(1, &mQuadListIndices);
62     mQuadListIndices = 0;
63 }
64 
dump()65 void MeshState::dump() {
66     ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer);
67     ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer);
68     ALOGD("MeshState vertices: vertex data %p, stride %d",
69             mCurrentPositionPointer, mCurrentPositionStride);
70     ALOGD("MeshState texCoord: data %p, stride %d",
71             mCurrentTexCoordsPointer, mCurrentTexCoordsStride);
72 }
73 
74 ///////////////////////////////////////////////////////////////////////////////
75 // Buffer Objects
76 ///////////////////////////////////////////////////////////////////////////////
77 
bindMeshBuffer(GLuint buffer)78 void MeshState::bindMeshBuffer(GLuint buffer) {
79     if (mCurrentBuffer != buffer) {
80         glBindBuffer(GL_ARRAY_BUFFER, buffer);
81         mCurrentBuffer = buffer;
82 
83         // buffer has changed, so invalidate cached vertex pos/texcoord pointers
84         resetVertexPointers();
85     }
86 }
87 
unbindMeshBuffer()88 void MeshState::unbindMeshBuffer() {
89     return bindMeshBuffer(0);
90 }
91 
genOrUpdateMeshBuffer(GLuint * buffer,GLsizeiptr size,const void * data,GLenum usage)92 void MeshState::genOrUpdateMeshBuffer(GLuint* buffer, GLsizeiptr size,
93         const void* data, GLenum usage) {
94     if (!*buffer) {
95         glGenBuffers(1, buffer);
96     }
97     bindMeshBuffer(*buffer);
98     glBufferData(GL_ARRAY_BUFFER, size, data, usage);
99 }
100 
updateMeshBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr size,const void * data)101 void MeshState::updateMeshBufferSubData(GLuint buffer, GLintptr offset,
102         GLsizeiptr size, const void* data) {
103     bindMeshBuffer(buffer);
104     glBufferSubData(GL_ARRAY_BUFFER, offset, size, data);
105 }
106 
deleteMeshBuffer(GLuint buffer)107 void MeshState::deleteMeshBuffer(GLuint buffer) {
108     if (buffer == mCurrentBuffer) {
109         // GL defines that deleting the currently bound VBO rebinds to 0 (no VBO).
110         // Reflect this in our cached value.
111         mCurrentBuffer = 0;
112     }
113     glDeleteBuffers(1, &buffer);
114 }
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 // Vertices
118 ///////////////////////////////////////////////////////////////////////////////
119 
bindPositionVertexPointer(const GLvoid * vertices,GLsizei stride)120 void MeshState::bindPositionVertexPointer(const GLvoid* vertices, GLsizei stride) {
121     // update pos coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
122     if (mCurrentBuffer == 0
123             || vertices != mCurrentPositionPointer
124             || stride != mCurrentPositionStride) {
125         glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices);
126         mCurrentPositionPointer = vertices;
127         mCurrentPositionStride = stride;
128     }
129 }
130 
bindTexCoordsVertexPointer(const GLvoid * vertices,GLsizei stride)131 void MeshState::bindTexCoordsVertexPointer(const GLvoid* vertices, GLsizei stride) {
132     // update tex coords if !current vbo, since vertices may point into mutable memory (e.g. stack)
133     if (mCurrentBuffer == 0
134             || vertices != mCurrentTexCoordsPointer
135             || stride != mCurrentTexCoordsStride) {
136         glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices);
137         mCurrentTexCoordsPointer = vertices;
138         mCurrentTexCoordsStride = stride;
139     }
140 }
141 
resetVertexPointers()142 void MeshState::resetVertexPointers() {
143     mCurrentPositionPointer = this;
144     mCurrentTexCoordsPointer = this;
145 }
146 
enableTexCoordsVertexArray()147 void MeshState::enableTexCoordsVertexArray() {
148     if (!mTexCoordsArrayEnabled) {
149         glEnableVertexAttribArray(Program::kBindingTexCoords);
150         mCurrentTexCoordsPointer = this;
151         mTexCoordsArrayEnabled = true;
152     }
153 }
154 
disableTexCoordsVertexArray()155 void MeshState::disableTexCoordsVertexArray() {
156     if (mTexCoordsArrayEnabled) {
157         glDisableVertexAttribArray(Program::kBindingTexCoords);
158         mTexCoordsArrayEnabled = false;
159     }
160 }
161 
162 ///////////////////////////////////////////////////////////////////////////////
163 // Indices
164 ///////////////////////////////////////////////////////////////////////////////
165 
bindIndicesBuffer(const GLuint buffer)166 void MeshState::bindIndicesBuffer(const GLuint buffer) {
167     if (mCurrentIndicesBuffer != buffer) {
168         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
169         mCurrentIndicesBuffer = buffer;
170     }
171 }
172 
unbindIndicesBuffer()173 void MeshState::unbindIndicesBuffer() {
174     if (mCurrentIndicesBuffer) {
175         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
176         mCurrentIndicesBuffer = 0;
177     }
178 }
179 
180 } /* namespace uirenderer */
181 } /* namespace android */
182 
183