From c9ebaacae01d1e2afbb95850e4f8f0d6791243a1 Mon Sep 17 00:00:00 2001 From: eguven Date: Wed, 26 Sep 2018 03:47:54 -0700 Subject: [PATCH] Use GlUtil class to share GL methods ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=214582295 --- .../exoplayer2/ext/vp9/VpxRenderer.java | 81 +++-------------- .../exoplayer2/util/EGLSurfaceTexture.java | 5 +- .../android/exoplayer2/util}/GlUtil.java | 86 +++++++++++-------- .../ui/spherical/ProjectionRenderer.java | 3 +- .../ui/spherical/SceneRenderer.java | 3 +- 5 files changed, 68 insertions(+), 110 deletions(-) rename library/{ui/src/main/java/com/google/android/exoplayer2/ui/spherical => core/src/main/java/com/google/android/exoplayer2/util}/GlUtil.java (63%) diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxRenderer.java index 837539593e..d82f5a6071 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxRenderer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer2/ext/vp9/VpxRenderer.java @@ -17,8 +17,7 @@ package com.google.android.exoplayer2.ext.vp9; import android.opengl.GLES20; import android.opengl.GLSurfaceView; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; +import com.google.android.exoplayer2.util.GlUtil; import java.nio.FloatBuffer; import java.util.concurrent.atomic.AtomicReference; import javax.microedition.khronos.egl.EGLConfig; @@ -72,11 +71,8 @@ import javax.microedition.khronos.opengles.GL10; + " gl_FragColor = vec4(mColorConversion * yuv, 1.0);\n" + "}\n"; - private static final FloatBuffer TEXTURE_VERTICES = nativeFloatBuffer( - -1.0f, 1.0f, - -1.0f, -1.0f, - 1.0f, 1.0f, - 1.0f, -1.0f); + private static final FloatBuffer TEXTURE_VERTICES = + GlUtil.createBuffer(new float[] {-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f}); private final int[] yuvTextures = new int[3]; private final AtomicReference pendingOutputBufferReference; @@ -114,21 +110,7 @@ import javax.microedition.khronos.opengles.GL10; @Override public void onSurfaceCreated(GL10 unused, EGLConfig config) { - // Create the GL program. - program = GLES20.glCreateProgram(); - - // Add the vertex and fragment shaders. - addShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER, program); - addShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER, program); - - // Link the GL program. - GLES20.glLinkProgram(program); - int[] result = new int[] { - GLES20.GL_FALSE - }; - result[0] = GLES20.GL_FALSE; - GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, result, 0); - abortUnless(result[0] == GLES20.GL_TRUE, GLES20.glGetProgramInfoLog(program)); + program = GlUtil.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER); GLES20.glUseProgram(program); int posLocation = GLES20.glGetAttribLocation(program, "in_pos"); GLES20.glEnableVertexAttribArray(posLocation); @@ -136,11 +118,11 @@ import javax.microedition.khronos.opengles.GL10; posLocation, 2, GLES20.GL_FLOAT, false, 0, TEXTURE_VERTICES); texLocation = GLES20.glGetAttribLocation(program, "in_tc"); GLES20.glEnableVertexAttribArray(texLocation); - checkNoGLES2Error(); + GlUtil.checkGlError(); colorMatrixLocation = GLES20.glGetUniformLocation(program, "mColorConversion"); - checkNoGLES2Error(); + GlUtil.checkGlError(); setupTextures(); - checkNoGLES2Error(); + GlUtil.checkGlError(); } @Override @@ -191,11 +173,8 @@ import javax.microedition.khronos.opengles.GL10; float crop = (float) outputBuffer.width / outputBuffer.yuvStrides[0]; // This buffer is consumed during each call to glDrawArrays. It needs to be a member variable // rather than a local variable to ensure that it doesn't get garbage collected. - textureCoords = nativeFloatBuffer( - 0.0f, 0.0f, - 0.0f, 1.0f, - crop, 0.0f, - crop, 1.0f); + textureCoords = + GlUtil.createBuffer(new float[] {0.0f, 0.0f, 0.0f, 1.0f, crop, 0.0f, crop, 1.0f}); GLES20.glVertexAttribPointer( texLocation, 2, GLES20.GL_FLOAT, false, 0, textureCoords); previousWidth = outputBuffer.width; @@ -203,23 +182,7 @@ import javax.microedition.khronos.opengles.GL10; } GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - checkNoGLES2Error(); - } - - private void addShader(int type, String source, int program) { - int[] result = new int[] { - GLES20.GL_FALSE - }; - int shader = GLES20.glCreateShader(type); - GLES20.glShaderSource(shader, source); - GLES20.glCompileShader(shader); - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, result, 0); - abortUnless(result[0] == GLES20.GL_TRUE, - GLES20.glGetShaderInfoLog(shader) + ", source: " + source); - GLES20.glAttachShader(program, shader); - GLES20.glDeleteShader(shader); - - checkNoGLES2Error(); + GlUtil.checkGlError(); } private void setupTextures() { @@ -237,28 +200,6 @@ import javax.microedition.khronos.opengles.GL10; GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); } - checkNoGLES2Error(); + GlUtil.checkGlError(); } - - private void abortUnless(boolean condition, String msg) { - if (!condition) { - throw new RuntimeException(msg); - } - } - - private void checkNoGLES2Error() { - int error = GLES20.glGetError(); - if (error != GLES20.GL_NO_ERROR) { - throw new RuntimeException("GLES20 error: " + error); - } - } - - private static FloatBuffer nativeFloatBuffer(float... array) { - FloatBuffer buffer = ByteBuffer.allocateDirect(array.length * 4).order( - ByteOrder.nativeOrder()).asFloatBuffer(); - buffer.put(array); - buffer.flip(); - return buffer; - } - } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/EGLSurfaceTexture.java b/library/core/src/main/java/com/google/android/exoplayer2/util/EGLSurfaceTexture.java index 90e37de828..bf4d78ee10 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/util/EGLSurfaceTexture.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/EGLSurfaceTexture.java @@ -305,9 +305,6 @@ public final class EGLSurfaceTexture implements SurfaceTexture.OnFrameAvailableL private static void generateTextureIds(int[] textureIdHolder) { GLES20.glGenTextures(/* n= */ 1, textureIdHolder, /* offset= */ 0); - int errorCode = GLES20.glGetError(); - if (errorCode != GLES20.GL_NO_ERROR) { - throw new GlException("glGenTextures failed. Error: " + Integer.toHexString(errorCode)); - } + GlUtil.checkGlError(); } } diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/GlUtil.java b/library/core/src/main/java/com/google/android/exoplayer2/util/GlUtil.java similarity index 63% rename from library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/GlUtil.java rename to library/core/src/main/java/com/google/android/exoplayer2/util/GlUtil.java index 68a85938a3..72a782c2ac 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/GlUtil.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/util/GlUtil.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer2.ui.spherical; +package com.google.android.exoplayer2.util; import static android.opengl.GLU.gluErrorString; @@ -23,15 +23,14 @@ import android.opengl.GLES20; import android.text.TextUtils; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.ExoPlayerLibraryInfo; -import com.google.android.exoplayer2.util.Log; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; /** GL utility methods. */ -/* package */ final class GlUtil { - private static final String TAG = "Spherical.Utils"; +public final class GlUtil { + private static final String TAG = "GlUtil"; /** Class only contains static methods. */ private GlUtil() {} @@ -57,42 +56,39 @@ import java.nio.IntBuffer; } /** - * Builds a GL shader program from vertex & fragment shader code. The vertex and fragment shaders - * are passed as arrays of strings in order to make debugging compilation issues easier. + * Builds a GL shader program from vertex & fragment shader code. + * + * @param vertexCode GLES20 vertex shader program as arrays of strings. Strings are joined by + * adding a new line character in between each of them. + * @param fragmentCode GLES20 fragment shader program as arrays of strings. Strings are joined by + * adding a new line character in between each of them. + * @return GLES20 program id. + */ + public static int compileProgram(String[] vertexCode, String[] fragmentCode) { + return compileProgram(TextUtils.join("\n", vertexCode), TextUtils.join("\n", fragmentCode)); + } + + /** + * Builds a GL shader program from vertex & fragment shader code. * * @param vertexCode GLES20 vertex shader program. * @param fragmentCode GLES20 fragment shader program. * @return GLES20 program id. */ - public static int compileProgram(String[] vertexCode, String[] fragmentCode) { - checkGlError(); - // prepare shaders and OpenGL program - int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); - GLES20.glShaderSource(vertexShader, TextUtils.join("\n", vertexCode)); - GLES20.glCompileShader(vertexShader); - checkGlError(); - - int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); - GLES20.glShaderSource(fragmentShader, TextUtils.join("\n", fragmentCode)); - GLES20.glCompileShader(fragmentShader); - checkGlError(); - + public static int compileProgram(String vertexCode, String fragmentCode) { int program = GLES20.glCreateProgram(); - GLES20.glAttachShader(program, vertexShader); - GLES20.glDeleteShader(vertexShader); - GLES20.glAttachShader(program, fragmentShader); - GLES20.glDeleteShader(fragmentShader); + checkGlError(); + + // Add the vertex and fragment shaders. + addShader(GLES20.GL_VERTEX_SHADER, vertexCode, program); + addShader(GLES20.GL_FRAGMENT_SHADER, fragmentCode, program); // Link and check for errors. GLES20.glLinkProgram(program); - int[] linkStatus = new int[1]; + int[] linkStatus = new int[] {GLES20.GL_FALSE}; GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); if (linkStatus[0] != GLES20.GL_TRUE) { - String errorMsg = "Unable to link shader program: \n" + GLES20.glGetProgramInfoLog(program); - Log.e(TAG, errorMsg); - if (ExoPlayerLibraryInfo.GL_ASSERTIONS_ENABLED) { - throw new RuntimeException(errorMsg); - } + throwGlError("Unable to link shader program: \n" + GLES20.glGetProgramInfoLog(program)); } checkGlError(); @@ -101,12 +97,11 @@ import java.nio.IntBuffer; /** Allocates a FloatBuffer with the given data. */ public static FloatBuffer createBuffer(float[] data) { - ByteBuffer bb = ByteBuffer.allocateDirect(data.length * C.BYTES_PER_FLOAT); - bb.order(ByteOrder.nativeOrder()); - FloatBuffer buffer = bb.asFloatBuffer(); + ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * C.BYTES_PER_FLOAT); + byteBuffer.order(ByteOrder.nativeOrder()); + FloatBuffer buffer = byteBuffer.asFloatBuffer(); buffer.put(data); - buffer.position(0); - + buffer.flip(); return buffer; } @@ -130,4 +125,27 @@ import java.nio.IntBuffer; checkGlError(); return texId[0]; } + + private static void addShader(int type, String source, int program) { + int shader = GLES20.glCreateShader(type); + GLES20.glShaderSource(shader, source); + GLES20.glCompileShader(shader); + + int[] result = new int[] {GLES20.GL_FALSE}; + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, result, 0); + if (result[0] != GLES20.GL_TRUE) { + throwGlError(GLES20.glGetShaderInfoLog(shader) + ", source: " + source); + } + + GLES20.glAttachShader(program, shader); + GLES20.glDeleteShader(shader); + checkGlError(); + } + + private static void throwGlError(String errorMsg) { + Log.e(TAG, errorMsg); + if (ExoPlayerLibraryInfo.GL_ASSERTIONS_ENABLED) { + throw new RuntimeException(errorMsg); + } + } } diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/ProjectionRenderer.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/ProjectionRenderer.java index b0760ec2bd..47515b023a 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/ProjectionRenderer.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/ProjectionRenderer.java @@ -15,12 +15,13 @@ */ package com.google.android.exoplayer2.ui.spherical; -import static com.google.android.exoplayer2.ui.spherical.GlUtil.checkGlError; +import static com.google.android.exoplayer2.util.GlUtil.checkGlError; import android.annotation.TargetApi; import android.opengl.GLES11Ext; import android.opengl.GLES20; import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.video.spherical.Projection; import java.nio.FloatBuffer; import org.checkerframework.checker.nullness.qual.Nullable; diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/SceneRenderer.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/SceneRenderer.java index ff3641135c..048c346781 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/SceneRenderer.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/spherical/SceneRenderer.java @@ -15,7 +15,7 @@ */ package com.google.android.exoplayer2.ui.spherical; -import static com.google.android.exoplayer2.ui.spherical.GlUtil.checkGlError; +import static com.google.android.exoplayer2.util.GlUtil.checkGlError; import android.graphics.SurfaceTexture; import android.opengl.GLES20; @@ -25,6 +25,7 @@ import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.ui.spherical.ProjectionRenderer.EyeType; import com.google.android.exoplayer2.util.Assertions; +import com.google.android.exoplayer2.util.GlUtil; import com.google.android.exoplayer2.util.TimedValueQueue; import com.google.android.exoplayer2.video.VideoFrameMetadataListener; import com.google.android.exoplayer2.video.spherical.CameraMotionListener;