| /* | |
| * Copyright 2018 The WebRTC Project Authors. All rights reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| package org.webrtc; | |
| import static org.junit.Assert.assertEquals; | |
| import static org.mockito.Mockito.mock; | |
| import static org.mockito.Mockito.times; | |
| import static org.mockito.Mockito.verify; | |
| import static org.mockito.Mockito.verifyNoMoreInteractions; | |
| import androidx.test.runner.AndroidJUnit4; | |
| import org.junit.After; | |
| import org.junit.Before; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.robolectric.annotation.Config; | |
| import org.webrtc.GlShader; | |
| @RunWith(AndroidJUnit4.class) | |
| @Config(manifest = Config.NONE) | |
| public class GlGenericDrawerTest { | |
| // Simplest possible valid generic fragment shader. | |
| private static final String FRAGMENT_SHADER = "void main() {\n" | |
| + " gl_FragColor = sample(tc);\n" | |
| + "}\n"; | |
| private static final int TEXTURE_ID = 3; | |
| private static final float[] TEX_MATRIX = | |
| new float[] {1, 2, 3, 4, -1, -2, -3, -4, 0, 0, 1, 0, 0, 0, 0, 1}; | |
| private static final int FRAME_WIDTH = 640; | |
| private static final int FRAME_HEIGHT = 480; | |
| private static final int VIEWPORT_X = 3; | |
| private static final int VIEWPORT_Y = 5; | |
| private static final int VIEWPORT_WIDTH = 500; | |
| private static final int VIEWPORT_HEIGHT = 500; | |
| // Replace OpenGLES GlShader dependency with a mock. | |
| private class GlGenericDrawerForTest extends GlGenericDrawer { | |
| public GlGenericDrawerForTest(String genericFragmentSource, ShaderCallbacks shaderCallbacks) { | |
| super(genericFragmentSource, shaderCallbacks); | |
| } | |
| @Override | |
| GlShader createShader(ShaderType shaderType) { | |
| return mockedShader; | |
| } | |
| } | |
| private GlShader mockedShader; | |
| private GlGenericDrawer glGenericDrawer; | |
| private GlGenericDrawer.ShaderCallbacks mockedCallbacks; | |
| @Before | |
| public void setUp() { | |
| mockedShader = mock(GlShader.class); | |
| mockedCallbacks = mock(GlGenericDrawer.ShaderCallbacks.class); | |
| glGenericDrawer = new GlGenericDrawerForTest(FRAGMENT_SHADER, mockedCallbacks); | |
| } | |
| @After | |
| public void tearDown() { | |
| verifyNoMoreInteractions(mockedCallbacks); | |
| } | |
| @Test | |
| public void testOesFragmentShader() { | |
| final String expectedOesFragmentShader = "#extension GL_OES_EGL_image_external : require\n" | |
| + "precision mediump float;\n" | |
| + "varying vec2 tc;\n" | |
| + "uniform samplerExternalOES tex;\n" | |
| + "void main() {\n" | |
| + " gl_FragColor = texture2D(tex, tc);\n" | |
| + "}\n"; | |
| final String oesFragmentShader = | |
| GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.OES); | |
| assertEquals(expectedOesFragmentShader, oesFragmentShader); | |
| } | |
| @Test | |
| public void testRgbFragmentShader() { | |
| final String expectedRgbFragmentShader = "precision mediump float;\n" | |
| + "varying vec2 tc;\n" | |
| + "uniform sampler2D tex;\n" | |
| + "void main() {\n" | |
| + " gl_FragColor = texture2D(tex, tc);\n" | |
| + "}\n"; | |
| final String rgbFragmentShader = | |
| GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.RGB); | |
| assertEquals(expectedRgbFragmentShader, rgbFragmentShader); | |
| } | |
| @Test | |
| public void testYuvFragmentShader() { | |
| final String expectedYuvFragmentShader = "precision mediump float;\n" | |
| + "varying vec2 tc;\n" | |
| + "uniform sampler2D y_tex;\n" | |
| + "uniform sampler2D u_tex;\n" | |
| + "uniform sampler2D v_tex;\n" | |
| + "vec4 sample(vec2 p) {\n" | |
| + " float y = texture2D(y_tex, p).r * 1.16438;\n" | |
| + " float u = texture2D(u_tex, p).r;\n" | |
| + " float v = texture2D(v_tex, p).r;\n" | |
| + " return vec4(y + 1.59603 * v - 0.874202,\n" | |
| + " y - 0.391762 * u - 0.812968 * v + 0.531668,\n" | |
| + " y + 2.01723 * u - 1.08563, 1);\n" | |
| + "}\n" | |
| + "void main() {\n" | |
| + " gl_FragColor = sample(tc);\n" | |
| + "}\n"; | |
| final String yuvFragmentShader = | |
| GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.YUV); | |
| assertEquals(expectedYuvFragmentShader, yuvFragmentShader); | |
| } | |
| @Test | |
| public void testShaderCallbacksOneRgbFrame() { | |
| glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, | |
| VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| verify(mockedCallbacks).onNewShader(mockedShader); | |
| verify(mockedCallbacks) | |
| .onPrepareShader( | |
| mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| } | |
| @Test | |
| public void testShaderCallbacksTwoRgbFrames() { | |
| glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, | |
| VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, | |
| VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| // Expect only one shader to be created, but two frames to be drawn. | |
| verify(mockedCallbacks, times(1)).onNewShader(mockedShader); | |
| verify(mockedCallbacks, times(2)) | |
| .onPrepareShader( | |
| mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| } | |
| @Test | |
| public void testShaderCallbacksChangingShaderType() { | |
| glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, | |
| VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| glGenericDrawer.drawOes(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, | |
| VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| // Expect two shaders to be created, and two frames to be drawn. | |
| verify(mockedCallbacks, times(2)).onNewShader(mockedShader); | |
| verify(mockedCallbacks, times(2)) | |
| .onPrepareShader( | |
| mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); | |
| } | |
| } |