2 * Copyright 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <utils/String8.h>
23 #include "ProgramCache.h"
24 #include "Description.h"
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);
40 glGetProgramiv(programId, GL_LINK_STATUS, &status);
41 if (status != GL_TRUE) {
42 ALOGE("Error while linking shaders:");
44 glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
47 glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
50 glDetachShader(programId, vertexId);
51 glDetachShader(programId, fragmentId);
52 glDeleteShader(vertexId);
53 glDeleteShader(fragmentId);
54 glDeleteProgram(programId);
57 mVertexShader = vertexId;
58 mFragmentShader = fragmentId;
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");
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);
79 bool Program::isValid() const {
84 glUseProgram(mProgram);
87 GLuint Program::getAttrib(const char* name) const {
88 // TODO: maybe use a local cache
89 return glGetAttribLocation(mProgram, name);
92 GLint Program::getUniform(const char* name) const {
93 // TODO: maybe use a local cache
94 return glGetUniformLocation(mProgram, name);
97 GLuint Program::buildShader(const char* source, GLenum type) {
98 GLuint shader = glCreateShader(type);
99 glShaderSource(shader, 1, &source, 0);
100 glCompileShader(shader);
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
107 glGetShaderInfoLog(shader, sizeof(log), 0, log);
108 ALOGE("Error while compiling shader: \n%s\n%s", source, log);
109 glDeleteShader(shader);
115 String8& Program::dumpShader(String8& result, GLenum /*type*/) {
116 GLuint shader = GL_FRAGMENT_SHADER ? mFragmentShader : mVertexShader;
118 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
119 char* src = new char[l];
120 glGetShaderSource(shader, l, NULL, src);
126 void Program::setUniforms(const Description& desc) {
128 // TODO: we should have a mechanism here to not always reset uniforms that
129 // didn't change for this program.
131 if (mSamplerLoc >= 0) {
132 glUniform1i(mSamplerLoc, 0);
133 glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray());
135 if (mAlphaPlaneLoc >= 0) {
136 glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha);
138 if (mColorLoc >= 0) {
139 glUniform4fv(mColorLoc, 1, desc.mColor);
141 if (mColorMatrixLoc >= 0) {
142 glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray());
144 // these uniforms are always present
145 glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix.asArray());
148 } /* namespace android */