Home | History | Annotate | Download | only in RenderEngine
      1 /*Gluint
      2  * Copyright 2013 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 
     17 #include <stdint.h>
     18 
     19 #include <log/log.h>
     20 
     21 #include "Program.h"
     22 #include "ProgramCache.h"
     23 #include "Description.h"
     24 #include <utils/String8.h>
     25 
     26 namespace android {
     27 
     28 Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const char* fragment)
     29         : mInitialized(false) {
     30     GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
     31     GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
     32     GLuint programId = glCreateProgram();
     33     glAttachShader(programId, vertexId);
     34     glAttachShader(programId, fragmentId);
     35     glBindAttribLocation(programId, position, "position");
     36     glBindAttribLocation(programId, texCoords, "texCoords");
     37     glLinkProgram(programId);
     38 
     39     GLint status;
     40     glGetProgramiv(programId, GL_LINK_STATUS, &status);
     41     if (status != GL_TRUE) {
     42         ALOGE("Error while linking shaders:");
     43         GLint infoLen = 0;
     44         glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
     45         if (infoLen > 1) {
     46             GLchar log[infoLen];
     47             glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
     48             ALOGE("%s", log);
     49         }
     50         glDetachShader(programId, vertexId);
     51         glDetachShader(programId, fragmentId);
     52         glDeleteShader(vertexId);
     53         glDeleteShader(fragmentId);
     54         glDeleteProgram(programId);
     55     } else {
     56         mProgram = programId;
     57         mVertexShader = vertexId;
     58         mFragmentShader = fragmentId;
     59         mInitialized = true;
     60 
     61         mColorMatrixLoc = glGetUniformLocation(programId, "colorMatrix");
     62         mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
     63         mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
     64         mSamplerLoc = glGetUniformLocation(programId, "sampler");
     65         mColorLoc = glGetUniformLocation(programId, "color");
     66         mAlphaPlaneLoc = glGetUniformLocation(programId, "alphaPlane");
     67 
     68         // set-up the default values for our uniforms
     69         glUseProgram(programId);
     70         const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
     71         glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, m);
     72         glEnableVertexAttribArray(0);
     73     }
     74 }
     75 
     76 Program::~Program() {
     77 }
     78 
     79 bool Program::isValid() const {
     80     return mInitialized;
     81 }
     82 
     83 void Program::use() {
     84     glUseProgram(mProgram);
     85 }
     86 
     87 GLuint Program::getAttrib(const char* name) const {
     88     // TODO: maybe use a local cache
     89     return glGetAttribLocation(mProgram, name);
     90 }
     91 
     92 GLint Program::getUniform(const char* name) const {
     93     // TODO: maybe use a local cache
     94     return glGetUniformLocation(mProgram, name);
     95 }
     96 
     97 GLuint Program::buildShader(const char* source, GLenum type) {
     98     GLuint shader = glCreateShader(type);
     99     glShaderSource(shader, 1, &source, 0);
    100     glCompileShader(shader);
    101     GLint status;
    102     glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    103     if (status != GL_TRUE) {
    104         // Some drivers return wrong values for GL_INFO_LOG_LENGTH
    105         // use a fixed size instead
    106         GLchar log[512];
    107         glGetShaderInfoLog(shader, sizeof(log), 0, log);
    108         ALOGE("Error while compiling shader: \n%s\n%s", source, log);
    109         glDeleteShader(shader);
    110         return 0;
    111     }
    112     return shader;
    113 }
    114 
    115 String8& Program::dumpShader(String8& result, GLenum /*type*/) {
    116     GLuint shader = GL_FRAGMENT_SHADER ? mFragmentShader : mVertexShader;
    117     GLint l;
    118     glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
    119     char* src = new char[l];
    120     glGetShaderSource(shader, l, NULL, src);
    121     result.append(src);
    122     delete [] src;
    123     return result;
    124 }
    125 
    126 void Program::setUniforms(const Description& desc) {
    127 
    128     // TODO: we should have a mechanism here to not always reset uniforms that
    129     // didn't change for this program.
    130 
    131     if (mSamplerLoc >= 0) {
    132         glUniform1i(mSamplerLoc, 0);
    133         glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray());
    134     }
    135     if (mAlphaPlaneLoc >= 0) {
    136         glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha);
    137     }
    138     if (mColorLoc >= 0) {
    139         glUniform4fv(mColorLoc, 1, desc.mColor);
    140     }
    141     if (mColorMatrixLoc >= 0) {
    142         glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray());
    143     }
    144     // these uniforms are always present
    145     glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix.asArray());
    146 }
    147 
    148 } /* namespace android */
    149