xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLLockSurface3Test.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 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 // EGLLockSurface3Test.cpp:
7 //   EGL extension EGL_KHR_lock_surface
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include <chrono>
13 #include <iostream>
14 #include <thread>
15 #include "test_utils/ANGLETest.h"
16 #include "test_utils/gl_raii.h"
17 #include "util/EGLWindow.h"
18 #include "util/OSWindow.h"
19 
20 using namespace std::chrono_literals;
21 
22 using namespace angle;
23 
24 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLLockSurface3Test);
25 
26 class EGLLockSurface3Test : public ANGLETest<>
27 {
28   public:
EGLLockSurface3Test()29     EGLLockSurface3Test() : mDisplay(EGL_NO_DISPLAY) {}
30 
testSetUp()31     void testSetUp() override
32     {
33         mMajorVersion = GetParam().majorVersion;
34 
35         EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
36         mDisplay           = eglGetPlatformDisplayEXT(
37             EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
38         EXPECT_NE(mDisplay, EGL_NO_DISPLAY);
39         EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
40     }
41 
supportsLockSurface3Extension()42     bool supportsLockSurface3Extension()
43     {
44         return IsEGLDisplayExtensionEnabled(mDisplay, "EGL_KHR_lock_surface3");
45     }
46 
testTearDown()47     void testTearDown() override
48     {
49         if (mDisplay != EGL_NO_DISPLAY)
50         {
51             eglTerminate(mDisplay);
52             eglReleaseThread();
53             mDisplay = EGL_NO_DISPLAY;
54         }
55         ASSERT_EGL_SUCCESS() << "Error during test TearDown";
56     }
57 
58     // This will work for Windows and linux systemsAny other BGRA systems will have to be included.
ChannelOrder(GLColor colorIn)59     GLColor ChannelOrder(GLColor colorIn)
60     {
61         GLColor color = colorIn;
62         if (IsWindows() || IsLinux())
63         {  // BGRA channel order
64             color.R = colorIn.B;
65             color.B = colorIn.R;
66         }
67         return color;
68     }
69 
fillBitMapRGBA32(GLColor colorIn,uint32_t * bitMapPtr,EGLint stride)70     void fillBitMapRGBA32(GLColor colorIn, uint32_t *bitMapPtr, EGLint stride)
71     {
72         for (uint32_t y = 0; y < kHeight; y++)
73         {
74             uint32_t *pixelPtr = bitMapPtr + (y * (stride / 4));
75             for (uint32_t x = 0; x < kWidth; x++)
76             {
77                 pixelPtr[x] = ChannelOrder(colorIn).asUint();
78             }
79         }
80     }
81 
checkBitMapRGBA32(GLColor colorIn,uint32_t * bitMapPtr,EGLint stride)82     bool checkBitMapRGBA32(GLColor colorIn, uint32_t *bitMapPtr, EGLint stride)
83     {
84         std::array<uint32_t, (kWidth * kHeight)> checkmap;
85         std::fill_n(checkmap.begin(), (kWidth * kHeight), ChannelOrder(colorIn).asUint());
86 
87         std::array<uint32_t, (kWidth * kHeight)> bitmap;
88         for (uint32_t i = 0; i < (kWidth * kHeight); i++)
89         {
90             bitmap[i] = bitMapPtr[i];
91         }
92 
93         if (bitmap != checkmap)
94         {
95             return false;
96         }
97 
98         return true;
99     }
100 
checkSurfaceRGBA32(GLColor color)101     bool checkSurfaceRGBA32(GLColor color)
102     {
103         std::array<uint32_t, (kWidth * kHeight)> actual;
104         glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, actual.data());
105         EXPECT_GL_NO_ERROR();
106 
107         std::array<uint32_t, (kWidth * kHeight)> checkmap;
108         std::fill_n(checkmap.begin(), (kWidth * kHeight), color.asUint());
109 
110         if (actual != checkmap)
111         {
112             return false;
113         }
114 
115         return true;
116     }
117 
createTexture()118     GLuint createTexture()
119     {
120         GLuint texture = 0;
121         glGenTextures(1, &texture);
122         glBindTexture(GL_TEXTURE_2D, texture);
123         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
124                      nullptr);
125         EXPECT_GL_NO_ERROR();
126         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
127         EXPECT_GL_NO_ERROR();
128         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
129         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
130         EXPECT_NE(texture, static_cast<GLuint>(0));
131         return texture;
132     }
133 
fillTexture(GLuint textureId,GLColor color)134     bool fillTexture(GLuint textureId, GLColor color)
135     {
136         std::array<GLuint, (kWidth * kHeight)> pixels;
137         std::fill_n(pixels.begin(), (kWidth * kHeight), color.asUint());
138         glBindTexture(GL_TEXTURE_2D, textureId);
139         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
140                         static_cast<void *>(pixels.data()));
141         EXPECT_GL_NO_ERROR();
142         return true;
143     }
144 
renderTexture(GLuint textureId)145     void renderTexture(GLuint textureId)
146     {
147         const char *kVertexShader   = R"(
148             precision highp float;
149             attribute vec4 position;
150             varying vec2 texcoord;
151 
152             void main()
153             {
154                 gl_Position = vec4(position.xy, 0.0, 1.0);
155                 texcoord = (position.xy * 0.5) + 0.5;
156             }
157         )";
158         const char *kFragmentShader = R"(
159             precision highp float;
160             uniform sampler2D tex;
161             varying vec2 texcoord;
162 
163             void main()
164             {
165                 gl_FragColor = texture2D(tex, texcoord);
166             }
167         )";
168 
169         ANGLE_GL_PROGRAM(program, kVertexShader, kFragmentShader);
170         glUseProgram(program);
171         glBindTexture(GL_TEXTURE_2D, textureId);
172         glActiveTexture(GL_TEXTURE0);
173         GLint texture2DUniformLocation = glGetUniformLocation(program, "tex");
174         glUniform1i(texture2DUniformLocation, 0);
175         drawQuad(program, "position", 0.5f);
176         glDeleteProgram(program);
177         EXPECT_GL_NO_ERROR();
178     }
179 
180     int mMajorVersion   = 2;
181     EGLDisplay mDisplay = EGL_NO_DISPLAY;
182 
183     static constexpr EGLint kWidth  = 5;
184     static constexpr EGLint kHeight = 5;
185 };
186 
187 // Create parity between eglQuerySurface and eglQuerySurface64KHR
TEST_P(EGLLockSurface3Test,QuerySurfaceAndQuerySurface64Parity)188 TEST_P(EGLLockSurface3Test, QuerySurfaceAndQuerySurface64Parity)
189 {
190     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
191 
192     EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
193     EGLint attribs[]     = {EGL_RED_SIZE,
194                             8,
195                             EGL_GREEN_SIZE,
196                             8,
197                             EGL_BLUE_SIZE,
198                             8,
199                             EGL_ALPHA_SIZE,
200                             8,
201                             EGL_RENDERABLE_TYPE,
202                             clientVersion,
203                             EGL_SURFACE_TYPE,
204                             (EGL_PBUFFER_BIT | EGL_LOCK_SURFACE_BIT_KHR),
205                             EGL_NONE};
206     EGLint count         = 0;
207     EGLConfig config     = EGL_NO_CONFIG_KHR;
208     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
209     EXPECT_GT(count, 0);
210     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
211 
212     EGLint pBufferAttribs[]   = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
213     EGLSurface pBufferSurface = eglCreatePbufferSurface(mDisplay, config, pBufferAttribs);
214     EXPECT_NE(pBufferSurface, EGL_NO_SURFACE);
215 
216     EGLint width         = 0;
217     EGLAttribKHR width64 = 0;
218     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_WIDTH, &width));
219     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_WIDTH, &width64));
220     EXPECT_EQ(static_cast<EGLAttribKHR>(width), width64);
221 
222     EGLint height         = 0;
223     EGLAttribKHR height64 = 0;
224     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_HEIGHT, &height));
225     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_HEIGHT, &height64));
226     EXPECT_EQ(static_cast<EGLAttribKHR>(height), height64);
227 
228     EXPECT_EGL_TRUE(eglDestroySurface(mDisplay, pBufferSurface));
229 }
230 
231 // Create PBufferSurface, Lock, check all the attributes, unlock.
TEST_P(EGLLockSurface3Test,AttributeTest)232 TEST_P(EGLLockSurface3Test, AttributeTest)
233 {
234     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
235 
236     EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
237     EGLint attribs[]     = {EGL_RED_SIZE,
238                             8,
239                             EGL_GREEN_SIZE,
240                             8,
241                             EGL_BLUE_SIZE,
242                             8,
243                             EGL_ALPHA_SIZE,
244                             8,
245                             EGL_RENDERABLE_TYPE,
246                             clientVersion,
247                             EGL_SURFACE_TYPE,
248                             (EGL_PBUFFER_BIT | EGL_LOCK_SURFACE_BIT_KHR),
249                             EGL_NONE};
250     EGLint count         = 0;
251     EGLConfig config     = EGL_NO_CONFIG_KHR;
252     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
253     EXPECT_GT(count, 0);
254     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
255 
256     EGLint pBufferAttribs[]   = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
257     EGLSurface pBufferSurface = eglCreatePbufferSurface(mDisplay, config, pBufferAttribs);
258     EXPECT_NE(pBufferSurface, EGL_NO_SURFACE);
259 
260     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR, EGL_NONE};
261     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, pBufferSurface, lockAttribs));
262 
263     EGLAttribKHR bitMapPtr = 0;
264     EXPECT_EGL_TRUE(
265         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_POINTER_KHR, &bitMapPtr));
266     EXPECT_NE(bitMapPtr, 0);
267 
268     EGLAttribKHR bitMapPitch = 0;
269     EXPECT_EGL_TRUE(
270         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
271     EXPECT_NE(bitMapPitch, 0);
272 
273     EGLAttribKHR bitMapOrigin = 0;
274     EXPECT_EGL_TRUE(
275         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_ORIGIN_KHR, &bitMapOrigin));
276     EXPECT_TRUE((bitMapOrigin == EGL_LOWER_LEFT_KHR) || (bitMapOrigin == EGL_UPPER_LEFT_KHR));
277 
278     EGLAttribKHR bitMapPixelRedOffset = 0;
279     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_RED_OFFSET_KHR,
280                                          &bitMapPixelRedOffset));
281     EXPECT_TRUE((bitMapPixelRedOffset == 0) || (bitMapPixelRedOffset == 16));
282 
283     EGLAttribKHR bitMapPixelGreenOffset = 0;
284     EXPECT_EGL_TRUE(eglQuerySurface64KHR(
285         mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR, &bitMapPixelGreenOffset));
286     EXPECT_EQ(bitMapPixelGreenOffset, 8);
287 
288     EGLAttribKHR bitMapPixelBlueOffset = 0;
289     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR,
290                                          &bitMapPixelBlueOffset));
291     EXPECT_TRUE((bitMapPixelBlueOffset == 16) || (bitMapPixelBlueOffset == 0));
292 
293     EGLAttribKHR bitMapPixelAlphaOffset = 0;
294     EXPECT_EGL_TRUE(eglQuerySurface64KHR(
295         mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR, &bitMapPixelAlphaOffset));
296     EXPECT_EQ(bitMapPixelAlphaOffset, 24);
297 
298     EGLAttribKHR bitMapPixelLuminanceOffset = 0;
299     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface,
300                                          EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR,
301                                          &bitMapPixelLuminanceOffset));
302     EXPECT_EQ(bitMapPixelLuminanceOffset, 0);
303 
304     EGLAttribKHR bitMapPixelSize = 0;
305     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_SIZE_KHR,
306                                          &bitMapPixelSize));
307     EXPECT_EQ(bitMapPixelSize, 32);
308 
309     EGLint bitMapPitchInt = 0;
310     EXPECT_EGL_TRUE(
311         eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitchInt));
312     EXPECT_NE(bitMapPitchInt, 0);
313 
314     EGLint bitMapOriginInt = 0;
315     EXPECT_EGL_TRUE(
316         eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_ORIGIN_KHR, &bitMapOriginInt));
317     EXPECT_TRUE((bitMapOriginInt == EGL_LOWER_LEFT_KHR) || (bitMapOriginInt == EGL_UPPER_LEFT_KHR));
318 
319     EGLint bitMapPixelRedOffsetInt = 0;
320     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_RED_OFFSET_KHR,
321                                     &bitMapPixelRedOffsetInt));
322     EXPECT_TRUE((bitMapPixelRedOffsetInt == 0) || (bitMapPixelRedOffsetInt == 16));
323 
324     EGLint bitMapPixelGreenOffsetInt = 0;
325     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR,
326                                     &bitMapPixelGreenOffsetInt));
327     EXPECT_EQ(bitMapPixelGreenOffsetInt, 8);
328 
329     EGLint bitMapPixelBlueOffsetInt = 0;
330     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR,
331                                     &bitMapPixelBlueOffsetInt));
332     EXPECT_TRUE((bitMapPixelBlueOffsetInt == 16) || (bitMapPixelBlueOffsetInt == 0));
333 
334     EGLint bitMapPixelAlphaOffsetInt = 0;
335     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR,
336                                     &bitMapPixelAlphaOffsetInt));
337     EXPECT_EQ(bitMapPixelAlphaOffsetInt, 24);
338 
339     EGLint bitMapPixelLuminanceOffsetInt = 0;
340     EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR,
341                                     &bitMapPixelLuminanceOffsetInt));
342     EXPECT_EQ(bitMapPixelLuminanceOffsetInt, 0);
343 
344     EGLint bitMapPixelSizeInt = 0;
345     EXPECT_EGL_TRUE(
346         eglQuerySurface(mDisplay, pBufferSurface, EGL_BITMAP_PIXEL_SIZE_KHR, &bitMapPixelSizeInt));
347     EXPECT_EQ(bitMapPixelSizeInt, 32);
348 
349     EXPECT_EGL_TRUE(eglUnlockSurfaceKHR(mDisplay, pBufferSurface));
350 }
351 
352 // Create PBufferSurface, glClear Green, Draw red quad, Lock, check buffer for red,
353 //  Write white pixels, Unlock, Test pixels for white
TEST_P(EGLLockSurface3Test,PbufferSurfaceReadWriteTest)354 TEST_P(EGLLockSurface3Test, PbufferSurfaceReadWriteTest)
355 {
356     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
357 
358     EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
359     EGLint attribs[]     = {EGL_RED_SIZE,
360                             8,
361                             EGL_GREEN_SIZE,
362                             8,
363                             EGL_BLUE_SIZE,
364                             8,
365                             EGL_ALPHA_SIZE,
366                             8,
367                             EGL_RENDERABLE_TYPE,
368                             clientVersion,
369                             EGL_SURFACE_TYPE,
370                             (EGL_PBUFFER_BIT | EGL_LOCK_SURFACE_BIT_KHR),
371                             EGL_NONE};
372     EGLint count         = 0;
373     EGLConfig config     = EGL_NO_CONFIG_KHR;
374     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
375     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
376     EXPECT_GT(count, 0);
377 
378     EGLint pBufferAttribs[]   = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
379     EGLSurface pBufferSurface = EGL_NO_SURFACE;
380     pBufferSurface            = eglCreatePbufferSurface(mDisplay, config, pBufferAttribs);
381     EXPECT_NE(pBufferSurface, EGL_NO_SURFACE);
382 
383     EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
384     EGLContext context  = eglCreateContext(mDisplay, config, nullptr, ctxAttribs);
385     EXPECT_NE(context, EGL_NO_CONTEXT);
386 
387     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
388     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
389 
390     glClearColor(kFloatGreen.R, kFloatGreen.G, kFloatGreen.B, kFloatGreen.A);
391     glClear(GL_COLOR_BUFFER_BIT);
392     ASSERT_GL_NO_ERROR() << "glClear failed";
393 
394     const GLColor drawColor = GLColor::red;
395     GLuint texture          = createTexture();
396     EXPECT_TRUE(fillTexture(texture, drawColor));
397     renderTexture(texture);
398     glFinish();
399     ASSERT_GL_NO_ERROR() << "glFinish failed";
400 
401     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
402 
403     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR,
404                             EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE, EGL_NONE};
405     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, pBufferSurface, lockAttribs));
406 
407     EGLAttribKHR bitMap = 0;
408     EXPECT_EGL_TRUE(
409         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_POINTER_KHR, &bitMap));
410     EGLAttribKHR bitMapPitch = 0;
411     uint32_t *bitMapPtr      = (uint32_t *)(bitMap);
412     EXPECT_EGL_TRUE(
413         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
414 
415     EXPECT_TRUE(checkBitMapRGBA32(drawColor, bitMapPtr, bitMapPitch));
416 
417     const GLColor fillColor = GLColor::white;
418     fillBitMapRGBA32(fillColor, bitMapPtr, bitMapPitch);
419 
420     EXPECT_EGL_TRUE(eglUnlockSurfaceKHR(mDisplay, pBufferSurface));
421 
422     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
423     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
424 
425     EXPECT_TRUE(checkSurfaceRGBA32(fillColor));
426 
427     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
428 }
429 
430 // Create PBufferSurface, glClear Green, Lock, check buffer for green, Write white pixels,
431 // Unlock, Test pixels for white.
432 // This expects that a glClear() alone is sufficient to pre-color the Surface
TEST_P(EGLLockSurface3Test,PbufferSurfaceReadWriteDeferredCleaarTest)433 TEST_P(EGLLockSurface3Test, PbufferSurfaceReadWriteDeferredCleaarTest)
434 {
435     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
436 
437     EGLint clientVersion = mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
438     EGLint attribs[]     = {EGL_RED_SIZE,
439                             8,
440                             EGL_GREEN_SIZE,
441                             8,
442                             EGL_BLUE_SIZE,
443                             8,
444                             EGL_ALPHA_SIZE,
445                             8,
446                             EGL_RENDERABLE_TYPE,
447                             clientVersion,
448                             EGL_SURFACE_TYPE,
449                             (EGL_PBUFFER_BIT | EGL_LOCK_SURFACE_BIT_KHR),
450                             EGL_NONE};
451     EGLint count         = 0;
452     EGLConfig config     = EGL_NO_CONFIG_KHR;
453     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
454     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
455     EXPECT_GT(count, 0);
456 
457     EGLint pBufferAttribs[]   = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
458     EGLSurface pBufferSurface = EGL_NO_SURFACE;
459     pBufferSurface            = eglCreatePbufferSurface(mDisplay, config, pBufferAttribs);
460     EXPECT_NE(pBufferSurface, EGL_NO_SURFACE);
461 
462     EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
463     EGLContext context  = eglCreateContext(mDisplay, config, nullptr, ctxAttribs);
464     EXPECT_NE(context, EGL_NO_CONTEXT);
465 
466     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
467     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
468 
469     const GLColor clearColor = GLColor::green;
470     glClearColor(kFloatGreen.R, kFloatGreen.G, kFloatGreen.B, kFloatGreen.A);
471     glClear(GL_COLOR_BUFFER_BIT);
472     ASSERT_GL_NO_ERROR() << "glClear failed";
473 
474     const GLColor drawColor = clearColor;
475 
476     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
477 
478     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_WRITE_SURFACE_BIT_KHR,
479                             EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE, EGL_NONE};
480     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, pBufferSurface, lockAttribs));
481 
482     EGLAttribKHR bitMap = 0;
483     EXPECT_EGL_TRUE(
484         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_POINTER_KHR, &bitMap));
485     EGLAttribKHR bitMapPitch = 0;
486     uint32_t *bitMapPtr      = (uint32_t *)(bitMap);
487     EXPECT_EGL_TRUE(
488         eglQuerySurface64KHR(mDisplay, pBufferSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
489 
490     EXPECT_TRUE(checkBitMapRGBA32(drawColor, bitMapPtr, bitMapPitch));
491 
492     const GLColor fillColor = GLColor::white;
493     fillBitMapRGBA32(fillColor, bitMapPtr, bitMapPitch);
494 
495     EXPECT_EGL_TRUE(eglUnlockSurfaceKHR(mDisplay, pBufferSurface));
496 
497     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
498     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
499 
500     EXPECT_TRUE(checkSurfaceRGBA32(fillColor));
501 
502     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
503 }
504 
505 // Create WindowSurface, Clear Color to GREEN, draw red quad, Lock with PRESERVE_PIXELS,
506 // read/check pixels, Unlock.
TEST_P(EGLLockSurface3Test,WindowSurfaceReadTest)507 TEST_P(EGLLockSurface3Test, WindowSurfaceReadTest)
508 {
509     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
510 
511     EGLint configAttribs[] = {EGL_RED_SIZE,
512                               8,
513                               EGL_GREEN_SIZE,
514                               8,
515                               EGL_BLUE_SIZE,
516                               8,
517                               EGL_ALPHA_SIZE,
518                               8,
519                               EGL_RENDERABLE_TYPE,
520                               (mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT),
521                               EGL_SURFACE_TYPE,
522                               (EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR),
523                               EGL_NONE};
524     EGLint count           = 0;
525     EGLConfig config       = EGL_NO_CONFIG_KHR;
526     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &config, 1, &count));
527     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
528     EXPECT_GT(count, 0);
529 
530     OSWindow *osWindow = OSWindow::New();
531     osWindow->initialize("LockSurfaceTest", kWidth, kHeight);
532     EGLint winAttribs[] = {EGL_NONE};
533     EGLSurface windowSurface =
534         eglCreateWindowSurface(mDisplay, config, osWindow->getNativeWindow(), winAttribs);
535     EXPECT_NE(windowSurface, EGL_NO_SURFACE);
536 
537     EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
538     EGLContext context  = eglCreateContext(mDisplay, config, nullptr, ctxAttribs);
539     EXPECT_NE(context, EGL_NO_CONTEXT);
540 
541     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
542     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
543 
544     glClearColor(kFloatGreen.R, kFloatGreen.G, kFloatGreen.B, kFloatGreen.A);
545     glClear(GL_COLOR_BUFFER_BIT);
546     ASSERT_GL_NO_ERROR() << "glClear failed";
547 
548     const GLColor drawColor = GLColor::red;
549     GLuint texture          = createTexture();
550     EXPECT_TRUE(fillTexture(texture, drawColor));
551     renderTexture(texture);
552     glFinish();
553     ASSERT_GL_NO_ERROR() << "glFinish failed";
554 
555     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
556 
557     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR,
558                             EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE, EGL_NONE};
559     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, windowSurface, lockAttribs));
560 
561     EGLAttribKHR bitMap = 0;
562     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_POINTER_KHR, &bitMap));
563     EGLAttribKHR bitMapPitch = 0;
564     EXPECT_EGL_TRUE(
565         eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
566 
567     uint32_t *bitMapPtr = (uint32_t *)(bitMap);
568     EXPECT_TRUE(checkBitMapRGBA32(drawColor, bitMapPtr, bitMapPitch));
569 
570     EXPECT_TRUE(eglUnlockSurfaceKHR(mDisplay, windowSurface));
571 
572     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
573     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
574     EXPECT_TRUE(checkSurfaceRGBA32(drawColor));
575     EXPECT_EGL_TRUE(eglSwapBuffers(mDisplay, windowSurface));
576 
577     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
578 
579     glDeleteTextures(1, &texture);
580 
581     eglDestroySurface(mDisplay, windowSurface);
582     osWindow->destroy();
583     OSWindow::Delete(&osWindow);
584 }
585 
586 // Test default msaa surface resolve path.
TEST_P(EGLLockSurface3Test,WindowMsaaSurfaceReadTest)587 TEST_P(EGLLockSurface3Test, WindowMsaaSurfaceReadTest)
588 {
589     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
590 
591     EGLint configAttribs[] = {EGL_RED_SIZE,
592                               8,
593                               EGL_GREEN_SIZE,
594                               8,
595                               EGL_BLUE_SIZE,
596                               8,
597                               EGL_ALPHA_SIZE,
598                               8,
599                               EGL_RENDERABLE_TYPE,
600                               (mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT),
601                               EGL_SAMPLE_BUFFERS,
602                               1,
603                               EGL_SAMPLES,
604                               4,
605                               EGL_SURFACE_TYPE,
606                               (EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR),
607                               EGL_NONE};
608     EGLint count           = 0;
609     EGLConfig config       = EGL_NO_CONFIG_KHR;
610     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, configAttribs, &config, 1, &count));
611     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
612     EXPECT_GT(count, 0);
613 
614     OSWindow *osWindow = OSWindow::New();
615     osWindow->initialize("LockSurfaceTest", kWidth, kHeight);
616     EGLint winAttribs[] = {EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER, EGL_NONE};
617     EGLSurface windowSurface =
618         eglCreateWindowSurface(mDisplay, config, osWindow->getNativeWindow(), winAttribs);
619     EXPECT_NE(windowSurface, EGL_NO_SURFACE);
620 
621     EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
622     EGLContext context  = eglCreateContext(mDisplay, config, nullptr, ctxAttribs);
623     EXPECT_NE(context, EGL_NO_CONTEXT);
624 
625     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
626     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
627 
628     glClearColor(kFloatGreen.R, kFloatGreen.G, kFloatGreen.B, kFloatGreen.A);
629     glClear(GL_COLOR_BUFFER_BIT);
630     ASSERT_GL_NO_ERROR() << "glClear failed";
631 
632     const GLColor drawColor = GLColor::red;
633     GLuint texture          = createTexture();
634     EXPECT_TRUE(fillTexture(texture, drawColor));
635     renderTexture(texture);
636     eglSwapBuffers(mDisplay, windowSurface);
637 
638     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
639 
640     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR,
641                             EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE, EGL_NONE};
642     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, windowSurface, lockAttribs));
643 
644     EGLAttribKHR bitMap = 0;
645     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_POINTER_KHR, &bitMap));
646     EGLAttribKHR bitMapPitch = 0;
647     EXPECT_EGL_TRUE(
648         eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
649 
650     uint32_t *bitMapPtr = (uint32_t *)(bitMap);
651     EXPECT_TRUE(checkBitMapRGBA32(drawColor, bitMapPtr, bitMapPitch));
652 
653     EXPECT_TRUE(eglUnlockSurfaceKHR(mDisplay, windowSurface));
654 
655     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
656     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
657     EXPECT_TRUE(checkSurfaceRGBA32(drawColor));
658     EXPECT_EGL_TRUE(eglSwapBuffers(mDisplay, windowSurface));
659 
660     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
661 
662     glDeleteTextures(1, &texture);
663 
664     eglDestroySurface(mDisplay, windowSurface);
665     osWindow->destroy();
666     OSWindow::Delete(&osWindow);
667 }
668 
669 // Create WindowSurface, Lock surface, Write pixels red, Unlock, check pixels,
670 //  then swapbuffers to visually check.
TEST_P(EGLLockSurface3Test,WindowSurfaceWritePreserveTest)671 TEST_P(EGLLockSurface3Test, WindowSurfaceWritePreserveTest)
672 {
673     ANGLE_SKIP_TEST_IF(!supportsLockSurface3Extension());
674 
675     EGLint attribs[] = {EGL_RED_SIZE,
676                         8,
677                         EGL_GREEN_SIZE,
678                         8,
679                         EGL_BLUE_SIZE,
680                         8,
681                         EGL_ALPHA_SIZE,
682                         8,
683                         EGL_RENDERABLE_TYPE,
684                         (mMajorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT),
685                         EGL_SURFACE_TYPE,
686                         (EGL_WINDOW_BIT | EGL_LOCK_SURFACE_BIT_KHR),
687                         EGL_NONE};
688     EGLint count     = 0;
689     EGLConfig config = EGL_NO_CONFIG_KHR;
690     EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, attribs, &config, 1, &count));
691     ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
692     EXPECT_GT(count, 0);
693 
694     OSWindow *osWindow = OSWindow::New();
695     osWindow->initialize("LockSurfaceTest", kWidth, kHeight);
696     EGLint winAttribs[] = {EGL_NONE};
697     EGLSurface windowSurface =
698         eglCreateWindowSurface(mDisplay, config, osWindow->getNativeWindow(), winAttribs);
699     EXPECT_NE(windowSurface, EGL_NO_SURFACE);
700 
701     EGLint ctxAttribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion, EGL_NONE};
702     EGLContext context  = eglCreateContext(mDisplay, config, nullptr, ctxAttribs);
703     EXPECT_NE(context, EGL_NO_CONTEXT);
704 
705     EGLint lockAttribs[] = {EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR, EGL_NONE};
706     EXPECT_EGL_TRUE(eglLockSurfaceKHR(mDisplay, windowSurface, lockAttribs));
707 
708     EGLAttribKHR bitMap = 0;
709     EXPECT_EGL_TRUE(eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_POINTER_KHR, &bitMap));
710     EGLAttribKHR bitMapPitch = 0;
711     EXPECT_EGL_TRUE(
712         eglQuerySurface64KHR(mDisplay, windowSurface, EGL_BITMAP_PITCH_KHR, &bitMapPitch));
713     uint32_t *bitMapPtr = (uint32_t *)(bitMap);
714 
715     const GLColor fillColor = GLColor::red;
716     fillBitMapRGBA32(fillColor, bitMapPtr, bitMapPitch);
717 
718     EXPECT_EGL_TRUE(eglUnlockSurfaceKHR(mDisplay, windowSurface));
719 
720     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
721     ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
722     EXPECT_TRUE(checkSurfaceRGBA32(fillColor));
723     EXPECT_EGL_TRUE(eglSwapBuffers(mDisplay, windowSurface));
724 
725     EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
726 
727     eglDestroySurface(mDisplay, windowSurface);
728     osWindow->destroy();
729     OSWindow::Delete(&osWindow);
730 }
731 
732 ANGLE_INSTANTIATE_TEST(EGLLockSurface3Test,
733                        WithNoFixture(ES2_VULKAN()),
734                        WithNoFixture(ES3_VULKAN()));
735