GL: Misc GL refactoring.

* Remove GlUtil.Program String[] constructor to unify and just use the
  String constructor.
* Add getAttributeArrayLocationAndEnable() to simplify things a tiny bit.
* Increase usage of constant values.

PiperOrigin-RevId: 407570340
This commit is contained in:
huangdarwin 2021-11-04 13:58:55 +00:00 committed by Ian Baker
parent b87f26490b
commit edc4bd5be1
4 changed files with 60 additions and 69 deletions

View File

@ -26,7 +26,6 @@ import android.opengl.EGLDisplay;
import android.opengl.EGLSurface; import android.opengl.EGLSurface;
import android.opengl.GLES11Ext; import android.opengl.GLES11Ext;
import android.opengl.GLES20; import android.opengl.GLES20;
import android.text.TextUtils;
import androidx.annotation.DoNotInline; import androidx.annotation.DoNotInline;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
@ -88,18 +87,6 @@ public final class GlUtil {
this(loadAsset(context, vertexShaderFilePath), loadAsset(context, fragmentShaderFilePath)); this(loadAsset(context, vertexShaderFilePath), loadAsset(context, fragmentShaderFilePath));
} }
/**
* Compiles a GL shader program from vertex and fragment shader GLSL GLES20 code.
*
* @param vertexShaderGlsl The vertex shader program as arrays of strings. Strings are joined by
* adding a new line character in between each of them.
* @param fragmentShaderGlsl The fragment shader program as arrays of strings. Strings are
* joined by adding a new line character in between each of them.
*/
public Program(String[] vertexShaderGlsl, String[] fragmentShaderGlsl) {
this(TextUtils.join("\n", vertexShaderGlsl), TextUtils.join("\n", fragmentShaderGlsl));
}
/** Uses the program. */ /** Uses the program. */
public void use() { public void use() {
// Link and check for errors. // Link and check for errors.
@ -120,8 +107,19 @@ public final class GlUtil {
GLES20.glDeleteProgram(programId); GLES20.glDeleteProgram(programId);
} }
/**
* Returns the location of an {@link Attribute}, which has been enabled as a vertex attribute
* array.
*/
public int getAttributeArrayLocationAndEnable(String attributeName) {
int location = getAttributeLocation(attributeName);
GLES20.glEnableVertexAttribArray(location);
checkGlError();
return location;
}
/** Returns the location of an {@link Attribute}. */ /** Returns the location of an {@link Attribute}. */
public int getAttribLocation(String attributeName) { private int getAttributeLocation(String attributeName) {
return GLES20.glGetAttribLocation(programId, attributeName); return GLES20.glGetAttribLocation(programId, attributeName);
} }
@ -135,7 +133,7 @@ public final class GlUtil {
int[] attributeCount = new int[1]; int[] attributeCount = new int[1];
GLES20.glGetProgramiv(programId, GLES20.GL_ACTIVE_ATTRIBUTES, attributeCount, 0); GLES20.glGetProgramiv(programId, GLES20.GL_ACTIVE_ATTRIBUTES, attributeCount, 0);
if (attributeCount[0] != 2) { if (attributeCount[0] != 2) {
throw new IllegalStateException("Expected two attributes."); throw new IllegalStateException("Expected two attributes but found " + attributeCount[0]);
} }
Attribute[] attributes = new Attribute[attributeCount[0]]; Attribute[] attributes = new Attribute[attributeCount[0]];
@ -170,7 +168,7 @@ public final class GlUtil {
GLES20.glGetActiveAttrib( GLES20.glGetActiveAttrib(
programId, index, length[0], ignore, 0, size, 0, type, 0, nameBytes, 0); programId, index, length[0], ignore, 0, size, 0, type, 0, nameBytes, 0);
String name = new String(nameBytes, 0, strlen(nameBytes)); String name = new String(nameBytes, 0, strlen(nameBytes));
int location = getAttribLocation(name); int location = getAttributeLocation(name);
return new Attribute(name, index, location); return new Attribute(name, index, location);
} }

View File

@ -169,8 +169,7 @@ public final class VideoDecoderGLSurfaceView extends GLSurfaceView
public void onSurfaceCreated(GL10 unused, EGLConfig config) { public void onSurfaceCreated(GL10 unused, EGLConfig config) {
program = new GlUtil.Program(VERTEX_SHADER, FRAGMENT_SHADER); program = new GlUtil.Program(VERTEX_SHADER, FRAGMENT_SHADER);
program.use(); program.use();
int posLocation = program.getAttribLocation("in_pos"); int posLocation = program.getAttributeArrayLocationAndEnable("in_pos");
GLES20.glEnableVertexAttribArray(posLocation);
GLES20.glVertexAttribPointer( GLES20.glVertexAttribPointer(
posLocation, posLocation,
2, 2,
@ -178,13 +177,9 @@ public final class VideoDecoderGLSurfaceView extends GLSurfaceView
/* normalized= */ false, /* normalized= */ false,
/* stride= */ 0, /* stride= */ 0,
TEXTURE_VERTICES); TEXTURE_VERTICES);
texLocations[0] = program.getAttribLocation("in_tc_y"); texLocations[0] = program.getAttributeArrayLocationAndEnable("in_tc_y");
GLES20.glEnableVertexAttribArray(texLocations[0]); texLocations[1] = program.getAttributeArrayLocationAndEnable("in_tc_u");
texLocations[1] = program.getAttribLocation("in_tc_u"); texLocations[2] = program.getAttributeArrayLocationAndEnable("in_tc_v");
GLES20.glEnableVertexAttribArray(texLocations[1]);
texLocations[2] = program.getAttribLocation("in_tc_v");
GLES20.glEnableVertexAttribArray(texLocations[2]);
GlUtil.checkGlError();
colorMatrixLocation = program.getUniformLocation("mColorConversion"); colorMatrixLocation = program.getUniformLocation("mColorConversion");
GlUtil.checkGlError(); GlUtil.checkGlError();
setupTextures(); setupTextures();
@ -257,9 +252,9 @@ public final class VideoDecoderGLSurfaceView extends GLSurfaceView
int[] widths = new int[3]; int[] widths = new int[3];
widths[0] = outputBuffer.width; widths[0] = outputBuffer.width;
// TODO: Handle streams where chroma channels are not stored at half width and height // TODO(b/142097774): Handle streams where chroma channels are not stored at half width and
// compared to luma channel. See [Internal: b/142097774]. // height compared to the luma channel. U and V planes are being stored at half width compared
// U and V planes are being stored at half width compared to Y. // to Y.
widths[1] = widths[2] = (widths[0] + 1) / 2; widths[1] = widths[2] = (widths[0] + 1) / 2;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
// Set cropping of stride if either width or stride has changed. // Set cropping of stride if either width or stride has changed.

View File

@ -46,33 +46,27 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
// Basic vertex & fragment shaders to render a mesh with 3D position & 2D texture data. // Basic vertex & fragment shaders to render a mesh with 3D position & 2D texture data.
private static final String[] VERTEX_SHADER_CODE = private static final String VERTEX_SHADER =
new String[] { "uniform mat4 uMvpMatrix;\n"
"uniform mat4 uMvpMatrix;", + "uniform mat3 uTexMatrix;\n"
"uniform mat3 uTexMatrix;", + "attribute vec4 aPosition;\n"
"attribute vec4 aPosition;", + "attribute vec2 aTexCoords;\n"
"attribute vec2 aTexCoords;", + "varying vec2 vTexCoords;\n"
"varying vec2 vTexCoords;", + "// Standard transformation.\n"
+ "void main() {\n"
// Standard transformation. + " gl_Position = uMvpMatrix * aPosition;\n"
"void main() {", + " vTexCoords = (uTexMatrix * vec3(aTexCoords, 1)).xy;\n"
" gl_Position = uMvpMatrix * aPosition;", + "}\n";
" vTexCoords = (uTexMatrix * vec3(aTexCoords, 1)).xy;", private static final String FRAGMENT_SHADER =
"}" "// This is required since the texture data is GL_TEXTURE_EXTERNAL_OES.\n"
}; + "#extension GL_OES_EGL_image_external : require\n"
private static final String[] FRAGMENT_SHADER_CODE = + "precision mediump float;\n"
new String[] { + "// Standard texture rendering shader.\n"
// This is required since the texture data is GL_TEXTURE_EXTERNAL_OES. + "uniform samplerExternalOES uTexture;\n"
"#extension GL_OES_EGL_image_external : require", + "varying vec2 vTexCoords;\n"
"precision mediump float;", + "void main() {\n"
+ " gl_FragColor = texture2D(uTexture, vTexCoords);\n"
// Standard texture rendering shader. + "}\n";
"uniform samplerExternalOES uTexture;",
"varying vec2 vTexCoords;",
"void main() {",
" gl_FragColor = texture2D(uTexture, vTexCoords);",
"}"
};
// Texture transform matrices. // Texture transform matrices.
private static final float[] TEX_MATRIX_WHOLE = { private static final float[] TEX_MATRIX_WHOLE = {
@ -121,11 +115,11 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
/** Initializes of the GL components. */ /** Initializes of the GL components. */
/* package */ void init() { /* package */ void init() {
program = new GlUtil.Program(VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE); program = new GlUtil.Program(VERTEX_SHADER, FRAGMENT_SHADER);
mvpMatrixHandle = program.getUniformLocation("uMvpMatrix"); mvpMatrixHandle = program.getUniformLocation("uMvpMatrix");
uTexMatrixHandle = program.getUniformLocation("uTexMatrix"); uTexMatrixHandle = program.getUniformLocation("uTexMatrix");
positionHandle = program.getAttribLocation("aPosition"); positionHandle = program.getAttributeArrayLocationAndEnable("aPosition");
texCoordsHandle = program.getAttribLocation("aTexCoords"); texCoordsHandle = program.getAttributeArrayLocationAndEnable("aTexCoords");
textureHandle = program.getUniformLocation("uTexture"); textureHandle = program.getUniformLocation("uTexture");
} }
@ -148,10 +142,6 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
checkNotNull(program).use(); checkNotNull(program).use();
checkGlError(); checkGlError();
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glEnableVertexAttribArray(texCoordsHandle);
checkGlError();
float[] texMatrix; float[] texMatrix;
if (stereoMode == C.STEREO_MODE_TOP_BOTTOM) { if (stereoMode == C.STEREO_MODE_TOP_BOTTOM) {
texMatrix = rightEye ? TEX_MATRIX_BOTTOM : TEX_MATRIX_TOP; texMatrix = rightEye ? TEX_MATRIX_BOTTOM : TEX_MATRIX_TOP;
@ -162,6 +152,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
} }
GLES20.glUniformMatrix3fv(uTexMatrixHandle, 1, false, texMatrix, 0); GLES20.glUniformMatrix3fv(uTexMatrixHandle, 1, false, texMatrix, 0);
// TODO(b/205002913): Update to use GlUtil.Uniform.bind().
GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0); GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId);

View File

@ -56,6 +56,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
private static final String TAG = "TransformerTranscodingVideoRenderer"; private static final String TAG = "TransformerTranscodingVideoRenderer";
// Predefined shader values.
private static final String VERTEX_SHADER_FILE_PATH = "shaders/blit_vertex_shader.glsl";
private static final String FRAGMENT_SHADER_FILE_PATH =
"shaders/copy_external_fragment_shader.glsl";
private static final int EXPECTED_NUMBER_OF_ATTRIBUTES = 2;
private static final int EXPECTED_NUMBER_OF_UNIFORMS = 2;
private final Context context; private final Context context;
private final DecoderInputBuffer decoderInputBuffer; private final DecoderInputBuffer decoderInputBuffer;
@ -231,18 +238,16 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
decoderTextureId = GlUtil.createExternalTexture(); decoderTextureId = GlUtil.createExternalTexture();
GlUtil.Program copyProgram; GlUtil.Program copyProgram;
try { try {
copyProgram = copyProgram = new GlUtil.Program(context, VERTEX_SHADER_FILE_PATH, FRAGMENT_SHADER_FILE_PATH);
new GlUtil.Program(
context,
/* vertexShaderFilePath= */ "shaders/blit_vertex_shader.glsl",
/* fragmentShaderFilePath= */ "shaders/copy_external_fragment_shader.glsl");
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
copyProgram.use(); copyProgram.use();
GlUtil.Attribute[] copyAttributes = copyProgram.getAttributes(); GlUtil.Attribute[] copyAttributes = copyProgram.getAttributes();
checkState(copyAttributes.length == 2, "Expected program to have two vertex attributes."); checkState(
copyAttributes.length == EXPECTED_NUMBER_OF_ATTRIBUTES,
"Expected program to have " + EXPECTED_NUMBER_OF_ATTRIBUTES + " vertex attributes.");
for (GlUtil.Attribute copyAttribute : copyAttributes) { for (GlUtil.Attribute copyAttribute : copyAttributes) {
if (copyAttribute.name.equals("a_position")) { if (copyAttribute.name.equals("a_position")) {
copyAttribute.setBuffer( copyAttribute.setBuffer(
@ -268,7 +273,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
copyAttribute.bind(); copyAttribute.bind();
} }
GlUtil.Uniform[] copyUniforms = copyProgram.getUniforms(); GlUtil.Uniform[] copyUniforms = copyProgram.getUniforms();
checkState(copyUniforms.length == 2, "Expected program to have two uniforms."); checkState(
copyUniforms.length == EXPECTED_NUMBER_OF_UNIFORMS,
"Expected program to have " + EXPECTED_NUMBER_OF_UNIFORMS + " uniforms.");
for (GlUtil.Uniform copyUniform : copyUniforms) { for (GlUtil.Uniform copyUniform : copyUniforms) {
if (copyUniform.name.equals("tex_sampler")) { if (copyUniform.name.equals("tex_sampler")) {
copyUniform.setSamplerTexId(decoderTextureId, 0); copyUniform.setSamplerTexId(decoderTextureId, 0);