blob: a172c562f4a9e4351597db1350771034b042176f [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
Peiyong Lin833074a2018-08-28 11:53:54 -070017#include "Program.h"
Peiyong Lincbc184f2018-08-22 13:24:10 -070018
Mathias Agopian3f844832013-08-07 21:24:32 -070019#include <stdint.h>
20
Mark Salyzyn7823e122016-09-29 08:08:05 -070021#include <log/log.h>
Chia-I Wub027f802017-11-29 14:00:52 -080022#include <math/mat4.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070023#include <utils/String8.h>
Peiyong Lin833074a2018-08-28 11:53:54 -070024#include "ProgramCache.h"
Mathias Agopian3f844832013-08-07 21:24:32 -070025
26namespace android {
Peiyong Lin833074a2018-08-28 11:53:54 -070027namespace renderengine {
28namespace gl {
Mathias Agopian3f844832013-08-07 21:24:32 -070029
Mark Salyzyn92dc3fc2014-03-12 13:12:44 -070030Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const char* fragment)
Chia-I Wub027f802017-11-29 14:00:52 -080031 : mInitialized(false) {
Mathias Agopian3f844832013-08-07 21:24:32 -070032 GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
33 GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
34 GLuint programId = glCreateProgram();
35 glAttachShader(programId, vertexId);
36 glAttachShader(programId, fragmentId);
37 glBindAttribLocation(programId, position, "position");
38 glBindAttribLocation(programId, texCoords, "texCoords");
Lucas Dupin1b6531c2018-07-05 17:18:21 -070039 glBindAttribLocation(programId, cropCoords, "cropCoords");
Vishnu Nair440992f2019-12-09 19:53:19 -080040 glBindAttribLocation(programId, shadowColor, "shadowColor");
41 glBindAttribLocation(programId, shadowParams, "shadowParams");
Mathias Agopian3f844832013-08-07 21:24:32 -070042 glLinkProgram(programId);
43
44 GLint status;
45 glGetProgramiv(programId, GL_LINK_STATUS, &status);
46 if (status != GL_TRUE) {
47 ALOGE("Error while linking shaders:");
48 GLint infoLen = 0;
49 glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
50 if (infoLen > 1) {
51 GLchar log[infoLen];
52 glGetProgramInfoLog(programId, infoLen, 0, &log[0]);
53 ALOGE("%s", log);
54 }
55 glDetachShader(programId, vertexId);
56 glDetachShader(programId, fragmentId);
57 glDeleteShader(vertexId);
58 glDeleteShader(fragmentId);
59 glDeleteProgram(programId);
60 } else {
61 mProgram = programId;
62 mVertexShader = vertexId;
63 mFragmentShader = fragmentId;
64 mInitialized = true;
Mathias Agopian3f844832013-08-07 21:24:32 -070065 mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
66 mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
67 mSamplerLoc = glGetUniformLocation(programId, "sampler");
68 mColorLoc = glGetUniformLocation(programId, "color");
KaiChieh Chuang436fc192020-09-07 13:48:42 +080069 mDisplayColorMatrixLoc = glGetUniformLocation(programId, "displayColorMatrix");
Peiyong Linfb069302018-04-25 14:34:31 -070070 mDisplayMaxLuminanceLoc = glGetUniformLocation(programId, "displayMaxLuminance");
Peiyong Lin1a70eca2019-11-15 09:33:33 -080071 mMaxMasteringLuminanceLoc = glGetUniformLocation(programId, "maxMasteringLuminance");
72 mMaxContentLuminanceLoc = glGetUniformLocation(programId, "maxContentLuminance");
Peiyong Lina296b0c2018-04-30 16:55:29 -070073 mInputTransformMatrixLoc = glGetUniformLocation(programId, "inputTransformMatrix");
74 mOutputTransformMatrixLoc = glGetUniformLocation(programId, "outputTransformMatrix");
Lucas Dupin1b6531c2018-07-05 17:18:21 -070075 mCornerRadiusLoc = glGetUniformLocation(programId, "cornerRadius");
76 mCropCenterLoc = glGetUniformLocation(programId, "cropCenter");
Mathias Agopian3f844832013-08-07 21:24:32 -070077
78 // set-up the default values for our uniforms
79 glUseProgram(programId);
Chia-I Wub027f802017-11-29 14:00:52 -080080 glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, mat4().asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -070081 glEnableVertexAttribArray(0);
82 }
83}
84
Mathias Agopian3f844832013-08-07 21:24:32 -070085bool Program::isValid() const {
86 return mInitialized;
87}
88
89void Program::use() {
90 glUseProgram(mProgram);
91}
92
93GLuint Program::getAttrib(const char* name) const {
94 // TODO: maybe use a local cache
95 return glGetAttribLocation(mProgram, name);
96}
97
98GLint Program::getUniform(const char* name) const {
99 // TODO: maybe use a local cache
100 return glGetUniformLocation(mProgram, name);
101}
102
103GLuint Program::buildShader(const char* source, GLenum type) {
104 GLuint shader = glCreateShader(type);
105 glShaderSource(shader, 1, &source, 0);
106 glCompileShader(shader);
107 GLint status;
108 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
109 if (status != GL_TRUE) {
110 // Some drivers return wrong values for GL_INFO_LOG_LENGTH
111 // use a fixed size instead
112 GLchar log[512];
113 glGetShaderInfoLog(shader, sizeof(log), 0, log);
114 ALOGE("Error while compiling shader: \n%s\n%s", source, log);
115 glDeleteShader(shader);
116 return 0;
117 }
118 return shader;
119}
120
Mathias Agopian3f844832013-08-07 21:24:32 -0700121void Program::setUniforms(const Description& desc) {
Mathias Agopian3f844832013-08-07 21:24:32 -0700122 // TODO: we should have a mechanism here to not always reset uniforms that
123 // didn't change for this program.
124
125 if (mSamplerLoc >= 0) {
126 glUniform1i(mSamplerLoc, 0);
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700127 glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.texture.getMatrix().asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -0700128 }
Mathias Agopian3f844832013-08-07 21:24:32 -0700129 if (mColorLoc >= 0) {
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700130 const float color[4] = {desc.color.r, desc.color.g, desc.color.b, desc.color.a};
chaviw13fdc492017-06-27 12:40:18 -0700131 glUniform4fv(mColorLoc, 1, color);
Mathias Agopian3f844832013-08-07 21:24:32 -0700132 }
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800133 if (mDisplayColorMatrixLoc >= 0) {
134 glUniformMatrix4fv(mDisplayColorMatrixLoc, 1, GL_FALSE, desc.displayColorMatrix.asArray());
135 }
Peiyong Lina296b0c2018-04-30 16:55:29 -0700136 if (mInputTransformMatrixLoc >= 0) {
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700137 mat4 inputTransformMatrix = desc.inputTransformMatrix;
Peiyong Lin00f9c022018-05-09 15:35:33 -0700138 glUniformMatrix4fv(mInputTransformMatrixLoc, 1, GL_FALSE, inputTransformMatrix.asArray());
Peiyong Lina296b0c2018-04-30 16:55:29 -0700139 }
140 if (mOutputTransformMatrixLoc >= 0) {
141 // The output transform matrix and color matrix can be combined as one matrix
142 // that is applied right before applying OETF.
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700143 mat4 outputTransformMatrix = desc.colorMatrix * desc.outputTransformMatrix;
Peiyong Lin46080ef2018-10-26 18:43:14 -0700144 glUniformMatrix4fv(mOutputTransformMatrixLoc, 1, GL_FALSE, outputTransformMatrix.asArray());
Mathias Agopianff2ed702013-09-01 21:36:12 -0700145 }
Peiyong Linfb069302018-04-25 14:34:31 -0700146 if (mDisplayMaxLuminanceLoc >= 0) {
Peiyong Lin46080ef2018-10-26 18:43:14 -0700147 glUniform1f(mDisplayMaxLuminanceLoc, desc.displayMaxLuminance);
Peiyong Linfb069302018-04-25 14:34:31 -0700148 }
Peiyong Lin1a70eca2019-11-15 09:33:33 -0800149 if (mMaxMasteringLuminanceLoc >= 0) {
150 glUniform1f(mMaxMasteringLuminanceLoc, desc.maxMasteringLuminance);
151 }
152 if (mMaxContentLuminanceLoc >= 0) {
153 glUniform1f(mMaxContentLuminanceLoc, desc.maxContentLuminance);
154 }
Lucas Dupin1b6531c2018-07-05 17:18:21 -0700155 if (mCornerRadiusLoc >= 0) {
156 glUniform1f(mCornerRadiusLoc, desc.cornerRadius);
157 }
158 if (mCropCenterLoc >= 0) {
159 glUniform2f(mCropCenterLoc, desc.cropSize.x / 2.0f, desc.cropSize.y / 2.0f);
160 }
Mathias Agopian3f844832013-08-07 21:24:32 -0700161 // these uniforms are always present
Peiyong Lin70b26ce2018-09-18 19:02:39 -0700162 glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.projectionMatrix.asArray());
Mathias Agopian3f844832013-08-07 21:24:32 -0700163}
164
Peiyong Lin46080ef2018-10-26 18:43:14 -0700165} // namespace gl
166} // namespace renderengine
167} // namespace android