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