1 /* 2 * Copyright 2018 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc; 12 13 import static org.junit.Assert.assertEquals; 14 import static org.mockito.Mockito.mock; 15 import static org.mockito.Mockito.times; 16 import static org.mockito.Mockito.verify; 17 import static org.mockito.Mockito.verifyNoMoreInteractions; 18 19 import org.chromium.testing.local.LocalRobolectricTestRunner; 20 import org.junit.After; 21 import org.junit.Before; 22 import org.junit.Test; 23 import org.junit.runner.RunWith; 24 import org.robolectric.annotation.Config; 25 import org.webrtc.GlShader; 26 27 @RunWith(LocalRobolectricTestRunner.class) 28 @Config(manifest = Config.NONE) 29 public class GlGenericDrawerTest { 30 // Simplest possible valid generic fragment shader. 31 private static final String FRAGMENT_SHADER = "void main() {\n" 32 + " gl_FragColor = sample(tc);\n" 33 + "}\n"; 34 private static final int TEXTURE_ID = 3; 35 private static final float[] TEX_MATRIX = 36 new float[] {1, 2, 3, 4, -1, -2, -3, -4, 0, 0, 1, 0, 0, 0, 0, 1}; 37 private static final int FRAME_WIDTH = 640; 38 private static final int FRAME_HEIGHT = 480; 39 private static final int VIEWPORT_X = 3; 40 private static final int VIEWPORT_Y = 5; 41 private static final int VIEWPORT_WIDTH = 500; 42 private static final int VIEWPORT_HEIGHT = 500; 43 44 // Replace OpenGLES GlShader dependency with a mock. 45 private class GlGenericDrawerForTest extends GlGenericDrawer { GlGenericDrawerForTest(String genericFragmentSource, ShaderCallbacks shaderCallbacks)46 public GlGenericDrawerForTest(String genericFragmentSource, ShaderCallbacks shaderCallbacks) { 47 super(genericFragmentSource, shaderCallbacks); 48 } 49 50 @Override createShader(ShaderType shaderType)51 GlShader createShader(ShaderType shaderType) { 52 return mockedShader; 53 } 54 } 55 56 private GlShader mockedShader; 57 private GlGenericDrawer glGenericDrawer; 58 private GlGenericDrawer.ShaderCallbacks mockedCallbacks; 59 60 @Before setUp()61 public void setUp() { 62 mockedShader = mock(GlShader.class); 63 mockedCallbacks = mock(GlGenericDrawer.ShaderCallbacks.class); 64 glGenericDrawer = new GlGenericDrawerForTest(FRAGMENT_SHADER, mockedCallbacks); 65 } 66 67 @After tearDown()68 public void tearDown() { 69 verifyNoMoreInteractions(mockedCallbacks); 70 } 71 72 @Test testOesFragmentShader()73 public void testOesFragmentShader() { 74 final String expectedOesFragmentShader = "#extension GL_OES_EGL_image_external : require\n" 75 + "precision mediump float;\n" 76 + "varying vec2 tc;\n" 77 + "uniform samplerExternalOES tex;\n" 78 + "void main() {\n" 79 + " gl_FragColor = texture2D(tex, tc);\n" 80 + "}\n"; 81 final String oesFragmentShader = 82 GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.OES); 83 assertEquals(expectedOesFragmentShader, oesFragmentShader); 84 } 85 86 @Test testRgbFragmentShader()87 public void testRgbFragmentShader() { 88 final String expectedRgbFragmentShader = "precision mediump float;\n" 89 + "varying vec2 tc;\n" 90 + "uniform sampler2D tex;\n" 91 + "void main() {\n" 92 + " gl_FragColor = texture2D(tex, tc);\n" 93 + "}\n"; 94 final String rgbFragmentShader = 95 GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.RGB); 96 assertEquals(expectedRgbFragmentShader, rgbFragmentShader); 97 } 98 99 @Test testYuvFragmentShader()100 public void testYuvFragmentShader() { 101 final String expectedYuvFragmentShader = "precision mediump float;\n" 102 + "varying vec2 tc;\n" 103 + "uniform sampler2D y_tex;\n" 104 + "uniform sampler2D u_tex;\n" 105 + "uniform sampler2D v_tex;\n" 106 + "vec4 sample(vec2 p) {\n" 107 + " float y = texture2D(y_tex, p).r * 1.16438;\n" 108 + " float u = texture2D(u_tex, p).r;\n" 109 + " float v = texture2D(v_tex, p).r;\n" 110 + " return vec4(y + 1.59603 * v - 0.874202,\n" 111 + " y - 0.391762 * u - 0.812968 * v + 0.531668,\n" 112 + " y + 2.01723 * u - 1.08563, 1);\n" 113 + "}\n" 114 + "void main() {\n" 115 + " gl_FragColor = sample(tc);\n" 116 + "}\n"; 117 final String yuvFragmentShader = 118 GlGenericDrawer.createFragmentShaderString(FRAGMENT_SHADER, GlGenericDrawer.ShaderType.YUV); 119 assertEquals(expectedYuvFragmentShader, yuvFragmentShader); 120 } 121 122 @Test testShaderCallbacksOneRgbFrame()123 public void testShaderCallbacksOneRgbFrame() { 124 glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, 125 VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 126 127 verify(mockedCallbacks).onNewShader(mockedShader); 128 verify(mockedCallbacks) 129 .onPrepareShader( 130 mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 131 } 132 133 @Test testShaderCallbacksTwoRgbFrames()134 public void testShaderCallbacksTwoRgbFrames() { 135 glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, 136 VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 137 glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, 138 VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 139 140 // Expect only one shader to be created, but two frames to be drawn. 141 verify(mockedCallbacks, times(1)).onNewShader(mockedShader); 142 verify(mockedCallbacks, times(2)) 143 .onPrepareShader( 144 mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 145 } 146 147 @Test testShaderCallbacksChangingShaderType()148 public void testShaderCallbacksChangingShaderType() { 149 glGenericDrawer.drawRgb(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, 150 VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 151 glGenericDrawer.drawOes(TEXTURE_ID, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_X, 152 VIEWPORT_Y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 153 154 // Expect two shaders to be created, and two frames to be drawn. 155 verify(mockedCallbacks, times(2)).onNewShader(mockedShader); 156 verify(mockedCallbacks, times(2)) 157 .onPrepareShader( 158 mockedShader, TEX_MATRIX, FRAME_WIDTH, FRAME_HEIGHT, VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 159 } 160 } 161