mirror of
https://github.com/androidx/media.git
synced 2025-05-10 09:12:16 +08:00
Use GlUtil class to share GL methods
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=214582295
This commit is contained in:
parent
b2e0a365d3
commit
c9ebaacae0
@ -17,8 +17,7 @@ package com.google.android.exoplayer2.ext.vp9;
|
|||||||
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
import java.nio.ByteBuffer;
|
import com.google.android.exoplayer2.util.GlUtil;
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
@ -72,11 +71,8 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
+ " gl_FragColor = vec4(mColorConversion * yuv, 1.0);\n"
|
+ " gl_FragColor = vec4(mColorConversion * yuv, 1.0);\n"
|
||||||
+ "}\n";
|
+ "}\n";
|
||||||
|
|
||||||
private static final FloatBuffer TEXTURE_VERTICES = nativeFloatBuffer(
|
private static final FloatBuffer TEXTURE_VERTICES =
|
||||||
-1.0f, 1.0f,
|
GlUtil.createBuffer(new float[] {-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 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 int[] yuvTextures = new int[3];
|
||||||
private final AtomicReference<VpxOutputBuffer> pendingOutputBufferReference;
|
private final AtomicReference<VpxOutputBuffer> pendingOutputBufferReference;
|
||||||
|
|
||||||
@ -114,21 +110,7 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
||||||
// Create the GL program.
|
program = GlUtil.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER);
|
||||||
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));
|
|
||||||
GLES20.glUseProgram(program);
|
GLES20.glUseProgram(program);
|
||||||
int posLocation = GLES20.glGetAttribLocation(program, "in_pos");
|
int posLocation = GLES20.glGetAttribLocation(program, "in_pos");
|
||||||
GLES20.glEnableVertexAttribArray(posLocation);
|
GLES20.glEnableVertexAttribArray(posLocation);
|
||||||
@ -136,11 +118,11 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
posLocation, 2, GLES20.GL_FLOAT, false, 0, TEXTURE_VERTICES);
|
posLocation, 2, GLES20.GL_FLOAT, false, 0, TEXTURE_VERTICES);
|
||||||
texLocation = GLES20.glGetAttribLocation(program, "in_tc");
|
texLocation = GLES20.glGetAttribLocation(program, "in_tc");
|
||||||
GLES20.glEnableVertexAttribArray(texLocation);
|
GLES20.glEnableVertexAttribArray(texLocation);
|
||||||
checkNoGLES2Error();
|
GlUtil.checkGlError();
|
||||||
colorMatrixLocation = GLES20.glGetUniformLocation(program, "mColorConversion");
|
colorMatrixLocation = GLES20.glGetUniformLocation(program, "mColorConversion");
|
||||||
checkNoGLES2Error();
|
GlUtil.checkGlError();
|
||||||
setupTextures();
|
setupTextures();
|
||||||
checkNoGLES2Error();
|
GlUtil.checkGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -191,11 +173,8 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
float crop = (float) outputBuffer.width / outputBuffer.yuvStrides[0];
|
float crop = (float) outputBuffer.width / outputBuffer.yuvStrides[0];
|
||||||
// This buffer is consumed during each call to glDrawArrays. It needs to be a member variable
|
// 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.
|
// rather than a local variable to ensure that it doesn't get garbage collected.
|
||||||
textureCoords = nativeFloatBuffer(
|
textureCoords =
|
||||||
0.0f, 0.0f,
|
GlUtil.createBuffer(new float[] {0.0f, 0.0f, 0.0f, 1.0f, crop, 0.0f, crop, 1.0f});
|
||||||
0.0f, 1.0f,
|
|
||||||
crop, 0.0f,
|
|
||||||
crop, 1.0f);
|
|
||||||
GLES20.glVertexAttribPointer(
|
GLES20.glVertexAttribPointer(
|
||||||
texLocation, 2, GLES20.GL_FLOAT, false, 0, textureCoords);
|
texLocation, 2, GLES20.GL_FLOAT, false, 0, textureCoords);
|
||||||
previousWidth = outputBuffer.width;
|
previousWidth = outputBuffer.width;
|
||||||
@ -203,23 +182,7 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
}
|
}
|
||||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
checkNoGLES2Error();
|
GlUtil.checkGlError();
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupTextures() {
|
private void setupTextures() {
|
||||||
@ -237,28 +200,6 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
|
||||||
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -305,9 +305,6 @@ public final class EGLSurfaceTexture implements SurfaceTexture.OnFrameAvailableL
|
|||||||
|
|
||||||
private static void generateTextureIds(int[] textureIdHolder) {
|
private static void generateTextureIds(int[] textureIdHolder) {
|
||||||
GLES20.glGenTextures(/* n= */ 1, textureIdHolder, /* offset= */ 0);
|
GLES20.glGenTextures(/* n= */ 1, textureIdHolder, /* offset= */ 0);
|
||||||
int errorCode = GLES20.glGetError();
|
GlUtil.checkGlError();
|
||||||
if (errorCode != GLES20.GL_NO_ERROR) {
|
|
||||||
throw new GlException("glGenTextures failed. Error: " + Integer.toHexString(errorCode));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
package com.google.android.exoplayer2.util;
|
||||||
|
|
||||||
import static android.opengl.GLU.gluErrorString;
|
import static android.opengl.GLU.gluErrorString;
|
||||||
|
|
||||||
@ -23,15 +23,14 @@ import android.opengl.GLES20;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
/** GL utility methods. */
|
/** GL utility methods. */
|
||||||
/* package */ final class GlUtil {
|
public final class GlUtil {
|
||||||
private static final String TAG = "Spherical.Utils";
|
private static final String TAG = "GlUtil";
|
||||||
|
|
||||||
/** Class only contains static methods. */
|
/** Class only contains static methods. */
|
||||||
private GlUtil() {}
|
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
|
* Builds a GL shader program from vertex & fragment shader code.
|
||||||
* are passed as arrays of strings in order to make debugging compilation issues easier.
|
*
|
||||||
|
* @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 vertexCode GLES20 vertex shader program.
|
||||||
* @param fragmentCode GLES20 fragment shader program.
|
* @param fragmentCode GLES20 fragment shader program.
|
||||||
* @return GLES20 program id.
|
* @return GLES20 program id.
|
||||||
*/
|
*/
|
||||||
public static int compileProgram(String[] vertexCode, String[] fragmentCode) {
|
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();
|
|
||||||
|
|
||||||
int program = GLES20.glCreateProgram();
|
int program = GLES20.glCreateProgram();
|
||||||
GLES20.glAttachShader(program, vertexShader);
|
checkGlError();
|
||||||
GLES20.glDeleteShader(vertexShader);
|
|
||||||
GLES20.glAttachShader(program, fragmentShader);
|
// Add the vertex and fragment shaders.
|
||||||
GLES20.glDeleteShader(fragmentShader);
|
addShader(GLES20.GL_VERTEX_SHADER, vertexCode, program);
|
||||||
|
addShader(GLES20.GL_FRAGMENT_SHADER, fragmentCode, program);
|
||||||
|
|
||||||
// Link and check for errors.
|
// Link and check for errors.
|
||||||
GLES20.glLinkProgram(program);
|
GLES20.glLinkProgram(program);
|
||||||
int[] linkStatus = new int[1];
|
int[] linkStatus = new int[] {GLES20.GL_FALSE};
|
||||||
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
|
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
|
||||||
if (linkStatus[0] != GLES20.GL_TRUE) {
|
if (linkStatus[0] != GLES20.GL_TRUE) {
|
||||||
String errorMsg = "Unable to link shader program: \n" + GLES20.glGetProgramInfoLog(program);
|
throwGlError("Unable to link shader program: \n" + GLES20.glGetProgramInfoLog(program));
|
||||||
Log.e(TAG, errorMsg);
|
|
||||||
if (ExoPlayerLibraryInfo.GL_ASSERTIONS_ENABLED) {
|
|
||||||
throw new RuntimeException(errorMsg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
checkGlError();
|
checkGlError();
|
||||||
|
|
||||||
@ -101,12 +97,11 @@ import java.nio.IntBuffer;
|
|||||||
|
|
||||||
/** Allocates a FloatBuffer with the given data. */
|
/** Allocates a FloatBuffer with the given data. */
|
||||||
public static FloatBuffer createBuffer(float[] data) {
|
public static FloatBuffer createBuffer(float[] data) {
|
||||||
ByteBuffer bb = ByteBuffer.allocateDirect(data.length * C.BYTES_PER_FLOAT);
|
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(data.length * C.BYTES_PER_FLOAT);
|
||||||
bb.order(ByteOrder.nativeOrder());
|
byteBuffer.order(ByteOrder.nativeOrder());
|
||||||
FloatBuffer buffer = bb.asFloatBuffer();
|
FloatBuffer buffer = byteBuffer.asFloatBuffer();
|
||||||
buffer.put(data);
|
buffer.put(data);
|
||||||
buffer.position(0);
|
buffer.flip();
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,4 +125,27 @@ import java.nio.IntBuffer;
|
|||||||
checkGlError();
|
checkGlError();
|
||||||
return texId[0];
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -15,12 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
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.annotation.TargetApi;
|
||||||
import android.opengl.GLES11Ext;
|
import android.opengl.GLES11Ext;
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.util.GlUtil;
|
||||||
import com.google.android.exoplayer2.video.spherical.Projection;
|
import com.google.android.exoplayer2.video.spherical.Projection;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ui.spherical;
|
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.graphics.SurfaceTexture;
|
||||||
import android.opengl.GLES20;
|
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.Format;
|
||||||
import com.google.android.exoplayer2.ui.spherical.ProjectionRenderer.EyeType;
|
import com.google.android.exoplayer2.ui.spherical.ProjectionRenderer.EyeType;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
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.util.TimedValueQueue;
|
||||||
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
import com.google.android.exoplayer2.video.VideoFrameMetadataListener;
|
||||||
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
import com.google.android.exoplayer2.video.spherical.CameraMotionListener;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user