blob: 225bcf032752adc0f73f6f80501991f08d2d278a [file] [log] [blame]
Mathias Agopian3f844832013-08-07 21:24:32 -07001/*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
Mark Salyzyn7823e122016-09-29 08:08:05 -070019#include <log/log.h>
Mark Salyzyna5e161b2016-09-29 08:08:05 -070020#include <utils/String8.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070021
Chia-I Wub027f802017-11-29 14:00:52 -080022#include <math/mat4.h>
23#include "Description.h"
Mathias Agopian3f844832013-08-07 21:24:32 -070024#include "Program.h"
25#include "ProgramCache.h"
Mathias Agopian3f844832013-08-07 21:24:32 -070026
27namespace android {
28
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070029Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const char* fragment)
Chia-I Wub027f802017-11-29 14:00:52 -080030 : mInitialized(false) {
Mathias Agopian3f844832013-08-07 21:24:32 -070031 GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
32 GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
33 GLuint programId = glCreateProgram();
34 glAttachShader(programId, vertexId);
35 glAttachShader(programId, fragmentId);
36 glBindAttribLocation(programId, position, "position");
37 glBindAttribLocation(programId, texCoords, "texCoords");
38 glLinkProgram(programId);
39
40 GLint status;
41 glGetProgramiv(programId, GL_LINK_STATUS, &status);
42 if (status != GL_TRUE) {
43 ALOGE("Error while linking shaders:");
44 GLint infoLen = 0;
45 glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
46 if (infoLen > 1) {
47 GLchar log[infoLen];
48 glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
49 ALOGE("%s", log);
50 }
51 glDetachShader(programId, vertexId);
52 glDetachShader(programId, fragmentId);
53 glDeleteShader(vertexId);
54 glDeleteShader(fragmentId);
55 glDeleteProgram(programId);
56 } else {
57 mProgram = programId;
58 mVertexShader = vertexId;
59 mFragmentShader = fragmentId;
60 mInitialized = true;
61
Mathias Agopianff2ed702013-09-01 21:36:12 -070062 mColorMatrixLoc = glGetUniformLocation(programId, "colorMatrix");
Mathias Agopian3f844832013-08-07 21:24:32 -070063 mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
64 mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
65 mSamplerLoc = glGetUniformLocation(programId, "sampler");
66 mColorLoc = glGetUniformLocation(programId, "color");
Mathias Agopian3f844832013-08-07 21:24:32 -070067
68 // set-up the default values for our uniforms
69 glUseProgram(programId);
Chia-I Wub027f802017-11-29 14:00:52 -080070 glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, mat4().asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -070071 glEnableVertexAttribArray(0);
72 }
73}
74
Chia-I Wub027f802017-11-29 14:00:52 -080075Program::~Program() {}
Mathias Agopian3f844832013-08-07 21:24:32 -070076
77bool Program::isValid() const {
78 return mInitialized;
79}
80
81void Program::use() {
82 glUseProgram(mProgram);
83}
84
85GLuint Program::getAttrib(const char* name) const {
86 // TODO: maybe use a local cache
87 return glGetAttribLocation(mProgram, name);
88}
89
90GLint Program::getUniform(const char* name) const {
91 // TODO: maybe use a local cache
92 return glGetUniformLocation(mProgram, name);
93}
94
95GLuint Program::buildShader(const char* source, GLenum type) {
96 GLuint shader = glCreateShader(type);
97 glShaderSource(shader, 1, &source, 0);
98 glCompileShader(shader);
99 GLint status;
100 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
101 if (status != GL_TRUE) {
102 // Some drivers return wrong values for GL_INFO_LOG_LENGTH
103 // use a fixed size instead
104 GLchar log[512];
105 glGetShaderInfoLog(shader, sizeof(log), 0, log);
106 ALOGE("Error while compiling shader: \n%s\n%s", source, log);
107 glDeleteShader(shader);
108 return 0;
109 }
110 return shader;
111}
112
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -0700113String8& Program::dumpShader(String8& result, GLenum /*type*/) {
Mathias Agopian3f844832013-08-07 21:24:32 -0700114 GLuint shader = GL_FRAGMENT_SHADER ? mFragmentShader : mVertexShader;
115 GLint l;
116 glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &l);
117 char* src = new char[l];
Peiyong Lin566a3b42018-01-09 18:22:43 -0800118 glGetShaderSource(shader, l, nullptr, src);
Mathias Agopian3f844832013-08-07 21:24:32 -0700119 result.append(src);
Chia-I Wub027f802017-11-29 14:00:52 -0800120 delete[] src;
Mathias Agopian3f844832013-08-07 21:24:32 -0700121 return result;
122}
123
124void Program::setUniforms(const Description& desc) {
Mathias Agopian3f844832013-08-07 21:24:32 -0700125 // TODO: we should have a mechanism here to not always reset uniforms that
126 // didn't change for this program.
127
128 if (mSamplerLoc >= 0) {
129 glUniform1i(mSamplerLoc, 0);
Mathias Agopiana8c386f2013-08-26 20:42:07 -0700130 glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.mTexture.getMatrix().asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -0700131 }
Mathias Agopian3f844832013-08-07 21:24:32 -0700132 if (mColorLoc >= 0) {
chaviw89e197a2017-10-05 15:38:42 -0700133 const float color[4] = {desc.mColor.r, desc.mColor.g, desc.mColor.b, desc.mColor.a};
chaviw13fdc492017-06-27 12:40:18 -0700134 glUniform4fv(mColorLoc, 1, color);
Mathias Agopian3f844832013-08-07 21:24:32 -0700135 }
Mathias Agopianff2ed702013-09-01 21:36:12 -0700136 if (mColorMatrixLoc >= 0) {
137 glUniformMatrix4fv(mColorMatrixLoc, 1, GL_FALSE, desc.mColorMatrix.asArray());
138 }
Mathias Agopian3f844832013-08-07 21:24:32 -0700139 // these uniforms are always present
Mathias Agopiana8c386f2013-08-26 20:42:07 -0700140 glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.mProjectionMatrix.asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -0700141}
142
143} /* namespace android */