summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/RenderEngine/Program.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2013-08-14 15:45:21 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-08-14 15:45:21 -0700
commitb881700ab160b4544453bf8920e3022d46fee262 (patch)
treefb8a662cf54a1be7b1e3d3b11d64f389c1c00cec /services/surfaceflinger/RenderEngine/Program.cpp
parent8bf4e52cdfc3b9a8101d5945124fb7c4fd92c84e (diff)
parent56f825e7ab9f83706a74dcd4825c7bc839e49ae4 (diff)
downloadframeworks_native-b881700ab160b4544453bf8920e3022d46fee262.zip
frameworks_native-b881700ab160b4544453bf8920e3022d46fee262.tar.gz
frameworks_native-b881700ab160b4544453bf8920e3022d46fee262.tar.bz2
am 56f825e7: Merge "SurfaceFlinger now uses GLES 2.x when available" into klp-dev
* commit '56f825e7ab9f83706a74dcd4825c7bc839e49ae4': SurfaceFlinger now uses GLES 2.x when available
Diffstat (limited to 'services/surfaceflinger/RenderEngine/Program.cpp')
-rw-r--r--services/surfaceflinger/RenderEngine/Program.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/services/surfaceflinger/RenderEngine/Program.cpp b/services/surfaceflinger/RenderEngine/Program.cpp
new file mode 100644
index 0000000..586d1ad
--- /dev/null
+++ b/services/surfaceflinger/RenderEngine/Program.cpp
@@ -0,0 +1,144 @@
+/*Gluint
+ * Copyright 2013 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 <stdint.h>
+
+#include <log/log.h>
+
+#include "Program.h"
+#include "ProgramCache.h"
+#include "Description.h"
+#include <utils/String8.h>
+
+namespace android {
+
+Program::Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment)
+ : mInitialized(false) {
+ GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
+ GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
+ GLuint programId = glCreateProgram();
+ glAttachShader(programId, vertexId);
+ glAttachShader(programId, fragmentId);
+ glBindAttribLocation(programId, position, "position");
+ glBindAttribLocation(programId, texCoords, "texCoords");
+ glLinkProgram(programId);
+
+ GLint status;
+ glGetProgramiv(programId, GL_LINK_STATUS, &status);
+ if (status != GL_TRUE) {
+ ALOGE("Error while linking shaders:");
+ GLint infoLen = 0;
+ glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1) {
+ GLchar log[infoLen];
+ glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
+ ALOGE("%s", log);
+ }
+ glDetachShader(programId, vertexId);
+ glDetachShader(programId, fragmentId);
+ glDeleteShader(vertexId);
+ glDeleteShader(fragmentId);
+ glDeleteProgram(programId);
+ } else {
+ mProgram = programId;
+ mVertexShader = vertexId;
+ mFragmentShader = fragmentId;
+ mInitialized = true;
+
+ mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
+ mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
+ mSamplerLoc = glGetUniformLocation(programId, "sampler");
+ mColorLoc = glGetUniformLocation(programId, "color");
+ mAlphaPlaneLoc = glGetUniformLocation(programId, "alphaPlane");
+
+ // set-up the default values for our uniforms
+ glUseProgram(programId);
+ const GLfloat m[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 };
+ glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, m);
+ glEnableVertexAttribArray(0);
+ }
+}
+
+Program::~Program() {
+}
+
+bool Program::isValid() const {
+ return mInitialized;
+}
+
+void Program::use() {
+ glUseProgram(mProgram);
+}
+
+GLuint Program::getAttrib(const char* name) const {
+ // TODO: maybe use a local cache
+ return glGetAttribLocation(mProgram, name);
+}
+
+GLint Program::getUniform(const char* name) const {
+ // TODO: maybe use a local cache
+ return glGetUniformLocation(mProgram, name);
+}
+
+GLuint Program::buildShader(const char* source, GLenum type) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &source, 0);
+ glCompileShader(shader);
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ // Some drivers return wrong values for GL_INFO_LOG_LENGTH
+ // use a fixed size instead
+ GLchar log[512];
+ glGetShaderInfoLog(shader, sizeof(log), 0, log);
+ ALOGE("Error while compiling shader: \n%s\n%s", source, log);
+ glDeleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+String8& Program::dumpShader(String8& result, GLenum type) {
+ GLuint shader = GL_FRAGMENT_SHADER ? mFragmentShader : mVertexShader;
+ GLint l;
+ glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
+ char* src = new char[l];
+ glGetShaderSource(shader, l, NULL, src);
+ result.append(src);
+ delete [] src;
+ return result;
+}
+
+void Program::setUniforms(const Description& desc) {
+
+ // TODO: we should have a mechanism here to not always reset uniforms that
+ // didn't change for this program.
+
+ if (mSamplerLoc >= 0) {
+ glUniform1i(mSamplerLoc, 0);
+ glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTextureMatrix);
+ }
+ if (mAlphaPlaneLoc >= 0) {
+ glUniform1f(mAlphaPlaneLoc, desc.mPlaneAlpha);
+ }
+ if (mColorLoc >= 0) {
+ glUniform4fv(mColorLoc, 1, desc.mColor);
+ }
+ // these uniforms are always present
+ glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix);
+}
+
+} /* namespace android */