• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "test_utils/ANGLETest.h"
8 
9 #include "test_utils/gl_raii.h"
10 
11 using namespace angle;
12 
13 namespace
14 {
15 
16 class WEBGLVideoTextureTest : public ANGLETest
17 {
18   protected:
WEBGLVideoTextureTest()19     WEBGLVideoTextureTest()
20     {
21         setWindowWidth(128);
22         setWindowHeight(128);
23         setConfigRedBits(8);
24         setConfigGreenBits(8);
25         setConfigBlueBits(8);
26         setConfigAlphaBits(8);
27     }
28 };
29 
30 class WEBGLVideoTextureES300Test : public ANGLETest
31 {
32   protected:
WEBGLVideoTextureES300Test()33     WEBGLVideoTextureES300Test()
34     {
35         setWindowWidth(128);
36         setWindowHeight(128);
37         setConfigRedBits(8);
38         setConfigGreenBits(8);
39         setConfigBlueBits(8);
40         setConfigAlphaBits(8);
41     }
42 };
43 
44 // Test to verify samplerVideoWEBGL works fine when extension is enabled.
TEST_P(WEBGLVideoTextureTest,VerifySamplerVideoWEBGL)45 TEST_P(WEBGLVideoTextureTest, VerifySamplerVideoWEBGL)
46 {
47     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
48 
49     constexpr char kVS[] = R"(
50 attribute vec2 position;
51 varying mediump vec2 texCoord;
52 void main()
53 {
54     gl_Position = vec4(position, 0, 1);
55     texCoord = position * 0.5 + vec2(0.5);
56 })";
57 
58     constexpr char kFS[] = R"(
59 
60 #extension GL_WEBGL_video_texture : require
61 precision mediump float;
62 varying mediump vec2 texCoord;
63 uniform mediump samplerVideoWEBGL s;
64 void main()
65 {
66     gl_FragColor = textureVideoWEBGL(s, texCoord);
67 })";
68 
69     ANGLE_GL_PROGRAM(program, kVS, kFS);
70     // Initialize basic red texture.
71     const std::vector<GLColor> redColors(4, GLColor::red);
72     GLTexture texture;
73     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
74     glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
75                  redColors.data());
76     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
77     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
78 
79     ASSERT_GL_NO_ERROR();
80 
81     drawQuad(program, "position", 0.0f);
82     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
83     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
84     ASSERT_GL_NO_ERROR();
85 }
86 
87 // Test to verify samplerVideoWEBGL works fine as parameter of user defined function
88 // when extension is enabled.
TEST_P(WEBGLVideoTextureTest,VerifySamplerVideoWEBGLAsParameter)89 TEST_P(WEBGLVideoTextureTest, VerifySamplerVideoWEBGLAsParameter)
90 {
91     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
92 
93     constexpr char kVS[] = R"(
94 attribute vec2 position;
95 varying mediump vec2 texCoord;
96 void main()
97 {
98     gl_Position = vec4(position, 0, 1);
99     texCoord = position * 0.5 + vec2(0.5);
100 })";
101 
102     constexpr char kFS[] = R"(
103 
104 #extension GL_WEBGL_video_texture : require
105 precision mediump float;
106 varying mediump vec2 texCoord;
107 uniform mediump samplerVideoWEBGL s;
108 
109 vec4 wrapTextureVideoWEBGL(samplerVideoWEBGL sampler, vec2 coord)
110 {
111     return textureVideoWEBGL(sampler, coord);
112 }
113 
114 void main()
115 {
116     gl_FragColor = wrapTextureVideoWEBGL(s, texCoord);
117 })";
118 
119     ANGLE_GL_PROGRAM(program, kVS, kFS);
120     // Initialize basic red texture.
121     const std::vector<GLColor> redColors(4, GLColor::red);
122     GLTexture texture;
123     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
124     glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
125                  redColors.data());
126     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
127     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
128     ASSERT_GL_NO_ERROR();
129 
130     drawQuad(program, "position", 0.0f);
131     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
132     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
133     ASSERT_GL_NO_ERROR();
134 }
135 
136 // Test to ensure ANGLE state manager knows the change when binding VideoImage
137 // and can handle it correctly based on the program.
TEST_P(WEBGLVideoTextureTest,VerifyStateManagerKnowsBindingVideoImage)138 TEST_P(WEBGLVideoTextureTest, VerifyStateManagerKnowsBindingVideoImage)
139 {
140     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
141 
142     constexpr char kVS[] = R"(
143 attribute vec2 position;
144 varying mediump vec2 texCoord;
145 void main()
146 {
147     gl_Position = vec4(position, 0, 1);
148     texCoord = position * 0.5 + vec2(0.5);
149 })";
150 
151     constexpr char kFS2D[] = R"(
152 
153 precision mediump float;
154 varying mediump vec2 texCoord;
155 uniform mediump sampler2D s;
156 
157 void main()
158 {
159     gl_FragColor = texture2D(s, texCoord);
160 })";
161 
162     constexpr char kFSVideoImage[] = R"(
163 
164 #extension GL_WEBGL_video_texture : require
165 precision mediump float;
166 varying mediump vec2 texCoord;
167 uniform mediump samplerVideoWEBGL s;
168 
169 void main()
170 {
171     gl_FragColor = textureVideoWEBGL(s, texCoord);
172 })";
173 
174     ANGLE_GL_PROGRAM(program2D, kVS, kFS2D);
175     ANGLE_GL_PROGRAM(programVideoImage, kVS, kFSVideoImage);
176     // Initialize basic red texture.
177     const std::vector<GLColor> redColors(4, GLColor::red);
178     const std::vector<GLColor> greenColors(4, GLColor::green);
179     GLTexture texture2D;
180     GLTexture textureVideoImage;
181     glBindTexture(GL_TEXTURE_2D, texture2D);
182     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, redColors.data());
183     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
184     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
185     ASSERT_GL_NO_ERROR();
186 
187     // This should unbind the native TEXTURE_2D
188     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, textureVideoImage);
189     glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
190                  greenColors.data());
191     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
192     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
193     ASSERT_GL_NO_ERROR();
194 
195     // ANGLE will check state change and apply changes through state manager. If state manager
196     // is aware of the unbind, it will bind the correct texture back in native and the draw should
197     // work fine.
198     drawQuad(program2D, "position", 0.0f);
199     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
200     drawQuad(programVideoImage, "position", 0.0f);
201     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
202     drawQuad(program2D, "position", 0.0f);
203     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
204 
205     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
206     glBindTexture(GL_TEXTURE_2D, 0);
207     ASSERT_GL_NO_ERROR();
208 }
209 
210 // Test to verify samplerVideoWEBGL works fine in ES300 when extension is enabled.
TEST_P(WEBGLVideoTextureES300Test,VerifySamplerVideoWEBGLInES300)211 TEST_P(WEBGLVideoTextureES300Test, VerifySamplerVideoWEBGLInES300)
212 {
213     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
214 
215     constexpr char kVS[] = R"(#version 300 es
216 in vec2 position;
217 out mediump vec2 texCoord;
218 
219 void main()
220 {
221     gl_Position = vec4(position, 0, 1);
222     texCoord = position * 0.5 + vec2(0.5);
223 })";
224 
225     constexpr char kFS[] = R"(#version 300 es
226 #extension GL_WEBGL_video_texture : require
227 precision mediump float;
228 in mediump vec2 texCoord;
229 uniform mediump samplerVideoWEBGL s;
230 out vec4 my_FragColor;
231 void main()
232 {
233     my_FragColor = texture(s, texCoord);
234 })";
235 
236     ANGLE_GL_PROGRAM(program, kVS, kFS);
237     // Initialize basic red texture.
238     const std::vector<GLColor> redColors(4, GLColor::red);
239     GLTexture texture;
240     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
241     glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
242                  redColors.data());
243     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
244     glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
245     ASSERT_GL_NO_ERROR();
246 
247     drawQuad(program, "position", 0.0f);
248     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
249     glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
250     ASSERT_GL_NO_ERROR();
251 }
252 
253 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WEBGLVideoTextureTest);
254 
255 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WEBGLVideoTextureES300Test);
256 ANGLE_INSTANTIATE_TEST_ES3(WEBGLVideoTextureES300Test);
257 }  // namespace
258