Index: talk/app/webrtc/androidtests/src/org/webrtc/GlRectDrawerTest.java |
diff --git a/talk/app/webrtc/androidtests/src/org/webrtc/GlRectDrawerTest.java b/talk/app/webrtc/androidtests/src/org/webrtc/GlRectDrawerTest.java |
index c12a3751ad5a9c00b6f856d2f1340842900a30b2..99f88a38f00847d70bb012ce677e849b95749009 100644 |
--- a/talk/app/webrtc/androidtests/src/org/webrtc/GlRectDrawerTest.java |
+++ b/talk/app/webrtc/androidtests/src/org/webrtc/GlRectDrawerTest.java |
@@ -28,22 +28,25 @@ package org.webrtc; |
import android.test.ActivityTestCase; |
import android.test.suitebuilder.annotation.SmallTest; |
+import android.test.suitebuilder.annotation.MediumTest; |
import java.nio.ByteBuffer; |
import java.util.Random; |
+import android.graphics.SurfaceTexture; |
import android.opengl.EGL14; |
-import android.opengl.Matrix; |
+import android.opengl.EGLContext; |
import android.opengl.GLES20; |
+import android.opengl.Matrix; |
-public class GlRectDrawerTest extends ActivityTestCase { |
+public final class GlRectDrawerTest extends ActivityTestCase { |
// Resolution of the test image. |
private static final int WIDTH = 16; |
private static final int HEIGHT = 16; |
// Seed for random pixel creation. |
private static final int SEED = 42; |
// When comparing pixels, allow some slack for float arithmetic and integer rounding. |
- final float MAX_DIFF = 1.0f; |
+ private static final float MAX_DIFF = 1.0f; |
private static float normalizedByte(byte b) { |
return (b & 0xFF) / 255.0f; |
@@ -95,7 +98,7 @@ public class GlRectDrawerTest extends ActivityTestCase { |
} |
@SmallTest |
- public void testRgbRendering() throws Exception { |
+ public void testRgbRendering() { |
// Create EGL base with a pixel buffer as display output. |
final EglBase eglBase = new EglBase(EGL14.EGL_NO_CONTEXT, EglBase.ConfigType.PIXEL_BUFFER); |
eglBase.createPbufferSurface(WIDTH, HEIGHT); |
@@ -134,7 +137,7 @@ public class GlRectDrawerTest extends ActivityTestCase { |
} |
@SmallTest |
- public void testYuvRendering() throws Exception { |
+ public void testYuvRendering() { |
// Create EGL base with a pixel buffer as display output. |
EglBase eglBase = new EglBase(EGL14.EGL_NO_CONTEXT, EglBase.ConfigType.PIXEL_BUFFER); |
eglBase.createPbufferSurface(WIDTH, HEIGHT); |
@@ -206,4 +209,108 @@ public class GlRectDrawerTest extends ActivityTestCase { |
GLES20.glDeleteTextures(3, yuvTextures, 0); |
eglBase.release(); |
} |
+ |
+ /** |
+ * The purpose here is to test GlRectDrawer.oesDraw(). Unfortunately, there is no easy way to |
+ * create an OES texture, which is needed for input to oesDraw(). Most of the test is concerned |
+ * with creating OES textures in the following way: |
+ * - Create SurfaceTexture with help from SurfaceTextureHelper. |
+ * - Create an EglBase with the SurfaceTexture as EGLSurface. |
+ * - Upload RGB texture with known content. |
+ * - Draw the RGB texture onto the EglBase with the SurfaceTexture as target. |
+ * - Wait for an OES texture to be produced. |
+ * The actual oesDraw() test is this: |
+ * - Create an EglBase with a pixel buffer as target. |
+ * - Render the OES texture onto the pixel buffer. |
+ * - Read back the pixel buffer and compare it with the known RGB data. |
+ */ |
+ @MediumTest |
+ public void testOesRendering() throws InterruptedException { |
+ /** |
+ * Stub class to convert RGB ByteBuffers to OES textures by drawing onto a SurfaceTexture. |
+ */ |
+ class StubOesTextureProducer { |
+ private final EglBase eglBase; |
+ private final GlRectDrawer drawer; |
+ private final int rgbTexture; |
+ |
+ public StubOesTextureProducer( |
+ EGLContext sharedContext, SurfaceTexture surfaceTexture, int width, int height) { |
+ eglBase = new EglBase(sharedContext, EglBase.ConfigType.PLAIN); |
+ surfaceTexture.setDefaultBufferSize(width, height); |
+ eglBase.createSurface(surfaceTexture); |
+ assertEquals(eglBase.surfaceWidth(), width); |
+ assertEquals(eglBase.surfaceHeight(), height); |
+ |
+ drawer = new GlRectDrawer(); |
+ |
+ eglBase.makeCurrent(); |
+ rgbTexture = GlUtil.generateTexture(GLES20.GL_TEXTURE_2D); |
+ } |
+ |
+ public void draw(ByteBuffer rgbPlane) { |
+ eglBase.makeCurrent(); |
+ |
+ // Upload RGB data to texture. |
+ GLES20.glActiveTexture(GLES20.GL_TEXTURE0); |
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, rgbTexture); |
+ GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, WIDTH, |
+ HEIGHT, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, rgbPlane); |
+ // Draw the RGB data onto the SurfaceTexture. |
+ final float[] identityMatrix = new float[16]; |
+ Matrix.setIdentityM(identityMatrix, 0); |
+ drawer.drawRgb(rgbTexture, identityMatrix); |
+ eglBase.swapBuffers(); |
+ } |
+ |
+ public void release() { |
+ eglBase.makeCurrent(); |
+ drawer.release(); |
+ GLES20.glDeleteTextures(1, new int[] {rgbTexture}, 0); |
+ eglBase.release(); |
+ } |
+ } |
+ |
+ // Create EGL base with a pixel buffer as display output. |
+ final EglBase eglBase = new EglBase(EGL14.EGL_NO_CONTEXT, EglBase.ConfigType.PIXEL_BUFFER); |
+ eglBase.createPbufferSurface(WIDTH, HEIGHT); |
+ |
+ // Create resources for generating OES textures. |
+ final SurfaceTextureHelper surfaceTextureHelper = |
+ new SurfaceTextureHelper(eglBase.getContext()); |
+ final StubOesTextureProducer oesProducer = new StubOesTextureProducer( |
+ eglBase.getContext(), surfaceTextureHelper.getSurfaceTexture(), WIDTH, HEIGHT); |
+ final SurfaceTextureHelperTest.MockTextureListener listener = |
+ new SurfaceTextureHelperTest.MockTextureListener(); |
+ surfaceTextureHelper.setListener(listener); |
+ |
+ // Create RGB byte buffer plane with random content. |
+ final ByteBuffer rgbPlane = ByteBuffer.allocateDirect(WIDTH * HEIGHT * 3); |
+ final Random random = new Random(SEED); |
+ random.nextBytes(rgbPlane.array()); |
+ |
+ // Draw the frame and block until an OES texture is delivered. |
+ oesProducer.draw(rgbPlane); |
+ listener.waitForNewFrame(); |
+ |
+ // Real test starts here. |
+ // Draw the OES texture on the pixel buffer. |
+ eglBase.makeCurrent(); |
+ final GlRectDrawer drawer = new GlRectDrawer(); |
+ drawer.drawOes(listener.oesTextureId, listener.transformMatrix); |
+ |
+ // Download the pixels in the pixel buffer as RGBA. Not all platforms support RGB, e.g. Nexus 9. |
+ final ByteBuffer rgbaData = ByteBuffer.allocateDirect(WIDTH * HEIGHT * 4); |
+ GLES20.glReadPixels(0, 0, WIDTH, HEIGHT, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, rgbaData); |
+ GlUtil.checkNoGLES2Error("glReadPixels"); |
+ |
+ // Assert rendered image is pixel perfect to source RGB. |
+ assertEquals(WIDTH, HEIGHT, stripAlphaChannel(rgbaData), rgbPlane); |
+ |
+ drawer.release(); |
+ surfaceTextureHelper.returnTextureFrame(); |
+ oesProducer.release(); |
+ surfaceTextureHelper.disconnect(); |
+ eglBase.release(); |
+ } |
} |