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:
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user