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:
parent
b87f26490b
commit
edc4bd5be1
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user