Android GLShader: Check return value of glCreateShader()

This CL adds a check to see if the return value of GLES20.glCreateShader() is zero. Also, shaders are flagged for deletion immediately after glLinkProgram() instead of doing it in release().

BUG=b/27197590

Review URL: https://codereview.webrtc.org/1702953002

Cr-Commit-Position: refs/heads/master@{#11668}
This commit is contained in:
magjed
2016-02-18 03:47:44 -08:00
committed by Commit bot
parent 3ee73a59ad
commit 347c0bb5b5

View File

@ -21,14 +21,17 @@ public class GlShader {
private static final String TAG = "GlShader";
private static int compileShader(int shaderType, String source) {
int[] result = new int[] {
GLES20.GL_FALSE
};
int shader = GLES20.glCreateShader(shaderType);
final int shader = GLES20.glCreateShader(shaderType);
if (shader == 0) {
throw new RuntimeException("glCreateShader() failed. GLES20 error: " + GLES20.glGetError());
}
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, result, 0);
if (result[0] != GLES20.GL_TRUE) {
int[] compileStatus = new int[] {
GLES20.GL_FALSE
};
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
if (compileStatus[0] != GLES20.GL_TRUE) {
Logging.e(TAG, "Could not compile shader " + shaderType + ":" +
GLES20.glGetShaderInfoLog(shader));
throw new RuntimeException(GLES20.glGetShaderInfoLog(shader));
@ -37,16 +40,14 @@ public class GlShader {
return shader;
}
private int vertexShader;
private int fragmentShader;
private int program;
public GlShader(String vertexSource, String fragmentSource) {
vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource);
fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
final int vertexShader = compileShader(GLES20.GL_VERTEX_SHADER, vertexSource);
final int fragmentShader = compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
program = GLES20.glCreateProgram();
if (program == 0) {
throw new RuntimeException("Could not create program");
throw new RuntimeException("glCreateProgram() failed. GLES20 error: " + GLES20.glGetError());
}
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
@ -60,6 +61,15 @@ public class GlShader {
GLES20.glGetProgramInfoLog(program));
throw new RuntimeException(GLES20.glGetProgramInfoLog(program));
}
// According to the documentation of glLinkProgram():
// "After the link operation, applications are free to modify attached shader objects, compile
// attached shader objects, detach shader objects, delete shader objects, and attach additional
// shader objects. None of these operations affects the information log or the program that is
// part of the program object."
// But in practice, detaching shaders from the program seems to break some devices. Deleting the
// shaders are fine however - it will delete them when they are no longer attached to a program.
GLES20.glDeleteShader(vertexShader);
GLES20.glDeleteShader(fragmentShader);
GlUtil.checkNoGLES2Error("Creating GlShader");
}
@ -109,15 +119,6 @@ public class GlShader {
public void release() {
Logging.d(TAG, "Deleting shader.");
// Flag shaders for deletion (does not delete until no longer attached to a program).
if (vertexShader != -1) {
GLES20.glDeleteShader(vertexShader);
vertexShader = -1;
}
if (fragmentShader != -1) {
GLES20.glDeleteShader(fragmentShader);
fragmentShader = -1;
}
// Delete program, automatically detaching any shaders from it.
if (program != -1) {
GLES20.glDeleteProgram(program);