diff options
Diffstat (limited to 'libs/hwui/renderstate/MeshState.cpp')
| -rw-r--r-- | libs/hwui/renderstate/MeshState.cpp | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/libs/hwui/renderstate/MeshState.cpp b/libs/hwui/renderstate/MeshState.cpp new file mode 100644 index 0000000..0521f65 --- /dev/null +++ b/libs/hwui/renderstate/MeshState.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "renderstate/MeshState.h" + +#include "Program.h" + +#include "ShadowTessellator.h" + +namespace android { +namespace uirenderer { + +MeshState::MeshState() + : mCurrentIndicesBuffer(0) + , mCurrentPixelBuffer(0) + , mCurrentPositionPointer(this) + , mCurrentPositionStride(0) + , mCurrentTexCoordsPointer(this) + , mCurrentTexCoordsStride(0) + , mTexCoordsArrayEnabled(false) + , mQuadListIndices(0) { + glGenBuffers(1, &mUnitQuadBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW); + + mCurrentBuffer = mUnitQuadBuffer; + + uint16_t regionIndices[kMaxNumberOfQuads * 6]; + for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { + uint16_t quad = i * 4; + int index = i * 6; + regionIndices[index ] = quad; // top-left + regionIndices[index + 1] = quad + 1; // top-right + regionIndices[index + 2] = quad + 2; // bottom-left + regionIndices[index + 3] = quad + 2; // bottom-left + regionIndices[index + 4] = quad + 1; // top-right + regionIndices[index + 5] = quad + 3; // bottom-right + } + glGenBuffers(1, &mQuadListIndices); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(regionIndices), regionIndices, GL_STATIC_DRAW); + mCurrentIndicesBuffer = mQuadListIndices; + + // position attribute always enabled + glEnableVertexAttribArray(Program::kBindingPosition); +} + +MeshState::~MeshState() { + glDeleteBuffers(1, &mUnitQuadBuffer); + mCurrentBuffer = 0; + + glDeleteBuffers(1, &mQuadListIndices); + mQuadListIndices = 0; +} + +void MeshState::dump() { + ALOGD("MeshState VBOs: unitQuad %d, current %d", mUnitQuadBuffer, mCurrentBuffer); + ALOGD("MeshState IBOs: quadList %d, current %d", mQuadListIndices, mCurrentIndicesBuffer); + ALOGD("MeshState vertices: vertex data %p, stride %d", + mCurrentPositionPointer, mCurrentPositionStride); + ALOGD("MeshState texCoord: data %p, stride %d", + mCurrentTexCoordsPointer, mCurrentTexCoordsStride); +} + +/////////////////////////////////////////////////////////////////////////////// +// Buffer Objects +/////////////////////////////////////////////////////////////////////////////// + +bool MeshState::bindMeshBuffer() { + return bindMeshBuffer(mUnitQuadBuffer); +} + +bool MeshState::bindMeshBuffer(GLuint buffer) { + if (!buffer) buffer = mUnitQuadBuffer; + return bindMeshBufferInternal(buffer); +} + +bool MeshState::unbindMeshBuffer() { + return bindMeshBufferInternal(0); +} + +bool MeshState::bindMeshBufferInternal(GLuint buffer) { + if (mCurrentBuffer != buffer) { + glBindBuffer(GL_ARRAY_BUFFER, buffer); + mCurrentBuffer = buffer; + return true; + } + return false; +} + +/////////////////////////////////////////////////////////////////////////////// +// Vertices +/////////////////////////////////////////////////////////////////////////////// + +void MeshState::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { + if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { + glVertexAttribPointer(Program::kBindingPosition, 2, GL_FLOAT, GL_FALSE, stride, vertices); + mCurrentPositionPointer = vertices; + mCurrentPositionStride = stride; + } +} + +void MeshState::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { + if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { + glVertexAttribPointer(Program::kBindingTexCoords, 2, GL_FLOAT, GL_FALSE, stride, vertices); + mCurrentTexCoordsPointer = vertices; + mCurrentTexCoordsStride = stride; + } +} + +void MeshState::resetVertexPointers() { + mCurrentPositionPointer = this; + mCurrentTexCoordsPointer = this; +} + +void MeshState::resetTexCoordsVertexPointer() { + mCurrentTexCoordsPointer = this; +} + +void MeshState::enableTexCoordsVertexArray() { + if (!mTexCoordsArrayEnabled) { + glEnableVertexAttribArray(Program::kBindingTexCoords); + mCurrentTexCoordsPointer = this; + mTexCoordsArrayEnabled = true; + } +} + +void MeshState::disableTexCoordsVertexArray() { + if (mTexCoordsArrayEnabled) { + glDisableVertexAttribArray(Program::kBindingTexCoords); + mTexCoordsArrayEnabled = false; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Indices +/////////////////////////////////////////////////////////////////////////////// + +bool MeshState::bindIndicesBufferInternal(const GLuint buffer) { + if (mCurrentIndicesBuffer != buffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); + mCurrentIndicesBuffer = buffer; + return true; + } + return false; +} + +bool MeshState::bindQuadIndicesBuffer() { + return bindIndicesBufferInternal(mQuadListIndices); +} + +bool MeshState::unbindIndicesBuffer() { + if (mCurrentIndicesBuffer) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + mCurrentIndicesBuffer = 0; + return true; + } + return false; +} + +} /* namespace uirenderer */ +} /* namespace android */ + |
