Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Unified Diff: talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java

Issue 1311093005: Android GlRectDrawer: Add fragment shader for RGB(A) textures (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: addressing hbos@ comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java
diff --git a/talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java b/talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java
index abd0ddf08a2cb96f26b71563bdd017aa101cf416..c14abb021949ae2e26c7383f4b561b4b5c266403 100644
--- a/talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java
+++ b/talk/app/webrtc/java/android/org/webrtc/GlRectDrawer.java
@@ -36,6 +36,8 @@ import org.webrtc.GlUtil;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.Arrays;
+import java.util.IdentityHashMap;
+import java.util.Map;
/**
* Helper class to draw a quad that covers the entire viewport. Rotation, mirror, and cropping is
@@ -47,7 +49,7 @@ import java.util.Arrays;
public class GlRectDrawer {
// Simple vertex shader, used for both YUV and OES.
private static final String VERTEX_SHADER_STRING =
- "varying vec2 interp_tc;\n"
+ "varying vec2 interp_tc;\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec4 in_tc;\n"
+ "\n"
@@ -59,7 +61,7 @@ public class GlRectDrawer {
+ "}\n";
private static final String YUV_FRAGMENT_SHADER_STRING =
- "precision mediump float;\n"
+ "precision mediump float;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
+ "uniform sampler2D y_tex;\n"
@@ -76,8 +78,18 @@ public class GlRectDrawer {
+ " y + 1.77 * u, 1);\n"
+ "}\n";
+ private static final String RGB_FRAGMENT_SHADER_STRING =
+ "precision mediump float;\n"
+ + "varying vec2 interp_tc;\n"
+ + "\n"
+ + "uniform sampler2D rgb_tex;\n"
+ + "\n"
+ + "void main() {\n"
+ + " gl_FragColor = texture2D(rgb_tex, interp_tc);\n"
+ + "}\n";
+
private static final String OES_FRAGMENT_SHADER_STRING =
- "#extension GL_OES_EGL_image_external : require\n"
+ "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "varying vec2 interp_tc;\n"
+ "\n"
@@ -103,38 +115,18 @@ public class GlRectDrawer {
1.0f, 1.0f // Top right.
});
- private GlShader oesShader;
- private GlShader yuvShader;
+ // The keys are one of the fragments shaders above.
+ private final Map<String, GlShader> shaders = new IdentityHashMap<String, GlShader>();
private GlShader currentShader;
private float[] currentTexMatrix;
private int texMatrixLocation;
- private void initGeometry(GlShader shader) {
- shader.setVertexAttribArray("in_pos", 2, FULL_RECTANGLE_BUF);
- shader.setVertexAttribArray("in_tc", 2, FULL_RECTANGLE_TEX_BUF);
- }
-
/**
* Draw an OES texture frame with specified texture transformation matrix. Required resources are
* allocated at the first call to this function.
*/
public void drawOes(int oesTextureId, float[] texMatrix) {
- // Lazy allocation.
- if (oesShader == null) {
- oesShader = new GlShader(VERTEX_SHADER_STRING, OES_FRAGMENT_SHADER_STRING);
- oesShader.useProgram();
- initGeometry(oesShader);
- }
-
- // Set GLES state to OES.
- if (currentShader != oesShader) {
- currentShader = oesShader;
- oesShader.useProgram();
- GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
- currentTexMatrix = null;
- texMatrixLocation = oesShader.getUniformLocation("texMatrix");
- }
-
+ prepareShader(OES_FRAGMENT_SHADER_STRING);
// updateTexImage() may be called from another thread in another EGL context, so we need to
// bind/unbind the texture in each draw call so that GLES understads it's a new texture.
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, oesTextureId);
@@ -143,39 +135,34 @@ public class GlRectDrawer {
}
/**
+ * Draw a RGB(A) texture frame with specified texture transformation matrix. Required resources
+ * are allocated at the first call to this function.
+ */
+ public void drawRgb(int textureId, float[] texMatrix) {
+ prepareShader(RGB_FRAGMENT_SHADER_STRING);
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
+ drawRectangle(texMatrix);
+ // Unbind the texture as a precaution.
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
+ }
+
+ /**
* Draw a YUV frame with specified texture transformation matrix. Required resources are
* allocated at the first call to this function.
*/
public void drawYuv(int width, int height, int[] yuvTextures, float[] texMatrix) {
- // Lazy allocation.
- if (yuvShader == null) {
- yuvShader = new GlShader(VERTEX_SHADER_STRING, YUV_FRAGMENT_SHADER_STRING);
- yuvShader.useProgram();
-
- // Set texture samplers.
- GLES20.glUniform1i(yuvShader.getUniformLocation("y_tex"), 0);
- GLES20.glUniform1i(yuvShader.getUniformLocation("u_tex"), 1);
- GLES20.glUniform1i(yuvShader.getUniformLocation("v_tex"), 2);
- GlUtil.checkNoGLES2Error("y/u/v_tex glGetUniformLocation");
-
- initGeometry(yuvShader);
- }
-
- // Set GLES state to YUV.
- if (currentShader != yuvShader) {
- currentShader = yuvShader;
- yuvShader.useProgram();
- currentTexMatrix = null;
- texMatrixLocation = yuvShader.getUniformLocation("texMatrix");
- }
-
+ prepareShader(YUV_FRAGMENT_SHADER_STRING);
// Bind the textures.
for (int i = 0; i < 3; ++i) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yuvTextures[i]);
}
-
drawRectangle(texMatrix);
+ // Unbind the textures as a precaution..
+ for (int i = 0; i < 3; ++i) {
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + i);
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
+ }
}
private void drawRectangle(float[] texMatrix) {
@@ -189,17 +176,48 @@ public class GlRectDrawer {
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
+ private void prepareShader(String fragmentShader) {
+ // Lazy allocation.
+ if (!shaders.containsKey(fragmentShader)) {
+ final GlShader shader = new GlShader(VERTEX_SHADER_STRING, fragmentShader);
+ shaders.put(fragmentShader, shader);
+ shader.useProgram();
+ // Initialize fragment shader uniform values.
+ if (fragmentShader == YUV_FRAGMENT_SHADER_STRING) {
+ GLES20.glUniform1i(shader.getUniformLocation("y_tex"), 0);
+ GLES20.glUniform1i(shader.getUniformLocation("u_tex"), 1);
+ GLES20.glUniform1i(shader.getUniformLocation("v_tex"), 2);
+ } else if (fragmentShader == RGB_FRAGMENT_SHADER_STRING) {
+ GLES20.glUniform1i(shader.getUniformLocation("rgb_tex"), 0);
+ } else if (fragmentShader == OES_FRAGMENT_SHADER_STRING) {
+ GLES20.glUniform1i(shader.getUniformLocation("oes_tex"), 0);
+ } else {
+ throw new IllegalStateException("Unknown fragment shader: " + fragmentShader);
+ }
+ GlUtil.checkNoGLES2Error("Initialize fragment shader uniform values.");
+ // Initialize vertex shader attributes.
+ shader.setVertexAttribArray("in_pos", 2, FULL_RECTANGLE_BUF);
+ shader.setVertexAttribArray("in_tc", 2, FULL_RECTANGLE_TEX_BUF);
+ }
+
+ // Update GLES state if shader is not already current.
+ final GlShader shader = shaders.get(fragmentShader);
+ if (currentShader != shader) {
+ currentShader = shader;
+ shader.useProgram();
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+ currentTexMatrix = null;
+ texMatrixLocation = shader.getUniformLocation("texMatrix");
+ }
+ }
+
/**
* Release all GLES resources. This needs to be done manually, otherwise the resources are leaked.
*/
public void release() {
- if (oesShader != null) {
- oesShader.release();
- oesShader = null;
- }
- if (yuvShader != null) {
- yuvShader.release();
- yuvShader = null;
+ for (GlShader shader : shaders.values()) {
+ shader.release();
}
+ shaders.clear();
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698