• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 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 // ExternalWrapTest:
7 //   Tests EXT_EGL_image_external_wrap_modes
8 //
9 
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12 #include "util/EGLWindow.h"
13 
14 constexpr int kPixelThreshold = 1;
15 
16 namespace angle
17 {
18 class ExternalWrapTest : public ANGLETest
19 {
20   protected:
ExternalWrapTest()21     ExternalWrapTest() : mProgram(0), mSourceTexture(0), mExternalImage(0), mExternalTexture(0)
22     {
23         setWindowWidth(128);
24         setWindowHeight(128);
25         setConfigRedBits(8);
26         setConfigGreenBits(8);
27         setConfigBlueBits(8);
28         setConfigAlphaBits(8);
29         setConfigDepthBits(24);
30     }
31 
testSetUp()32     void testSetUp() override
33     {
34         if (!IsGLExtensionEnabled("GL_OES_EGL_image_external"))
35         {
36             return;
37         }
38 
39         const char *vertSrc = R"(precision highp float;
40 attribute vec4 a_position;
41 varying vec2 v_texcoord;
42 
43 uniform vec2 u_offset;
44 
45 void main()
46 {
47     gl_Position = a_position;
48     v_texcoord = (a_position.xy * 0.5) + 0.5 + u_offset;
49 }
50 )";
51         const char *fragSrc = R"(#extension GL_OES_EGL_image_external : require
52 precision highp float;
53 uniform samplerExternalOES s_tex;
54 varying vec2 v_texcoord;
55 
56 void main()
57 {
58     gl_FragColor = texture2D(s_tex, v_texcoord);
59 }
60 )";
61 
62         mProgram = CompileProgram(vertSrc, fragSrc);
63         ASSERT_GL_NO_ERROR();
64         ASSERT_NE(mProgram, 0u);
65 
66         constexpr GLsizei texSize = 32;
67         GLubyte data[texSize * texSize * 4];
68 
69         for (int y = 0; y < texSize; y++)
70         {
71             float green = static_cast<float>(y) / texSize;
72             for (int x = 0; x < texSize; x++)
73             {
74                 float red = static_cast<float>(x) / texSize;
75 
76                 data[(y * texSize + x) * 4 + 0] = static_cast<GLubyte>(red * 255);
77                 data[(y * texSize + x) * 4 + 1] = static_cast<GLubyte>(green * 255);
78 
79                 data[(y * texSize + x) * 4 + 2] = 0;
80                 data[(y * texSize + x) * 4 + 3] = 255;
81             }
82         }
83 
84         glGenTextures(1, &mSourceTexture);
85         glBindTexture(GL_TEXTURE_2D, mSourceTexture);
86         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
87                      data);
88 
89         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
90         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
91         ASSERT_GL_NO_ERROR();
92 
93         glGenTextures(1, &mExternalTexture);
94 
95         ASSERT_GL_NO_ERROR();
96     }
97 
testTearDown()98     void testTearDown() override
99     {
100         if (mProgram != 0)
101         {
102             glDeleteProgram(mProgram);
103         }
104         if (mExternalTexture != 0)
105         {
106             glDeleteTextures(1, &mExternalTexture);
107         }
108         if (mSourceTexture != 0)
109         {
110             glDeleteTextures(1, &mSourceTexture);
111         }
112     }
113 
createExternalTexture()114     void createExternalTexture()
115     {
116         ASSERT_TRUE(IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
117                                                  "EGL_KHR_gl_texture_2D_image"));
118         ASSERT_TRUE(IsGLExtensionEnabled("GL_OES_EGL_image_external"));
119 
120         EGLWindow *window = getEGLWindow();
121         EGLint attribs[]  = {
122             EGL_IMAGE_PRESERVED,
123             EGL_TRUE,
124             EGL_NONE,
125         };
126         EGLImageKHR image =
127             eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
128                               reinterpret_cast<EGLClientBuffer>(mSourceTexture), attribs);
129         ASSERT_EGL_SUCCESS();
130 
131         glBindTexture(GL_TEXTURE_EXTERNAL_OES, mExternalTexture);
132         glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image);
133 
134         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
135         glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
136 
137         ASSERT_GL_NO_ERROR();
138     }
139 
140     GLuint mProgram;
141     GLuint mTextureUniformLocation;
142     GLuint mOffsetUniformLocation;
143 
144     GLuint mSourceTexture;
145     EGLImageKHR mExternalImage;
146     GLuint mExternalTexture;
147 };
148 
149 // Test the default sampling behavior of an external texture
TEST_P(ExternalWrapTest,NoWrap)150 TEST_P(ExternalWrapTest, NoWrap)
151 {
152     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
153     ANGLE_SKIP_TEST_IF(
154         !IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
155 
156     // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
157     ANGLE_SKIP_TEST_IF(IsOzone());
158 
159     createExternalTexture();
160 
161     ASSERT_NE(mProgram, 0u);
162     glUseProgram(mProgram);
163     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mExternalTexture);
164     glUniform2f(glGetUniformLocation(mProgram, "u_offset"), 0.0, 0.0);
165     drawQuad(mProgram, "a_position", 0);
166     EXPECT_GL_NO_ERROR();
167 
168     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(0, 0, 0, 255), kPixelThreshold);
169     EXPECT_PIXEL_COLOR_NEAR(127, 0, GLColor(247, 0, 0, 255), kPixelThreshold);
170     EXPECT_PIXEL_COLOR_NEAR(0, 127, GLColor(0, 247, 0, 255), kPixelThreshold);
171     EXPECT_PIXEL_COLOR_NEAR(127, 127, GLColor(247, 247, 0, 255), kPixelThreshold);
172 }
173 
174 // Test that external textures are sampled correctly when used with GL_CLAMP_TO_EDGE
TEST_P(ExternalWrapTest,ClampToEdge)175 TEST_P(ExternalWrapTest, ClampToEdge)
176 {
177     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
178     ANGLE_SKIP_TEST_IF(
179         !IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
180 
181     // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
182     ANGLE_SKIP_TEST_IF(IsOzone());
183 
184     createExternalTexture();
185 
186     ASSERT_NE(mProgram, 0u);
187     glUseProgram(mProgram);
188     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mExternalTexture);
189     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
190     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
191     glUniform2f(glGetUniformLocation(mProgram, "u_offset"), 0.5, 0.5);
192     drawQuad(mProgram, "a_position", 0);
193     EXPECT_GL_NO_ERROR();
194 
195     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 127, 0, 255), kPixelThreshold);
196     EXPECT_PIXEL_COLOR_NEAR(127, 0, GLColor(247, 127, 0, 255), kPixelThreshold);
197     EXPECT_PIXEL_COLOR_NEAR(0, 127, GLColor(127, 247, 0, 255), kPixelThreshold);
198     EXPECT_PIXEL_COLOR_NEAR(127, 127, GLColor(247, 247, 0, 255), kPixelThreshold);
199 }
200 
201 // Test that external textures are sampled correctly when used with GL_REPEAT
TEST_P(ExternalWrapTest,Repeat)202 TEST_P(ExternalWrapTest, Repeat)
203 {
204     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
205     ANGLE_SKIP_TEST_IF(
206         !IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
207     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_EGL_image_external_wrap_modes"));
208 
209     // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
210     ANGLE_SKIP_TEST_IF(IsOzone());
211 
212     createExternalTexture();
213 
214     ASSERT_NE(mProgram, 0u);
215     glUseProgram(mProgram);
216     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mExternalTexture);
217     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_REPEAT);
218     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_REPEAT);
219     glUniform2f(glGetUniformLocation(mProgram, "u_offset"), 0.5, 0.5);
220 
221     drawQuad(mProgram, "a_position", 0);
222     EXPECT_GL_NO_ERROR();
223 
224     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 127, 0, 255), kPixelThreshold);
225     EXPECT_PIXEL_COLOR_NEAR(127, 0, GLColor(119, 127, 0, 255), kPixelThreshold);
226     EXPECT_PIXEL_COLOR_NEAR(0, 127, GLColor(127, 119, 0, 255), kPixelThreshold);
227     EXPECT_PIXEL_COLOR_NEAR(127, 127, GLColor(119, 119, 0, 255), kPixelThreshold);
228 
229     EXPECT_PIXEL_COLOR_NEAR(63, 63, GLColor(247, 247, 0, 255), kPixelThreshold);
230     EXPECT_PIXEL_COLOR_NEAR(64, 63, GLColor(0, 247, 0, 255), kPixelThreshold);
231 }
232 
233 // Test that external textures are sampled correctly when used with GL_MIRRORED_REPEAT
TEST_P(ExternalWrapTest,MirroredRepeat)234 TEST_P(ExternalWrapTest, MirroredRepeat)
235 {
236     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image_external"));
237     ANGLE_SKIP_TEST_IF(
238         !IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
239     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_EGL_image_external_wrap_modes"));
240 
241     // Ozone only supports external target for images created with EGL_EXT_image_dma_buf_import
242     ANGLE_SKIP_TEST_IF(IsOzone());
243 
244     createExternalTexture();
245 
246     ASSERT_NE(mProgram, 0u);
247     glUseProgram(mProgram);
248     glBindTexture(GL_TEXTURE_EXTERNAL_OES, mExternalTexture);
249     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
250     glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
251     glUniform2f(glGetUniformLocation(mProgram, "u_offset"), 0.5, 0.5);
252 
253     drawQuad(mProgram, "a_position", 0);
254     EXPECT_GL_NO_ERROR();
255 
256     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 127, 0, 255), kPixelThreshold);
257     EXPECT_PIXEL_COLOR_NEAR(127, 0, GLColor(127, 127, 0, 255), kPixelThreshold);
258     EXPECT_PIXEL_COLOR_NEAR(0, 127, GLColor(127, 127, 0, 255), kPixelThreshold);
259     EXPECT_PIXEL_COLOR_NEAR(127, 127, GLColor(127, 127, 0, 255), kPixelThreshold);
260 
261     EXPECT_PIXEL_COLOR_NEAR(63, 63, GLColor(247, 247, 0, 255), kPixelThreshold);
262     EXPECT_PIXEL_COLOR_NEAR(64, 63, GLColor(247, 247, 0, 255), kPixelThreshold);
263 }
264 
265 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
266 // tests should be run against.
267 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ExternalWrapTest);
268 }  // namespace angle
269