xref: /aosp_15_r20/external/angle/src/tests/egl_tests/EGLPreRotationTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // EGLPreRotationTest:
7 //   Tests pertaining to Android pre-rotation.
8 //
9 
10 #include <gtest/gtest.h>
11 
12 #include <vector>
13 
14 #include "common/Color.h"
15 #include "common/platform.h"
16 #include "test_utils/ANGLETest.h"
17 #include "test_utils/gl_raii.h"
18 #include "util/EGLWindow.h"
19 #include "util/OSWindow.h"
20 #include "util/Timer.h"
21 #include "util/test_utils.h"
22 
23 using namespace angle;
24 
25 namespace
26 {
27 
28 using EGLPreRotationSurfaceTestParams = std::tuple<angle::PlatformParameters, bool>;
29 
PrintToStringParamName(const::testing::TestParamInfo<EGLPreRotationSurfaceTestParams> & info)30 std::string PrintToStringParamName(
31     const ::testing::TestParamInfo<EGLPreRotationSurfaceTestParams> &info)
32 {
33     std::stringstream ss;
34     ss << std::get<0>(info.param);
35     if (std::get<1>(info.param))
36     {
37         ss << "__PreRotationEnabled";
38     }
39     else
40     {
41         ss << "__PreRotationDisabled";
42     }
43     return ss.str();
44 }
45 
46 // A class to test various Android pre-rotation cases.  In order to make it easier to debug test
47 // failures, the initial window size is 256x256, and each pixel will have a unique and predictable
48 // value.  The red channel will increment with the x axis, and the green channel will increment
49 // with the y axis.  The four corners will have the following values:
50 //
51 // Where                 GLES Render &  ReadPixels coords       Color    (in Hex)
52 // Lower-left,  which is (-1.0,-1.0) & (  0,   0) in GLES will be black  (0x00, 0x00, 0x00, 0xFF)
53 // Lower-right, which is ( 1.0,-1.0) & (256,   0) in GLES will be red    (0xFF, 0x00, 0x00, 0xFF)
54 // Upper-left,  which is (-1.0, 1.0) & (  0, 256) in GLES will be green  (0x00, 0xFF, 0x00, 0xFF)
55 // Upper-right, which is ( 1.0, 1.0) & (256, 256) in GLES will be yellow (0xFF, 0xFF, 0x00, 0xFF)
56 class EGLPreRotationSurfaceTest : public ANGLETest<EGLPreRotationSurfaceTestParams>
57 {
58   protected:
EGLPreRotationSurfaceTest()59     EGLPreRotationSurfaceTest()
60         : mDisplay(EGL_NO_DISPLAY),
61           mWindowSurface(EGL_NO_SURFACE),
62           mContext(EGL_NO_CONTEXT),
63           mOSWindow(nullptr),
64           mSize(256)
65     {}
66 
67     // Release any resources created in the test body
testTearDown()68     void testTearDown() override
69     {
70         if (mDisplay != EGL_NO_DISPLAY)
71         {
72             eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
73 
74             if (mWindowSurface != EGL_NO_SURFACE)
75             {
76                 eglDestroySurface(mDisplay, mWindowSurface);
77                 mWindowSurface = EGL_NO_SURFACE;
78             }
79 
80             if (mContext != EGL_NO_CONTEXT)
81             {
82                 eglDestroyContext(mDisplay, mContext);
83                 mContext = EGL_NO_CONTEXT;
84             }
85 
86             eglTerminate(mDisplay);
87             mDisplay = EGL_NO_DISPLAY;
88         }
89 
90         mOSWindow->destroy();
91         OSWindow::Delete(&mOSWindow);
92 
93         ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT);
94     }
95 
testSetUp()96     void testSetUp() override
97     {
98         mOSWindow = OSWindow::New();
99         mOSWindow->initialize("EGLSurfaceTest", mSize, mSize);
100     }
101 
initializeDisplay()102     void initializeDisplay()
103     {
104         const angle::PlatformParameters platform = ::testing::get<0>(GetParam());
105         GLenum platformType                      = platform.getRenderer();
106         GLenum deviceType                        = platform.getDeviceType();
107 
108         std::vector<const char *> enabledFeatures;
109         std::vector<const char *> disabledFeatures;
110         if (::testing::get<1>(GetParam()))
111         {
112             enabledFeatures.push_back("enablePreRotateSurfaces");
113         }
114         else
115         {
116             disabledFeatures.push_back("enablePreRotateSurfaces");
117         }
118         enabledFeatures.push_back(nullptr);
119         disabledFeatures.push_back(nullptr);
120 
121         std::vector<EGLAttrib> displayAttributes;
122         displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
123         displayAttributes.push_back(platformType);
124         displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
125         displayAttributes.push_back(EGL_DONT_CARE);
126         displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
127         displayAttributes.push_back(EGL_DONT_CARE);
128         displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
129         displayAttributes.push_back(deviceType);
130         displayAttributes.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
131         displayAttributes.push_back(reinterpret_cast<EGLAttrib>(enabledFeatures.data()));
132         displayAttributes.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);
133         displayAttributes.push_back(reinterpret_cast<EGLAttrib>(disabledFeatures.data()));
134         displayAttributes.push_back(EGL_NONE);
135 
136         mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
137                                          reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
138                                          displayAttributes.data());
139         ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
140 
141         EGLint majorVersion, minorVersion;
142         ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);
143 
144         eglBindAPI(EGL_OPENGL_ES_API);
145         ASSERT_EGL_SUCCESS();
146     }
147 
initializeContext()148     void initializeContext()
149     {
150         EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION,
151                                      ::testing::get<0>(GetParam()).majorVersion, EGL_NONE};
152 
153         mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
154         ASSERT_EGL_SUCCESS();
155     }
156 
initializeSurfaceWithRGBA8888Config()157     void initializeSurfaceWithRGBA8888Config()
158     {
159         const EGLint configAttributes[] = {
160             EGL_RED_SIZE,   8, EGL_GREEN_SIZE,   8, EGL_BLUE_SIZE,      8, EGL_ALPHA_SIZE, 8,
161             EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};
162 
163         EGLint configCount;
164         EGLConfig config;
165         ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) ||
166                     (configCount != 1) == EGL_TRUE);
167 
168         mConfig = config;
169 
170         EGLint surfaceType = EGL_NONE;
171         eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
172 
173         std::vector<EGLint> windowAttributes;
174         windowAttributes.push_back(EGL_NONE);
175 
176         if (surfaceType & EGL_WINDOW_BIT)
177         {
178             // Create first window surface
179             mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
180                                                     windowAttributes.data());
181             ASSERT_EGL_SUCCESS();
182         }
183 
184         initializeContext();
185     }
186 
initializeSurfaceWithRGBA8888d24s8Config()187     void initializeSurfaceWithRGBA8888d24s8Config()
188     {
189         const EGLint configAttributes[] = {
190             EGL_RED_SIZE,   8,  EGL_GREEN_SIZE,   8, EGL_BLUE_SIZE,      8, EGL_ALPHA_SIZE, 8,
191             EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};
192 
193         EGLint configCount;
194         EGLConfig config;
195         ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) ||
196                     (configCount != 1) == EGL_TRUE);
197 
198         mConfig = config;
199 
200         EGLint surfaceType = EGL_NONE;
201         eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
202 
203         std::vector<EGLint> windowAttributes;
204         windowAttributes.push_back(EGL_NONE);
205 
206         if (surfaceType & EGL_WINDOW_BIT)
207         {
208             // Create first window surface
209             mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
210                                                     windowAttributes.data());
211             ASSERT_EGL_SUCCESS();
212         }
213 
214         initializeContext();
215     }
216 
testDrawingAndReadPixels()217     void testDrawingAndReadPixels()
218     {
219         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
220         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
221         EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);
222         EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);
223         EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor::yellow);
224         ASSERT_GL_NO_ERROR();
225 
226         eglSwapBuffers(mDisplay, mWindowSurface);
227         ASSERT_EGL_SUCCESS();
228 
229         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
230         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
231         EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);
232         EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);
233         EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor::yellow);
234         ASSERT_GL_NO_ERROR();
235 
236         {
237             // Now, test a 4x4 area in the center of the window, which should tell us if a non-1x1
238             // ReadPixels is oriented correctly for the device's orientation:
239             GLint xOffset  = 126;
240             GLint yOffset  = 126;
241             GLsizei width  = 4;
242             GLsizei height = 4;
243             std::vector<GLColor> pixels(width * height);
244             glReadPixels(xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
245             EXPECT_GL_NO_ERROR();
246             // Expect that all red values equate to x and green values equate to y
247             for (int y = 0; y < height; y++)
248             {
249                 for (int x = 0; x < width; x++)
250                 {
251                     int index = (y * width) + x;
252                     GLColor expectedPixel(xOffset + x, yOffset + y, 0, 255);
253                     GLColor actualPixel = pixels[index];
254                     EXPECT_EQ(expectedPixel, actualPixel);
255                 }
256             }
257         }
258 
259         {
260             // Now, test a 8x4 area off-the-center of the window, just to make sure that works too:
261             GLint xOffset  = 13;
262             GLint yOffset  = 26;
263             GLsizei width  = 8;
264             GLsizei height = 4;
265             std::vector<GLColor> pixels2(width * height);
266             glReadPixels(xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels2[0]);
267             EXPECT_GL_NO_ERROR();
268             // Expect that all red values equate to x and green values equate to y
269             for (int y = 0; y < height; y++)
270             {
271                 for (int x = 0; x < width; x++)
272                 {
273                     int index = (y * width) + x;
274                     GLColor expectedPixel(xOffset + x, yOffset + y, 0, 255);
275                     GLColor actualPixel = pixels2[index];
276                     EXPECT_EQ(expectedPixel, actualPixel);
277                 }
278             }
279         }
280 
281         eglSwapBuffers(mDisplay, mWindowSurface);
282         ASSERT_EGL_SUCCESS();
283     }
284 
285     EGLDisplay mDisplay;
286     EGLSurface mWindowSurface;
287     EGLContext mContext;
288     EGLConfig mConfig;
289     OSWindow *mOSWindow;
290     int mSize;
291 };
292 
293 // Provide a predictable pattern for testing pre-rotation
TEST_P(EGLPreRotationSurfaceTest,OrientedWindowWithDraw)294 TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDraw)
295 {
296     // http://anglebug.com/42263074
297     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
298 
299     // Flaky on Linux SwANGLE http://anglebug.com/42263074
300     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
301 
302     // To aid in debugging, we want this window visible
303     setWindowVisible(mOSWindow, true);
304 
305     initializeDisplay();
306     initializeSurfaceWithRGBA8888Config();
307 
308     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
309     ASSERT_EGL_SUCCESS();
310 
311     // Init program
312     constexpr char kVS[] =
313         "attribute vec2 position;\n"
314         "attribute vec2 redGreen;\n"
315         "varying vec2 v_data;\n"
316         "void main() {\n"
317         "  gl_Position = vec4(position, 0, 1);\n"
318         "  v_data = redGreen;\n"
319         "}";
320 
321     constexpr char kFS[] =
322         "varying highp vec2 v_data;\n"
323         "void main() {\n"
324         "  gl_FragColor = vec4(v_data, 0, 1);\n"
325         "}";
326 
327     ANGLE_GL_PROGRAM(program, kVS, kFS);
328     glUseProgram(program);
329 
330     GLint positionLocation = glGetAttribLocation(program, "position");
331     ASSERT_NE(-1, positionLocation);
332 
333     GLint redGreenLocation = glGetAttribLocation(program, "redGreen");
334     ASSERT_NE(-1, redGreenLocation);
335 
336     GLBuffer indexBuffer;
337     GLVertexArray vertexArray;
338     GLBuffer vertexBuffers[2];
339 
340     glBindVertexArray(vertexArray);
341 
342     std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};
343     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
344     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
345                  GL_STATIC_DRAW);
346 
347     std::vector<GLfloat> positionData = {// quad vertices
348                                          -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
349 
350     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
351     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
352                  GL_STATIC_DRAW);
353     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
354     glEnableVertexAttribArray(positionLocation);
355 
356     std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)
357                                          0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};
358 
359     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
360     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],
361                  GL_STATIC_DRAW);
362     glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
363     glEnableVertexAttribArray(redGreenLocation);
364 
365     ASSERT_GL_NO_ERROR();
366 
367     testDrawingAndReadPixels();
368 }
369 
370 // Use dFdx() and dFdy() and still provide a predictable pattern for testing pre-rotation
371 // In this case, the color values will be the following: (dFdx(v_data.x), dFdy(v_data.y), 0, 1).
372 // To help make this meaningful for pre-rotation, the derivatives will vary in the four corners of
373 // the window:
374 //
375 //  +------------+------------+      +--------+--------+
376 //  | (  0, 219) | (239, 249) |      | Green  | Yellow |
377 //  +------------+------------+  OR  +--------+--------+
378 //  | (  0,   0) | (229,   0) |      | Black  |  Red   |
379 //  +------------+------------+      +--------+--------+
TEST_P(EGLPreRotationSurfaceTest,OrientedWindowWithDerivativeDraw)380 TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDerivativeDraw)
381 {
382     // http://anglebug.com/42263074
383     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
384 
385     // Flaky on Linux SwANGLE http://anglebug.com/42263074
386     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
387 
388     // To aid in debugging, we want this window visible
389     setWindowVisible(mOSWindow, true);
390 
391     initializeDisplay();
392     initializeSurfaceWithRGBA8888Config();
393 
394     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
395     ASSERT_EGL_SUCCESS();
396 
397     // Init program
398     constexpr char kVS[] =
399         "#version 300 es\n"
400         "in highp vec2 position;\n"
401         "in highp vec2 redGreen;\n"
402         "out highp vec2 v_data;\n"
403         "void main() {\n"
404         "  gl_Position = vec4(position, 0, 1);\n"
405         "  v_data = redGreen;\n"
406         "}";
407 
408     constexpr char kFS[] =
409         "#version 300 es\n"
410         "in highp vec2 v_data;\n"
411         "out highp vec4 FragColor;\n"
412         "void main() {\n"
413         "  FragColor = vec4(dFdx(v_data.x), dFdy(v_data.y), 0, 1);\n"
414         "}";
415 
416     ANGLE_GL_PROGRAM(program, kVS, kFS);
417     glUseProgram(program);
418 
419     GLint positionLocation = glGetAttribLocation(program, "position");
420     ASSERT_NE(-1, positionLocation);
421 
422     GLint redGreenLocation = glGetAttribLocation(program, "redGreen");
423     ASSERT_NE(-1, redGreenLocation);
424 
425     GLBuffer indexBuffer;
426     GLVertexArray vertexArray;
427     GLBuffer vertexBuffers[2];
428 
429     glBindVertexArray(vertexArray);
430 
431     std::vector<GLushort> indices = {// 4 squares each made up of 6 vertices:
432                                      // 1st square, in the upper-left part of window
433                                      0, 1, 2, 2, 3, 0,
434                                      // 2nd square, in the upper-right part of window
435                                      4, 5, 6, 6, 7, 4,
436                                      // 3rd square, in the lower-left part of window
437                                      8, 9, 10, 10, 11, 8,
438                                      // 4th square, in the lower-right part of window
439                                      12, 13, 14, 14, 15, 12};
440     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
441     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
442                  GL_STATIC_DRAW);
443 
444     std::vector<GLfloat> positionData = {// 4 squares each made up of quad vertices
445                                          // 1st square, in the upper-left part of window
446                                          -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
447                                          // 2nd square, in the upper-right part of window
448                                          0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
449                                          // 3rd square, in the lower-left part of window
450                                          -1.0f, 0.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f,
451                                          // 4th square, in the lower-right part of window
452                                          0.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f};
453 
454     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
455     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
456                  GL_STATIC_DRAW);
457     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
458     glEnableVertexAttribArray(positionLocation);
459 
460     std::vector<GLfloat> redGreenData = {// green(0,110), black(0,0), red(115,0), yellow(120,125)
461                                          // 4 squares each made up of 4 pairs of half-color values:
462                                          // 1st square, in the upper-left part of window
463                                          0.0f, 110.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 110.0f,
464                                          // 2nd square, in the upper-right part of window
465                                          0.0f, 125.0f, 0.0f, 0.0f, 120.0f, 0.0f, 120.0f, 125.0f,
466                                          // 3rd square, in the lower-left part of window
467                                          0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
468                                          // 4th square, in the lower-right part of window
469                                          0.0f, 0.0f, 0.0f, 0.0f, 115.0f, 0.0f, 115.0f, 0.0f};
470 
471     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
472     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],
473                  GL_STATIC_DRAW);
474     glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
475     glEnableVertexAttribArray(redGreenLocation);
476 
477     ASSERT_GL_NO_ERROR();
478 
479     // Draw and check the 4 corner pixels, to ensure we're getting the expected "colors"
480     glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);
481     GLColor expectedPixelLowerLeft(0, 0, 0, 255);
482     GLColor expectedPixelLowerRight(229, 0, 0, 255);
483     GLColor expectedPixelUpperLeft(0, 219, 0, 255);
484     GLColor expectedPixelUpperRight(239, 249, 0, 255);
485     EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixelLowerLeft);
486     EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, expectedPixelLowerRight);
487     EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, expectedPixelUpperLeft);
488     EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, expectedPixelUpperRight);
489     ASSERT_GL_NO_ERROR();
490 
491     // Make the image visible
492     eglSwapBuffers(mDisplay, mWindowSurface);
493     ASSERT_EGL_SUCCESS();
494 
495     // Draw again and check the 4 center pixels, to ensure we're getting the expected "colors"
496     glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);
497     EXPECT_PIXEL_COLOR_EQ((mSize / 2) - 1, (mSize / 2) - 1, expectedPixelLowerLeft);
498     EXPECT_PIXEL_COLOR_EQ((mSize / 2) - 1, (mSize / 2), expectedPixelUpperLeft);
499     EXPECT_PIXEL_COLOR_EQ((mSize / 2), (mSize / 2) - 1, expectedPixelLowerRight);
500     EXPECT_PIXEL_COLOR_EQ((mSize / 2), (mSize / 2), expectedPixelUpperRight);
501     ASSERT_GL_NO_ERROR();
502 }
503 
504 // Android-specific test that changes a window's rotation, which requires ContextVk::syncState() to
505 // handle the new rotation
TEST_P(EGLPreRotationSurfaceTest,ChangeRotationWithDraw)506 TEST_P(EGLPreRotationSurfaceTest, ChangeRotationWithDraw)
507 {
508     // This test uses functionality that is only available on Android
509     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
510 
511     // To aid in debugging, we want this window visible
512     setWindowVisible(mOSWindow, true);
513 
514     initializeDisplay();
515     initializeSurfaceWithRGBA8888Config();
516 
517     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
518     ASSERT_EGL_SUCCESS();
519 
520     // Init program
521     constexpr char kVS[] =
522         "attribute vec2 position;\n"
523         "attribute vec2 redGreen;\n"
524         "varying vec2 v_data;\n"
525         "void main() {\n"
526         "  gl_Position = vec4(position, 0, 1);\n"
527         "  v_data = redGreen;\n"
528         "}";
529 
530     constexpr char kFS[] =
531         "varying highp vec2 v_data;\n"
532         "void main() {\n"
533         "  gl_FragColor = vec4(v_data, 0, 1);\n"
534         "}";
535 
536     ANGLE_GL_PROGRAM(program, kVS, kFS);
537     glUseProgram(program);
538 
539     GLint positionLocation = glGetAttribLocation(program, "position");
540     ASSERT_NE(-1, positionLocation);
541 
542     GLint redGreenLocation = glGetAttribLocation(program, "redGreen");
543     ASSERT_NE(-1, redGreenLocation);
544 
545     GLBuffer indexBuffer;
546     GLVertexArray vertexArray;
547     GLBuffer vertexBuffers[2];
548 
549     glBindVertexArray(vertexArray);
550 
551     std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};
552     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
553     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
554                  GL_STATIC_DRAW);
555 
556     std::vector<GLfloat> positionData = {// quad vertices
557                                          -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
558 
559     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
560     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
561                  GL_STATIC_DRAW);
562     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
563     glEnableVertexAttribArray(positionLocation);
564 
565     std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)
566                                          0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};
567 
568     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
569     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],
570                  GL_STATIC_DRAW);
571     glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
572     glEnableVertexAttribArray(redGreenLocation);
573 
574     ASSERT_GL_NO_ERROR();
575 
576     // Change the rotation back and forth between landscape and portrait, and make sure that the
577     // drawing and reading happen consistently with the desired rotation.
578     // Last rotation needs to be portrait, since other tests expect it to be the default.
579     for (int i = 0; i < 4; i++)
580     {
581         bool landscape;
582         EGLint actualWidth   = 0;
583         EGLint actualHeight  = 0;
584         EGLint desiredWidth  = 0;
585         EGLint desiredHeight = 0;
586         if ((i % 2) == 0)
587         {
588             landscape     = true;
589             desiredWidth  = 300;
590             desiredHeight = 200;
591         }
592         else
593         {
594             landscape     = false;
595             desiredWidth  = 200;
596             desiredHeight = 300;
597         }
598         mOSWindow->resize(desiredWidth, desiredHeight);
599         // setOrientation() uses a reverse-JNI call, which sends data to other parts of Android.
600         // Sometime later (i.e. asynchronously), the window is updated.  Sleep a little here, and
601         // then allow for multiple eglSwapBuffers calls to eventually see the new rotation.
602         mOSWindow->setOrientation(desiredWidth, desiredHeight);
603         angle::Sleep(1000);
604         eglSwapBuffers(mDisplay, mWindowSurface);
605         ASSERT_EGL_SUCCESS();
606 
607         while ((actualWidth != desiredWidth) && (actualHeight != desiredHeight))
608         {
609             glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
610             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
611             if (landscape)
612             {
613                 EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);
614             }
615             else
616             {
617                 EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);
618             }
619             ASSERT_GL_NO_ERROR();
620 
621             eglSwapBuffers(mDisplay, mWindowSurface);
622             ASSERT_EGL_SUCCESS();
623 
624             eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &actualHeight);
625             eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &actualWidth);
626         }
627     }
628 }
629 
630 // A slight variation of EGLPreRotationSurfaceTest, where the initial window size is 400x300, yet
631 // the drawing is still 256x256.  In addition, gl_FragCoord is used in a "clever" way, as the color
632 // of the 256x256 drawing area, which reproduces an interesting pre-rotation case from the
633 // following dEQP tests:
634 //
635 // - dEQP.GLES31/functional_texture_multisample_samples_*_sample_position
636 //
637 // This will test the rotation of gl_FragCoord, as well as the viewport, scissor, and rendering
638 // area calculations, especially when the Android device is rotated.
639 class EGLPreRotationLargeSurfaceTest : public EGLPreRotationSurfaceTest
640 {
641   protected:
EGLPreRotationLargeSurfaceTest()642     EGLPreRotationLargeSurfaceTest() : mSize(256) {}
643 
testSetUp()644     void testSetUp() override
645     {
646         mOSWindow = OSWindow::New();
647         mOSWindow->initialize("EGLSurfaceTest", 400, 300);
648     }
649 
650     int mSize;
651 };
652 
653 // Provide a predictable pattern for testing pre-rotation
TEST_P(EGLPreRotationLargeSurfaceTest,OrientedWindowWithFragCoordDraw)654 TEST_P(EGLPreRotationLargeSurfaceTest, OrientedWindowWithFragCoordDraw)
655 {
656     // http://anglebug.com/42263074
657     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
658 
659     // Flaky on Linux SwANGLE http://anglebug.com/42263074
660     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
661 
662     // To aid in debugging, we want this window visible
663     setWindowVisible(mOSWindow, true);
664 
665     initializeDisplay();
666     initializeSurfaceWithRGBA8888Config();
667 
668     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
669     ASSERT_EGL_SUCCESS();
670 
671     // Init program
672     constexpr char kVS[] =
673         "attribute vec2 position;\n"
674         "void main() {\n"
675         "  gl_Position = vec4(position, 0, 1);\n"
676         "}";
677 
678     constexpr char kFS[] =
679         "void main() {\n"
680         "  gl_FragColor = vec4(gl_FragCoord.x / 256.0, gl_FragCoord.y / 256.0, 0.0, 1.0);\n"
681         "}";
682 
683     ANGLE_GL_PROGRAM(program, kVS, kFS);
684     glUseProgram(program);
685 
686     GLint positionLocation = glGetAttribLocation(program, "position");
687     ASSERT_NE(-1, positionLocation);
688 
689     GLBuffer indexBuffer;
690     GLVertexArray vertexArray;
691     GLBuffer vertexBuffer;
692 
693     glBindVertexArray(vertexArray);
694 
695     std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};
696     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
697     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
698                  GL_STATIC_DRAW);
699 
700     std::vector<GLfloat> positionData = {// quad vertices
701                                          -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
702 
703     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
704     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
705                  GL_STATIC_DRAW);
706     glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
707     glEnableVertexAttribArray(positionLocation);
708 
709     ASSERT_GL_NO_ERROR();
710 
711     glViewport(0, 0, mSize, mSize);
712 
713     testDrawingAndReadPixels();
714 }
715 
716 // Pre-rotation tests for glBlitFramebuffer.  A slight variation of EGLPreRotationLargeSurfaceTest,
717 // where the initial window size is still 400x300, and the drawing is still 256x256.  In addition,
718 // glBlitFramebuffer is tested in a variety of ways.  Separate tests are used to make debugging
719 // simpler, but they all share common setup.  These tests reproduce interesting pre-rotation cases
720 // from dEQP tests such as the following:
721 //
722 // - dEQP.GLES3/functional_fbo_blit_default_framebuffer_*
723 // - dEQP.GLES3/functional_fbo_invalidate_*
724 constexpr GLuint kCoordMidWayShort       = 127;
725 constexpr GLuint kCoordMidWayLong        = 128;
726 constexpr GLColor kColorMidWayShortShort = GLColor(127, 127, 0, 255);
727 constexpr GLColor kColorMidWayShortLong  = GLColor(127, 128, 0, 255);
728 constexpr GLColor kColorMidWayLongShort  = GLColor(128, 127, 0, 255);
729 constexpr GLColor kColorMidWayLongLong   = GLColor(128, 128, 0, 255);
730 // When scaling horizontally, the "black" and "green" colors have a 1 in the red component
731 constexpr GLColor kColorScaleHorizBlack = GLColor(1, 0, 0, 255);
732 constexpr GLColor kColorScaleHorizGreen = GLColor(1, 255, 0, 255);
733 // When scaling vertically, the "black" and "red" colors have a 1 in the green component
734 constexpr GLColor kColorScaleVertBlack = GLColor(0, 1, 0, 255);
735 constexpr GLColor kColorScaleVertRed   = GLColor(255, 1, 0, 255);
736 
737 class EGLPreRotationBlitFramebufferTest : public EGLPreRotationLargeSurfaceTest
738 {
739   protected:
EGLPreRotationBlitFramebufferTest()740     EGLPreRotationBlitFramebufferTest() {}
741 
createProgram()742     GLuint createProgram()
743     {
744         constexpr char kVS[] =
745             "attribute vec2 position;\n"
746             "attribute vec2 redGreen;\n"
747             "varying vec2 v_data;\n"
748             "void main() {\n"
749             "  gl_Position = vec4(position, 0, 1);\n"
750             "  v_data = redGreen;\n"
751             "}";
752 
753         constexpr char kFS[] =
754             "varying highp vec2 v_data;\n"
755             "void main() {\n"
756             "  gl_FragColor = vec4(v_data, 0, 1);\n"
757             "}";
758 
759         return CompileProgram(kVS, kFS);
760     }
761 
initializeGeometry(GLuint program,GLBuffer * indexBuffer,GLVertexArray * vertexArray,GLBuffer * vertexBuffers)762     void initializeGeometry(GLuint program,
763                             GLBuffer *indexBuffer,
764                             GLVertexArray *vertexArray,
765                             GLBuffer *vertexBuffers)
766     {
767         GLint positionLocation = glGetAttribLocation(program, "position");
768         ASSERT_NE(-1, positionLocation);
769 
770         GLint redGreenLocation = glGetAttribLocation(program, "redGreen");
771         ASSERT_NE(-1, redGreenLocation);
772 
773         glBindVertexArray(*vertexArray);
774 
775         std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};
776         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
777         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
778                      GL_STATIC_DRAW);
779 
780         std::vector<GLfloat> positionData = {// quad vertices
781                                              -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
782 
783         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
784         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
785                      GL_STATIC_DRAW);
786         glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,
787                               nullptr);
788         glEnableVertexAttribArray(positionLocation);
789 
790         std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)
791                                              0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};
792 
793         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
794         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],
795                      GL_STATIC_DRAW);
796         glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,
797                               nullptr);
798         glEnableVertexAttribArray(redGreenLocation);
799     }
800 
initializeFBO(GLFramebuffer * framebuffer,GLTexture * texture)801     void initializeFBO(GLFramebuffer *framebuffer, GLTexture *texture)
802     {
803         glBindTexture(GL_TEXTURE_2D, *texture);
804         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
805         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
806         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
807         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
808         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mSize, mSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
809                      nullptr);
810 
811         glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
812         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);
813     }
814 
815     // Ensures that the correct colors are where they should be when the entire 256x256 pattern has
816     // been rendered or blitted to a location relative to an x and y offset.
test256x256PredictablePattern(GLint xOffset,GLint yOffset)817     void test256x256PredictablePattern(GLint xOffset, GLint yOffset)
818     {
819         EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, GLColor::black);
820         EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, GLColor::green);
821         EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, GLColor::red);
822         EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);
823         EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + kCoordMidWayShort,
824                               kColorMidWayShortShort);
825         EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + kCoordMidWayLong,
826                               kColorMidWayShortLong);
827         EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + kCoordMidWayShort,
828                               kColorMidWayLongShort);
829         EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + kCoordMidWayLong,
830                               kColorMidWayLongLong);
831     }
832 };
833 
834 // Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer
835 // to blit that pattern into various places within the 400x300 window
TEST_P(EGLPreRotationBlitFramebufferTest,BasicBlitFramebuffer)836 TEST_P(EGLPreRotationBlitFramebufferTest, BasicBlitFramebuffer)
837 {
838     // http://anglebug.com/42263074
839     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
840 
841     // Flaky on Linux SwANGLE http://anglebug.com/42263074
842     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
843 
844     // To aid in debugging, we want this window visible
845     setWindowVisible(mOSWindow, true);
846 
847     initializeDisplay();
848     initializeSurfaceWithRGBA8888Config();
849 
850     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
851     ASSERT_EGL_SUCCESS();
852 
853     // Init program
854     GLuint program = createProgram();
855     ASSERT_NE(0u, program);
856     glUseProgram(program);
857 
858     GLBuffer indexBuffer;
859     GLVertexArray vertexArray;
860     GLBuffer vertexBuffers[2];
861     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
862     ASSERT_GL_NO_ERROR();
863 
864     // Create a texture-backed FBO and render the predictable pattern to it
865     GLFramebuffer fbo;
866     GLTexture texture;
867     initializeFBO(&fbo, &texture);
868     ASSERT_GL_NO_ERROR();
869 
870     glViewport(0, 0, mSize, mSize);
871     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
872     ASSERT_GL_NO_ERROR();
873 
874     // Ensure the predictable pattern seems correct in the FBO
875     test256x256PredictablePattern(0, 0);
876     ASSERT_GL_NO_ERROR();
877 
878     //
879     // Test blitting the entire FBO image to a 256x256 part of the default framebuffer (no scaling)
880     //
881 
882     // Blit from the FBO to the default framebuffer (i.e. the swapchain)
883     glBindFramebuffer(GL_FRAMEBUFFER, 0);
884     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
885     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
886     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
887     glClear(GL_COLOR_BUFFER_BIT);
888     glBlitFramebuffer(0, 0, mSize, mSize, 0, 0, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
889     ASSERT_GL_NO_ERROR();
890 
891     // Swap buffers to put the image in the window (so the test can be visually checked)
892     eglSwapBuffers(mDisplay, mWindowSurface);
893     ASSERT_GL_NO_ERROR();
894 
895     // Blit again to check the colors in the back buffer
896     glClear(GL_COLOR_BUFFER_BIT);
897     glBlitFramebuffer(0, 0, mSize, mSize, 0, 0, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
898     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
899     test256x256PredictablePattern(0, 0);
900     ASSERT_GL_NO_ERROR();
901 
902     // Clear to black and blit to a different part of the window
903     glClear(GL_COLOR_BUFFER_BIT);
904     GLint xOffset = 40;
905     GLint yOffset = 30;
906     glViewport(xOffset, yOffset, mSize, mSize);
907     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
908     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
909                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
910 
911     // Swap buffers to put the image in the window (so the test can be visually checked)
912     eglSwapBuffers(mDisplay, mWindowSurface);
913     ASSERT_GL_NO_ERROR();
914 
915     // Blit again to check the colors in the back buffer
916     glClear(GL_COLOR_BUFFER_BIT);
917     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
918                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
919     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
920     test256x256PredictablePattern(xOffset, yOffset);
921     ASSERT_GL_NO_ERROR();
922 
923     ASSERT_EGL_SUCCESS();
924 }
925 
926 // Blit the ms0 stencil buffer to the default framebuffer with rotation on android.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitStencilWithRotation)927 TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithRotation)
928 {
929     // http://anglebug.com/42263074
930     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
931 
932     // Flaky on Linux SwANGLE http://anglebug.com/42263074
933     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
934 
935     setWindowVisible(mOSWindow, true);
936 
937     initializeDisplay();
938     initializeSurfaceWithRGBA8888d24s8Config();
939 
940     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
941     ASSERT_EGL_SUCCESS();
942 
943     mOSWindow->setOrientation(300, 400);
944     angle::Sleep(1000);
945     eglSwapBuffers(mDisplay, mWindowSurface);
946     ASSERT_EGL_SUCCESS();
947 
948     GLRenderbuffer colorbuf;
949     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
950     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 64, 128);
951 
952     GLRenderbuffer depthstencilbuf;
953     glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());
954     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_DEPTH24_STENCIL8, 64, 128);
955 
956     GLFramebuffer framebuffer;
957     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
958     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
959     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
960                               depthstencilbuf);
961     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
962                               depthstencilbuf);
963     glCheckFramebufferStatus(GL_FRAMEBUFFER);
964 
965     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
966     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
967 
968     // Replace stencil to 1.
969     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
970     glEnable(GL_STENCIL_TEST);
971     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
972     glStencilFunc(GL_ALWAYS, 1, 255);
973     drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);
974 
975     // Blit stencil buffer to default frambuffer.
976     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
977     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
978     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
979     glBlitFramebuffer(0, 0, 64, 128, 0, 0, 64, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
980                       GL_NEAREST);
981     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
982 
983     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
984     glDisable(GL_STENCIL_TEST);
985     drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
986 
987     // Draw blue color if the stencil is equal to 1.
988     // If the blit finished successfully, the stencil test should all pass.
989     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
990     glEnable(GL_STENCIL_TEST);
991     glStencilFunc(GL_EQUAL, 1, 255);
992     drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f);
993 
994     // Check the result, especially the boundaries.
995     EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);
996     EXPECT_PIXEL_COLOR_EQ(32, 127, GLColor::blue);
997     EXPECT_PIXEL_COLOR_EQ(32, 0, GLColor::blue);
998     EXPECT_PIXEL_COLOR_EQ(63, 0, GLColor::blue);
999     EXPECT_PIXEL_COLOR_EQ(63, 64, GLColor::blue);
1000     EXPECT_PIXEL_COLOR_EQ(32, 64, GLColor::blue);
1001 
1002     // Some pixels around x=0/63 (related to the pre-rotation degree) still fail on android.
1003     // From the image in the window, the failures near one of the image's edge look like "aliasing".
1004     // We need to fix blit with pre-rotation. http://anglebug.com/42263612
1005     // EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1006     // EXPECT_PIXEL_COLOR_EQ(0, 64, GLColor::blue);
1007     // EXPECT_PIXEL_COLOR_EQ(63, 1, GLColor::blue);
1008     // EXPECT_PIXEL_COLOR_EQ(63, 127, GLColor::blue);
1009 
1010     eglSwapBuffers(mDisplay, mWindowSurface);
1011 
1012     ASSERT_GL_NO_ERROR();
1013 }
1014 
1015 // Blit the multisample stencil buffer to the default framebuffer with rotation on android.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitMultisampleStencilWithRotation)1016 TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleStencilWithRotation)
1017 {
1018     // http://anglebug.com/42263074
1019     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1020 
1021     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1022     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1023 
1024     setWindowVisible(mOSWindow, true);
1025 
1026     initializeDisplay();
1027     initializeSurfaceWithRGBA8888d24s8Config();
1028 
1029     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1030     ASSERT_EGL_SUCCESS();
1031 
1032     mOSWindow->setOrientation(300, 400);
1033     angle::Sleep(1000);
1034     eglSwapBuffers(mDisplay, mWindowSurface);
1035     ASSERT_EGL_SUCCESS();
1036 
1037     GLRenderbuffer colorbuf;
1038     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1039     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 64);
1040 
1041     GLRenderbuffer depthstencilbuf;
1042     glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());
1043     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 64);
1044 
1045     GLFramebuffer framebuffer;
1046     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1047     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1048     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1049                               depthstencilbuf);
1050     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1051                               depthstencilbuf);
1052     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1053 
1054     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1055     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1056 
1057     // Replace stencil to 1.
1058     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1059     glEnable(GL_STENCIL_TEST);
1060     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1061     glStencilFunc(GL_ALWAYS, 1, 255);
1062     drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);
1063 
1064     // Blit multisample stencil buffer to default frambuffer.
1065     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
1066     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
1067     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1068     glBlitFramebuffer(0, 0, 128, 64, 0, 0, 128, 64, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1069                       GL_NEAREST);
1070     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1071 
1072     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1073     glDisable(GL_STENCIL_TEST);
1074     drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
1075 
1076     // Draw blue color if the stencil is equal to 1.
1077     // If the blit finished successfully, the stencil test should all pass.
1078     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1079     glEnable(GL_STENCIL_TEST);
1080     glStencilFunc(GL_EQUAL, 1, 255);
1081     drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f);
1082 
1083     // Check the result, especially the boundaries.
1084     EXPECT_PIXEL_COLOR_EQ(127, 32, GLColor::blue);
1085     EXPECT_PIXEL_COLOR_EQ(64, 32, GLColor::blue);
1086     EXPECT_PIXEL_COLOR_EQ(0, 63, GLColor::blue);
1087     EXPECT_PIXEL_COLOR_EQ(64, 63, GLColor::blue);
1088 
1089     // Some pixels around x=0/127 or y=0 (related to the pre-rotation degree)still fail on android.
1090     // We need to fix blit with pre-rotation. http://anglebug.com/42263612
1091     // Failures of Rotated90Degrees.
1092     // EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
1093     // EXPECT_PIXEL_COLOR_EQ(127, 63, GLColor::blue);
1094     // Failures of Rotated180Degrees.
1095     // EXPECT_PIXEL_COLOR_EQ(64, 0, GLColor::blue);
1096     // EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
1097     // Failures of Rotated270Degrees.
1098     // EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1099     // EXPECT_PIXEL_COLOR_EQ(0, 32, GLColor::blue);
1100 
1101     eglSwapBuffers(mDisplay, mWindowSurface);
1102 
1103     ASSERT_GL_NO_ERROR();
1104 }
1105 
1106 // Blit stencil to default framebuffer with flip and prerotation.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitStencilWithFlip)1107 TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithFlip)
1108 {
1109     // http://anglebug.com/42263074
1110     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1111 
1112     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1113     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1114 
1115     // We need to fix blit with pre-rotation. http://anglebug.com/42263612
1116     ANGLE_SKIP_TEST_IF(IsPixel4() || IsPixel4XL() || IsWindows());
1117 
1118     // To aid in debugging, we want this window visible
1119     setWindowVisible(mOSWindow, true);
1120 
1121     initializeDisplay();
1122     initializeSurfaceWithRGBA8888d24s8Config();
1123 
1124     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1125     ASSERT_EGL_SUCCESS();
1126 
1127     mOSWindow->setOrientation(300, 400);
1128     angle::Sleep(1000);
1129     eglSwapBuffers(mDisplay, mWindowSurface);
1130     ASSERT_EGL_SUCCESS();
1131 
1132     constexpr int kSize = 128;
1133     glViewport(0, 0, kSize, kSize);
1134 
1135     GLRenderbuffer colorbuf;
1136     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1137     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);
1138 
1139     GLRenderbuffer depthstencilbuf;
1140     glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());
1141     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_DEPTH24_STENCIL8, kSize, kSize);
1142 
1143     GLFramebuffer framebuffer;
1144     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1145     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1146     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1147                               depthstencilbuf);
1148     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1149                               depthstencilbuf);
1150     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1151 
1152     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1153     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1154 
1155     // Replace stencil to 1.
1156     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1157     glEnable(GL_STENCIL_TEST);
1158     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1159     glStencilFunc(GL_ALWAYS, 1, 255);
1160     drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);
1161 
1162     // Blit stencil buffer to default frambuffer with X-flip.
1163     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
1164     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
1165     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1166     glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize,
1167                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1168     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1169 
1170     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1171     glDisable(GL_STENCIL_TEST);
1172     drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
1173 
1174     // Draw blue color if the stencil is equal to 1.
1175     // If the blit finished successfully, the stencil test should all pass.
1176     glEnable(GL_STENCIL_TEST);
1177     glStencilFunc(GL_EQUAL, 1, 255);
1178     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1179                      essl31_shaders::fs::RedGreenGradient());
1180     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1181 
1182     // Check the result, especially the boundaries.
1183     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);                      // Black
1184     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0);            // Red
1185     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0);            // Green
1186     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0);  // Yellow
1187 
1188     eglSwapBuffers(mDisplay, mWindowSurface);
1189 
1190     ASSERT_GL_NO_ERROR();
1191 }
1192 
1193 // Blit color buffer to default framebuffer with Y-flip/X-flip.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitColorToDefault)1194 TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorToDefault)
1195 {
1196     // This test uses functionality that is only available on Android
1197     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
1198 
1199     // To aid in debugging, we want this window visible
1200     setWindowVisible(mOSWindow, true);
1201 
1202     initializeDisplay();
1203     initializeSurfaceWithRGBA8888Config();
1204 
1205     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1206     ASSERT_EGL_SUCCESS();
1207 
1208     constexpr int kSize = 128;
1209     glViewport(0, 0, kSize, kSize);
1210 
1211     GLRenderbuffer colorbuf;
1212     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1213     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);
1214 
1215     GLFramebuffer framebuffer;
1216     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1217     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1218 
1219     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1220 
1221     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1222     glClear(GL_COLOR_BUFFER_BIT);
1223 
1224     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1225                      essl31_shaders::fs::RedGreenGradient());
1226 
1227     EGLint desiredWidth  = 300;
1228     EGLint desiredHeight = 400;
1229     mOSWindow->resize(desiredWidth, desiredHeight);
1230     mOSWindow->setOrientation(desiredWidth, desiredHeight);
1231     angle::Sleep(1000);
1232     eglSwapBuffers(mDisplay, mWindowSurface);
1233     ASSERT_EGL_SUCCESS();
1234 
1235     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
1236     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1237 
1238     // Blit color buffer to default frambuffer without flip.
1239     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1240     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1241     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1242 
1243     // Check the result, especially the boundaries.
1244     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);                      // Balck
1245     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0);            // Red
1246     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0);            // Green
1247     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0);  // Yellow
1248 
1249     // Blit color buffer to default frambuffer with Y-flip.
1250     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1251     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1252     glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1253     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1254 
1255     EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0);                  // Green
1256     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0);        // Yellow
1257     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0);            // Balck
1258     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0);  // Red
1259 
1260     // Blit color buffer to default frambuffer with X-flip.
1261     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1262     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1263     glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1264     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1265 
1266     EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0);                  // Red
1267     EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0);            // Balck
1268     EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0);        // Yellow
1269     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0);  // Green
1270 
1271     ASSERT_GL_NO_ERROR();
1272 }
1273 
1274 // Blit color buffer from default framebuffer with Y-flip/X-flip.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitColorFromDefault)1275 TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorFromDefault)
1276 {
1277     // This test uses functionality that is only available on Android
1278     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
1279 
1280     // To aid in debugging, we want this window visible
1281     setWindowVisible(mOSWindow, true);
1282 
1283     initializeDisplay();
1284     initializeSurfaceWithRGBA8888Config();
1285 
1286     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1287     ASSERT_EGL_SUCCESS();
1288 
1289     constexpr int kSize = 128;
1290     glViewport(0, 0, kSize, kSize);
1291 
1292     GLRenderbuffer colorbuf;
1293     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1294     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);
1295 
1296     GLFramebuffer framebuffer;
1297     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1298     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1299     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1300 
1301     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1302     glClear(GL_COLOR_BUFFER_BIT);
1303 
1304     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1305                      essl31_shaders::fs::RedGreenGradient());
1306 
1307     EGLint desiredWidth  = 300;
1308     EGLint desiredHeight = 400;
1309     mOSWindow->resize(desiredWidth, desiredHeight);
1310     mOSWindow->setOrientation(desiredWidth, desiredHeight);
1311     angle::Sleep(1000);
1312     eglSwapBuffers(mDisplay, mWindowSurface);
1313     ASSERT_EGL_SUCCESS();
1314 
1315     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1316     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1317 
1318     // Blit color buffer from default frambuffer without flip.
1319     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
1320     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1321     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1322 
1323     // Check the result, especially the boundaries.
1324     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);                      // Balck
1325     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0);            // Red
1326     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0);            // Green
1327     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0);  // Yellow
1328 
1329     // Blit color buffer from default frambuffer with Y-flip.
1330     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1331     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
1332     glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1333     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1334 
1335     EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0);                  // Green
1336     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0);        // Yellow
1337     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0);            // Balck
1338     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0);  // Red
1339 
1340     // Blit color buffer from default frambuffer with X-flip.
1341     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1342     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
1343     glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1344     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1345 
1346     EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0);                  // Red
1347     EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0);            // Balck
1348     EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0);        // Yellow
1349     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0);  // Green
1350 
1351     ASSERT_GL_NO_ERROR();
1352 }
1353 
1354 // Blit multisample color buffer to resolved framebuffer.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitMultisampleColorToResolved)1355 TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleColorToResolved)
1356 {
1357     // This test uses functionality that is only available on Android
1358     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
1359 
1360     // To aid in debugging, we want this window visible
1361     setWindowVisible(mOSWindow, true);
1362 
1363     initializeDisplay();
1364     initializeSurfaceWithRGBA8888Config();
1365 
1366     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1367     ASSERT_EGL_SUCCESS();
1368 
1369     constexpr int kSize = 128;
1370     glViewport(0, 0, kSize, kSize);
1371 
1372     GLRenderbuffer colorMS;
1373     glBindRenderbuffer(GL_RENDERBUFFER, colorMS.get());
1374     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize, kSize);
1375 
1376     GLRenderbuffer colorResolved;
1377     glBindRenderbuffer(GL_RENDERBUFFER, colorResolved.get());
1378     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
1379 
1380     GLFramebuffer framebufferMS;
1381     glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS.get());
1382     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
1383 
1384     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1385 
1386     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1387     glClear(GL_COLOR_BUFFER_BIT);
1388 
1389     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1390                      essl31_shaders::fs::RedGreenGradient());
1391     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1392 
1393     GLFramebuffer framebufferResolved;
1394     glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());
1395     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1396                               colorResolved.get());
1397 
1398     EGLint desiredWidth  = 300;
1399     EGLint desiredHeight = 400;
1400     mOSWindow->resize(desiredWidth, desiredHeight);
1401     mOSWindow->setOrientation(desiredWidth, desiredHeight);
1402     angle::Sleep(1000);
1403     eglSwapBuffers(mDisplay, mWindowSurface);
1404     ASSERT_EGL_SUCCESS();
1405 
1406     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferMS.get());
1407     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1408 
1409     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS.get());
1410     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferResolved.get());
1411     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1412     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferResolved.get());
1413 
1414     // Check the result, especially the boundaries.
1415     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);                      // Balck
1416     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0);            // Red
1417     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0);            // Green
1418     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0);  // Yellow
1419 
1420     ASSERT_GL_NO_ERROR();
1421 }
1422 
1423 // Blit color buffer to default framebuffer with linear filter.
TEST_P(EGLPreRotationBlitFramebufferTest,BlitColorWithLinearFilter)1424 TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithLinearFilter)
1425 {
1426     // http://anglebug.com/42263074
1427     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1428 
1429     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1430     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1431 
1432     setWindowVisible(mOSWindow, true);
1433 
1434     initializeDisplay();
1435     initializeSurfaceWithRGBA8888Config();
1436 
1437     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1438     ASSERT_EGL_SUCCESS();
1439 
1440     mOSWindow->setOrientation(300, 400);
1441     angle::Sleep(1000);
1442     eglSwapBuffers(mDisplay, mWindowSurface);
1443     ASSERT_EGL_SUCCESS();
1444 
1445     constexpr int kSize = 128;
1446     glViewport(0, 0, kSize, kSize);
1447 
1448     GLRenderbuffer colorbuf;
1449     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1450     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);
1451 
1452     GLFramebuffer framebuffer;
1453     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1454     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1455 
1456     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1457 
1458     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1459     glClear(GL_COLOR_BUFFER_BIT);
1460 
1461     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1462                      essl31_shaders::fs::RedGreenGradient());
1463     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1464 
1465     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1466     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);
1467     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1468 
1469     // Check the result, especially the boundaries.
1470     EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);                      // Black
1471     EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0);            // Red
1472     EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0);            // Green
1473     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0);  // Yellow
1474 
1475     eglSwapBuffers(mDisplay, mWindowSurface);
1476 
1477     ASSERT_GL_NO_ERROR();
1478 }
1479 
1480 // Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer
1481 // to blit the left and right halves of that pattern into various places within the 400x300 window
TEST_P(EGLPreRotationBlitFramebufferTest,LeftAndRightBlitFramebuffer)1482 TEST_P(EGLPreRotationBlitFramebufferTest, LeftAndRightBlitFramebuffer)
1483 {
1484     // http://anglebug.com/42263074
1485     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1486 
1487     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1488     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1489 
1490     // To aid in debugging, we want this window visible
1491     setWindowVisible(mOSWindow, true);
1492 
1493     initializeDisplay();
1494     initializeSurfaceWithRGBA8888Config();
1495 
1496     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1497     ASSERT_EGL_SUCCESS();
1498 
1499     // Init program
1500     GLuint program = createProgram();
1501     ASSERT_NE(0u, program);
1502     glUseProgram(program);
1503 
1504     GLBuffer indexBuffer;
1505     GLVertexArray vertexArray;
1506     GLBuffer vertexBuffers[2];
1507     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
1508     ASSERT_GL_NO_ERROR();
1509 
1510     // Create a texture-backed FBO and render the predictable pattern to it
1511     GLFramebuffer fbo;
1512     GLTexture texture;
1513     initializeFBO(&fbo, &texture);
1514     ASSERT_GL_NO_ERROR();
1515 
1516     glViewport(0, 0, mSize, mSize);
1517     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1518     ASSERT_GL_NO_ERROR();
1519 
1520     // Ensure the predictable pattern seems correct in the FBO
1521     test256x256PredictablePattern(0, 0);
1522     ASSERT_GL_NO_ERROR();
1523 
1524     // Prepare to blit to the default framebuffer and read from the FBO
1525     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1526     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1527     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1528     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1529 
1530     // Blit to an offset part of the 400x300 window
1531     GLint xOffset = 40;
1532     GLint yOffset = 30;
1533 
1534     //
1535     // Test blitting half of the FBO image to a 128x256 or 256x128 part of the default framebuffer
1536     // (no scaling)
1537     //
1538 
1539     // 1st) Clear to black and blit the left and right halves of the texture to the left and right
1540     // halves of that different part of the window
1541     glClear(GL_COLOR_BUFFER_BIT);
1542     glViewport(xOffset, yOffset, mSize, mSize);
1543     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1544     glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset, yOffset, xOffset + (mSize / 2),
1545                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1546     glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1547                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1548 
1549     // Swap buffers to put the image in the window (so the test can be visually checked)
1550     eglSwapBuffers(mDisplay, mWindowSurface);
1551     ASSERT_GL_NO_ERROR();
1552 
1553     // Blit again to check the colors in the back buffer
1554     glClear(GL_COLOR_BUFFER_BIT);
1555     glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset, yOffset, xOffset + (mSize / 2),
1556                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1557     glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1558                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1559     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1560     test256x256PredictablePattern(xOffset, yOffset);
1561     ASSERT_GL_NO_ERROR();
1562 
1563     // 2nd) Clear to black and this time blit the left half of the source texture to the right half
1564     // of the destination window, and then blit the right half of the source texture to the left
1565     // half of the destination window
1566     glClear(GL_COLOR_BUFFER_BIT);
1567     glViewport(xOffset, yOffset, mSize, mSize);
1568     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1569     glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2),
1570                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1571     glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1572                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1573 
1574     // Swap buffers to put the image in the window (so the test can be visually checked)
1575     eglSwapBuffers(mDisplay, mWindowSurface);
1576     ASSERT_GL_NO_ERROR();
1577 
1578     // Blit again to check the colors in the back buffer
1579     glClear(GL_COLOR_BUFFER_BIT);
1580     glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2),
1581                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1582     glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1583                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1584     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1585     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort + 1, yOffset + 0, GLColor::black);
1586     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort + 1, yOffset + mSize - 1, GLColor::green);
1587     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, GLColor::red);
1588     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, GLColor::yellow);
1589     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, kColorMidWayShortShort);
1590     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayLong, kColorMidWayShortLong);
1591     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, kColorMidWayLongShort);
1592     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayLong, kColorMidWayLongLong);
1593     ASSERT_GL_NO_ERROR();
1594 
1595     ASSERT_EGL_SUCCESS();
1596 }
1597 
1598 // Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer
1599 // to blit the top and bottom halves of that pattern into various places within the 400x300 window
TEST_P(EGLPreRotationBlitFramebufferTest,TopAndBottomBlitFramebuffer)1600 TEST_P(EGLPreRotationBlitFramebufferTest, TopAndBottomBlitFramebuffer)
1601 {
1602     // http://anglebug.com/42263074
1603     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1604 
1605     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1606     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1607 
1608     // To aid in debugging, we want this window visible
1609     setWindowVisible(mOSWindow, true);
1610 
1611     initializeDisplay();
1612     initializeSurfaceWithRGBA8888Config();
1613 
1614     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1615     ASSERT_EGL_SUCCESS();
1616 
1617     // Init program
1618     GLuint program = createProgram();
1619     ASSERT_NE(0u, program);
1620     glUseProgram(program);
1621 
1622     GLBuffer indexBuffer;
1623     GLVertexArray vertexArray;
1624     GLBuffer vertexBuffers[2];
1625     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
1626     ASSERT_GL_NO_ERROR();
1627 
1628     // Create a texture-backed FBO and render the predictable pattern to it
1629     GLFramebuffer fbo;
1630     GLTexture texture;
1631     initializeFBO(&fbo, &texture);
1632     ASSERT_GL_NO_ERROR();
1633 
1634     glViewport(0, 0, mSize, mSize);
1635     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1636     ASSERT_GL_NO_ERROR();
1637 
1638     // Ensure the predictable pattern seems correct in the FBO
1639     test256x256PredictablePattern(0, 0);
1640     ASSERT_GL_NO_ERROR();
1641 
1642     // Prepare to blit to the default framebuffer and read from the FBO
1643     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1644     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1645     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1646     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1647 
1648     // Blit to an offset part of the 400x300 window
1649     GLint xOffset = 40;
1650     GLint yOffset = 30;
1651 
1652     //
1653     // Test blitting half of the FBO image to a 128x256 or 256x128 part of the default framebuffer
1654     // (no scaling)
1655     //
1656 
1657     // 1st) Clear to black and blit the top and bottom halves of the texture to the top and bottom
1658     // halves of that different part of the window
1659     glClear(GL_COLOR_BUFFER_BIT);
1660     glViewport(xOffset, yOffset, mSize, mSize);
1661     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1662     glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset, xOffset + mSize,
1663                       yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1664     glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1665                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1666 
1667     // Swap buffers to put the image in the window (so the test can be visually checked)
1668     eglSwapBuffers(mDisplay, mWindowSurface);
1669     ASSERT_GL_NO_ERROR();
1670 
1671     // Blit again to check the colors in the back buffer
1672     glClear(GL_COLOR_BUFFER_BIT);
1673     glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset, xOffset + mSize,
1674                       yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1675     glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1676                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1677     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1678     test256x256PredictablePattern(xOffset, yOffset);
1679     ASSERT_GL_NO_ERROR();
1680 
1681     // 2nd) Clear to black and this time blit the top half of the source texture to the bottom half
1682     // of the destination window, and then blit the bottom half of the source texture to the top
1683     // half of the destination window
1684     glClear(GL_COLOR_BUFFER_BIT);
1685     glViewport(xOffset, yOffset, mSize, mSize);
1686     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1687     glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1688                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1689     glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset, xOffset + mSize,
1690                       yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1691 
1692     // Swap buffers to put the image in the window (so the test can be visually checked)
1693     eglSwapBuffers(mDisplay, mWindowSurface);
1694     ASSERT_GL_NO_ERROR();
1695 
1696     // Blit again to check the colors in the back buffer
1697     glClear(GL_COLOR_BUFFER_BIT);
1698     glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1699                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1700     glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset, xOffset + mSize,
1701                       yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1702     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1703     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort + 1, GLColor::black);
1704     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, GLColor::green);
1705     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort + 1, GLColor::red);
1706     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, GLColor::yellow);
1707     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, kColorMidWayShortShort);
1708     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, kColorMidWayShortLong);
1709     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + mSize - 1, kColorMidWayLongShort);
1710     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + 0, kColorMidWayLongLong);
1711     ASSERT_GL_NO_ERROR();
1712 
1713     ASSERT_EGL_SUCCESS();
1714 }
1715 
1716 // Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer
1717 // to blit that pattern into various places within the 400x300 window, but being scaled to one-half
1718 // size
TEST_P(EGLPreRotationBlitFramebufferTest,ScaledBlitFramebuffer)1719 TEST_P(EGLPreRotationBlitFramebufferTest, ScaledBlitFramebuffer)
1720 {
1721     // http://anglebug.com/42263074
1722     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1723 
1724     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1725     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1726 
1727     // To aid in debugging, we want this window visible
1728     setWindowVisible(mOSWindow, true);
1729 
1730     initializeDisplay();
1731     initializeSurfaceWithRGBA8888Config();
1732 
1733     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1734     ASSERT_EGL_SUCCESS();
1735 
1736     // Init program
1737     GLuint program = createProgram();
1738     ASSERT_NE(0u, program);
1739     glUseProgram(program);
1740 
1741     GLBuffer indexBuffer;
1742     GLVertexArray vertexArray;
1743     GLBuffer vertexBuffers[2];
1744     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
1745     ASSERT_GL_NO_ERROR();
1746 
1747     // Create a texture-backed FBO and render the predictable pattern to it
1748     GLFramebuffer fbo;
1749     GLTexture texture;
1750     initializeFBO(&fbo, &texture);
1751     ASSERT_GL_NO_ERROR();
1752 
1753     glViewport(0, 0, mSize, mSize);
1754     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1755     ASSERT_GL_NO_ERROR();
1756 
1757     // Ensure the predictable pattern seems correct in the FBO
1758     test256x256PredictablePattern(0, 0);
1759     ASSERT_GL_NO_ERROR();
1760 
1761     // Prepare to blit to the default framebuffer and read from the FBO
1762     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1763     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1764     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1765     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1766 
1767     // Blit to an offset part of the 400x300 window
1768     GLint xOffset = 40;
1769     GLint yOffset = 30;
1770 
1771     //
1772     // Test blitting the entire FBO image to a 128x256 or 256x128 part of the default framebuffer
1773     // (requires scaling)
1774     //
1775 
1776     // 1st) Clear to black and blit the FBO to the left and right halves of that different part of
1777     // the window
1778     glClear(GL_COLOR_BUFFER_BIT);
1779     glViewport(xOffset, yOffset, mSize, mSize);
1780     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1781     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2), yOffset + mSize,
1782                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1783     glBlitFramebuffer(0, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1784                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1785 
1786     // Swap buffers to put the image in the window (so the test can be visually checked)
1787     eglSwapBuffers(mDisplay, mWindowSurface);
1788     ASSERT_GL_NO_ERROR();
1789 
1790     // Blit again to check the colors in the back buffer
1791     glClear(GL_COLOR_BUFFER_BIT);
1792     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2), yOffset + mSize,
1793                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1794     glBlitFramebuffer(0, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,
1795                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1796     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1797     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, kColorScaleHorizBlack);
1798     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, kColorScaleHorizGreen);
1799     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, GLColor::red);
1800     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, GLColor::yellow);
1801     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + 0, kColorScaleHorizBlack);
1802     EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + mSize - 1, kColorScaleHorizGreen);
1803     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, GLColor::red);
1804     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);
1805 
1806     // 2nd) Clear to black and blit the FBO to the top and bottom halves of that different part of
1807     // the window
1808     glClear(GL_COLOR_BUFFER_BIT);
1809     glViewport(xOffset, yOffset, mSize, mSize);
1810     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1811     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + (mSize / 2),
1812                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1813     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1814                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1815 
1816     // Swap buffers to put the image in the window (so the test can be visually checked)
1817     eglSwapBuffers(mDisplay, mWindowSurface);
1818     ASSERT_GL_NO_ERROR();
1819 
1820     // Blit again to check the colors in the back buffer
1821     glClear(GL_COLOR_BUFFER_BIT);
1822     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + (mSize / 2),
1823                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1824     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,
1825                       yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1826     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1827     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, kColorScaleVertBlack);
1828     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, kColorScaleVertRed);
1829     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, GLColor::green);
1830     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, GLColor::yellow);
1831     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayLong, kColorScaleVertBlack);
1832     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayLong, kColorScaleVertRed);
1833     EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, GLColor::green);
1834     EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);
1835     ASSERT_GL_NO_ERROR();
1836 
1837     ASSERT_EGL_SUCCESS();
1838 }
1839 
1840 // Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x300
1841 // window, and then use glBlitFramebuffer to blit that pattern into an FBO
TEST_P(EGLPreRotationBlitFramebufferTest,FboDestBlitFramebuffer)1842 TEST_P(EGLPreRotationBlitFramebufferTest, FboDestBlitFramebuffer)
1843 {
1844     // http://anglebug.com/42263074
1845     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1846 
1847     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1848     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1849 
1850     // To aid in debugging, we want this window visible
1851     setWindowVisible(mOSWindow, true);
1852 
1853     initializeDisplay();
1854     initializeSurfaceWithRGBA8888Config();
1855 
1856     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1857     ASSERT_EGL_SUCCESS();
1858 
1859     // Init program
1860     GLuint program = createProgram();
1861     ASSERT_NE(0u, program);
1862     glUseProgram(program);
1863 
1864     GLBuffer indexBuffer;
1865     GLVertexArray vertexArray;
1866     GLBuffer vertexBuffers[2];
1867     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
1868     ASSERT_GL_NO_ERROR();
1869 
1870     // Create a texture-backed FBO and render the predictable pattern to it
1871     GLFramebuffer fbo;
1872     GLTexture texture;
1873     initializeFBO(&fbo, &texture);
1874     ASSERT_GL_NO_ERROR();
1875 
1876     glViewport(0, 0, mSize, mSize);
1877     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1878     ASSERT_GL_NO_ERROR();
1879 
1880     // Ensure the predictable pattern seems correct in the FBO
1881     test256x256PredictablePattern(0, 0);
1882     ASSERT_GL_NO_ERROR();
1883 
1884     // Prepare to blit to the default framebuffer and read from the FBO
1885     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1886     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1887     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1888     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1889 
1890     // Blit to an offset part of the 400x300 window
1891     GLint xOffset = 40;
1892     GLint yOffset = 30;
1893 
1894     //
1895     // Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)
1896     //
1897 
1898     // To get the entire predictable pattern into the default framebuffer at the desired offset,
1899     // blit it from the FBO
1900     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1901     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1902     glViewport(xOffset, yOffset, mSize, mSize);
1903     glClear(GL_COLOR_BUFFER_BIT);
1904     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
1905                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1906     // Swap buffers to put the image in the window (so the test can be visually checked)
1907     eglSwapBuffers(mDisplay, mWindowSurface);
1908     ASSERT_GL_NO_ERROR();
1909     // Blit again to check the colors in the back buffer
1910     glClear(GL_COLOR_BUFFER_BIT);
1911     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
1912                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1913 
1914     // Clear the FBO to black and blit from the window to the FBO
1915     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1916     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
1917     glViewport(0, 0, mSize, mSize);
1918     glClear(GL_COLOR_BUFFER_BIT);
1919     glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize, mSize,
1920                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1921 
1922     // Ensure the predictable pattern seems correct in the FBO
1923     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1924     test256x256PredictablePattern(0, 0);
1925     ASSERT_GL_NO_ERROR();
1926 
1927     ASSERT_EGL_SUCCESS();
1928 }
1929 
1930 // Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x300
1931 // window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with coordinates
1932 // that are partially out-of-bounds of the source
TEST_P(EGLPreRotationBlitFramebufferTest,FboDestOutOfBoundsSourceBlitFramebuffer)1933 TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceBlitFramebuffer)
1934 {
1935     // http://anglebug.com/42263074
1936     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1937 
1938     // Flaky on Linux SwANGLE http://anglebug.com/42263074
1939     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1940 
1941     // To aid in debugging, we want this window visible
1942     setWindowVisible(mOSWindow, true);
1943 
1944     initializeDisplay();
1945     initializeSurfaceWithRGBA8888Config();
1946 
1947     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1948     ASSERT_EGL_SUCCESS();
1949 
1950     // Init program
1951     GLuint program = createProgram();
1952     ASSERT_NE(0u, program);
1953     glUseProgram(program);
1954 
1955     GLBuffer indexBuffer;
1956     GLVertexArray vertexArray;
1957     GLBuffer vertexBuffers[2];
1958     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
1959     ASSERT_GL_NO_ERROR();
1960 
1961     // Create a texture-backed FBO and render the predictable pattern to it
1962     GLFramebuffer fbo;
1963     GLTexture texture;
1964     initializeFBO(&fbo, &texture);
1965     ASSERT_GL_NO_ERROR();
1966 
1967     glViewport(0, 0, mSize, mSize);
1968     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
1969     ASSERT_GL_NO_ERROR();
1970 
1971     // Ensure the predictable pattern seems correct in the FBO
1972     test256x256PredictablePattern(0, 0);
1973     ASSERT_GL_NO_ERROR();
1974 
1975     // Prepare to blit to the default framebuffer and read from the FBO
1976     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1977     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1978     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1979     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1980 
1981     // Blit to the origin of the 400x300 window
1982     GLint xOffset = 0;
1983     GLint yOffset = 0;
1984 
1985     //
1986     // Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)
1987     //
1988 
1989     // To get the entire predictable pattern into the default framebuffer at the desired offset,
1990     // blit it from the FBO
1991     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
1992     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1993     glViewport(xOffset, yOffset, mSize, mSize);
1994     glClear(GL_COLOR_BUFFER_BIT);
1995     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
1996                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
1997     // Swap buffers to put the image in the window (so the test can be visually checked)
1998     eglSwapBuffers(mDisplay, mWindowSurface);
1999     ASSERT_GL_NO_ERROR();
2000     // Blit again to check the colors in the back buffer
2001     glClear(GL_COLOR_BUFFER_BIT);
2002     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
2003                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2004 
2005     // Clear the FBO to black and blit from the window to the FBO, but give source coordinates that
2006     // are partially outside of the window
2007     xOffset = -10;
2008     yOffset = -15;
2009     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
2010     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2011     glViewport(0, 0, mSize, mSize);
2012     glClear(GL_COLOR_BUFFER_BIT);
2013     glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize, mSize,
2014                       GL_COLOR_BUFFER_BIT, GL_LINEAR);
2015 
2016     // Ensure the predictable pattern seems correct in the FBO
2017     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2018     // NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to
2019     // the source coordinates that were outside of the source.  The strip of black is xOffset
2020     // pixels wide on the left side, and yOffset pixels tall on the bottom side.
2021     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2022     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::black);
2023     EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 0, GLColor::black);
2024     EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 255, GLColor::black);
2025     EXPECT_PIXEL_COLOR_EQ(0, -yOffset - 1, GLColor::black);
2026     EXPECT_PIXEL_COLOR_EQ(255, -yOffset - 1, GLColor::black);
2027     EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 0, GLColor::black);
2028     EXPECT_PIXEL_COLOR_EQ(255 + xOffset, -yOffset - 1, GLColor::black);
2029     EXPECT_PIXEL_COLOR_EQ(0, 255 + yOffset, GLColor::black);
2030     EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 255 + yOffset, GLColor::black);
2031 
2032     // FBO coordinate (-xOffset, -yOffset) (or (10, 15)) has the values from the bottom-left corner
2033     // of the source (which happens to be black).  Thus, the following two tests are equivalent:
2034     EXPECT_PIXEL_COLOR_EQ(-xOffset, -yOffset, GLColor::black);
2035     EXPECT_PIXEL_COLOR_EQ(10, 15, GLColor::black);
2036 
2037     // Note: the following is equivalent to (0, 0):
2038     EXPECT_PIXEL_COLOR_EQ(10 + xOffset, 15 + yOffset, GLColor::black);
2039 
2040     EXPECT_PIXEL_COLOR_EQ(-xOffset + 1, -yOffset + 1, GLColor(1, 1, 0, 255));
2041     EXPECT_PIXEL_COLOR_EQ(-xOffset + 10, -yOffset + 10, GLColor(10, 10, 0, 255));
2042     EXPECT_PIXEL_COLOR_EQ(-xOffset + 20, -yOffset + 20, GLColor(20, 20, 0, 255));
2043     EXPECT_PIXEL_COLOR_EQ(-xOffset + 100, -yOffset + 100, GLColor(100, 100, 0, 255));
2044     EXPECT_PIXEL_COLOR_EQ(-xOffset + 200, -yOffset + 200, GLColor(200, 200, 0, 255));
2045     EXPECT_PIXEL_COLOR_EQ(-xOffset + 230, -yOffset + 230, GLColor(230, 230, 0, 255));
2046     // Note how the offset works differently when added to the same coordinate value as above.  The
2047     // black strip causes the value to be 2X less the offset in each direction.  Thus, coordinate
2048     // (230+xOffset, 230+yOffset) yields actual coordinate (220, 215) and red-green values
2049     // (230+(2*xOffset), 230+(2*yOffset)) or (210, 200).  The following two tests are equivalent:
2050     EXPECT_PIXEL_COLOR_EQ(230 + xOffset, 230 + yOffset,
2051                           GLColor(230 + (2 * xOffset), 230 + (2 * yOffset), 0, 255));
2052     EXPECT_PIXEL_COLOR_EQ(220, 215, GLColor(210, 200, 0, 255));
2053     // FBO coordinate (245, 240) has the highest pixel values from the source.  The value of the
2054     // FBO pixel at (245, 240) is smaller than the same coordinate in the source because of the
2055     // blit's offsets.  That is, the value is (245-xOffset, 240-yOffset) or (235, 225).  Thus, the
2056     // following two tests are the same:
2057     EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 255 + yOffset,
2058                           GLColor(255 + (2 * xOffset), 255 + (2 * yOffset), 0, 255));
2059     EXPECT_PIXEL_COLOR_EQ(245, 240, GLColor(235, 225, 0, 255));
2060 
2061     // Again, the "mid-way" coordinates will get values that aren't truly mid-way:
2062     EXPECT_PIXEL_COLOR_EQ(
2063         xOffset + kCoordMidWayShort, yOffset + kCoordMidWayShort,
2064         GLColor(kCoordMidWayShort + (2 * xOffset), kCoordMidWayShort + (2 * yOffset), 0, 255));
2065     EXPECT_PIXEL_COLOR_EQ(
2066         xOffset + kCoordMidWayShort, yOffset + kCoordMidWayLong,
2067         GLColor(kCoordMidWayShort + (2 * xOffset), kCoordMidWayLong + (2 * yOffset), 0, 255));
2068     EXPECT_PIXEL_COLOR_EQ(
2069         xOffset + kCoordMidWayLong, yOffset + kCoordMidWayShort,
2070         GLColor(kCoordMidWayLong + (2 * xOffset), kCoordMidWayShort + (2 * yOffset), 0, 255));
2071     EXPECT_PIXEL_COLOR_EQ(
2072         xOffset + kCoordMidWayLong, yOffset + kCoordMidWayLong,
2073         GLColor(kCoordMidWayLong + (2 * xOffset), kCoordMidWayLong + (2 * yOffset), 0, 255));
2074 
2075     // Almost Red
2076     EXPECT_PIXEL_COLOR_EQ(255, -yOffset, GLColor(255 + xOffset, 0, 0, 255));
2077     // Almost Green
2078     EXPECT_PIXEL_COLOR_EQ(-xOffset, 255, GLColor(0, 255 + yOffset, 0, 255));
2079     // Almost Yellow
2080     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor(255 + xOffset, 255 + yOffset, 0, 255));
2081 
2082     ASSERT_GL_NO_ERROR();
2083 
2084     ASSERT_EGL_SUCCESS();
2085 }
2086 
2087 // Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x300
2088 // window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with coordinates
2089 // that are partially out-of-bounds of the source, and cause a "stretch" to occur
TEST_P(EGLPreRotationBlitFramebufferTest,FboDestOutOfBoundsSourceWithStretchBlitFramebuffer)2090 TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceWithStretchBlitFramebuffer)
2091 {
2092     // http://anglebug.com/42263074
2093     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2094 
2095     // Flaky on Linux SwANGLE http://anglebug.com/42263074
2096     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
2097 
2098     // To aid in debugging, we want this window visible
2099     setWindowVisible(mOSWindow, true);
2100 
2101     initializeDisplay();
2102     initializeSurfaceWithRGBA8888Config();
2103 
2104     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
2105     ASSERT_EGL_SUCCESS();
2106 
2107     // Init program
2108     GLuint program = createProgram();
2109     ASSERT_NE(0u, program);
2110     glUseProgram(program);
2111 
2112     GLBuffer indexBuffer;
2113     GLVertexArray vertexArray;
2114     GLBuffer vertexBuffers[2];
2115     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
2116     ASSERT_GL_NO_ERROR();
2117 
2118     // Create a texture-backed FBO and render the predictable pattern to it
2119     GLFramebuffer fbo;
2120     GLTexture texture;
2121     initializeFBO(&fbo, &texture);
2122     ASSERT_GL_NO_ERROR();
2123 
2124     glViewport(0, 0, mSize, mSize);
2125     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
2126     ASSERT_GL_NO_ERROR();
2127 
2128     // Ensure the predictable pattern seems correct in the FBO
2129     test256x256PredictablePattern(0, 0);
2130     ASSERT_GL_NO_ERROR();
2131 
2132     // Prepare to blit to the default framebuffer and read from the FBO
2133     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2134     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
2135     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2136     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2137 
2138     // Blit to the origin of the 400x300 window
2139     GLint xOffset = 0;
2140     GLint yOffset = 0;
2141 
2142     //
2143     // Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)
2144     //
2145 
2146     // To get the entire predictable pattern into the default framebuffer at the desired offset,
2147     // blit it from the FBO
2148     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2149     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
2150     glViewport(xOffset, yOffset, mSize, mSize);
2151     glClear(GL_COLOR_BUFFER_BIT);
2152     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
2153                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2154     // Swap buffers to put the image in the window (so the test can be visually checked)
2155     eglSwapBuffers(mDisplay, mWindowSurface);
2156     ASSERT_GL_NO_ERROR();
2157     // Blit again to check the colors in the back buffer
2158     glClear(GL_COLOR_BUFFER_BIT);
2159     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
2160                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2161 
2162     // Clear the FBO to black and blit from the window to the FBO, but give source coordinates that
2163     // are partially outside of the window, but "stretch" the result by 0.5 (i.e. 2X shrink in x)
2164     xOffset = -10;
2165     yOffset = -15;
2166     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
2167     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2168     glViewport(0, 0, mSize, mSize);
2169     glClear(GL_COLOR_BUFFER_BIT);
2170     glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize / 2, mSize,
2171                       GL_COLOR_BUFFER_BIT, GL_LINEAR);
2172 
2173     // Ensure the predictable pattern seems correct in the FBO
2174     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2175     // NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to
2176     // the source coordinates that were outside of the source.  The strip of black is xOffset/2
2177     // pixels wide on the left side, and yOffset pixels tall on the bottom side.
2178     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::black, 1);
2179     EXPECT_PIXEL_COLOR_NEAR(0, 255, GLColor::black, 1);
2180     EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 0, GLColor::black, 1);
2181     EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 255, GLColor::black, 1);
2182     EXPECT_PIXEL_COLOR_NEAR(0, -yOffset - 1, GLColor::black, 1);
2183     EXPECT_PIXEL_COLOR_NEAR(255 / 2, -yOffset - 1, GLColor::black, 1);
2184     EXPECT_PIXEL_COLOR_NEAR((255 + xOffset) / 2, 0, GLColor::black, 1);
2185     EXPECT_PIXEL_COLOR_NEAR((255 + xOffset) / 2, -yOffset - 1, GLColor::black, 1);
2186     EXPECT_PIXEL_COLOR_NEAR(0, 255 + yOffset, GLColor::black, 1);
2187     EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 255 + yOffset, GLColor::black, 1);
2188 
2189     // FBO coordinate (-xOffset, -yOffset) (or (10, 15)) has the values from the bottom-left corner
2190     // of the source (which happens to be black).  Thus, the following two tests are equivalent:
2191     EXPECT_PIXEL_COLOR_NEAR(-xOffset / 2, -yOffset, GLColor::black, 1);
2192     EXPECT_PIXEL_COLOR_NEAR(10 + xOffset, 15 + yOffset, GLColor::black, 1);
2193     EXPECT_PIXEL_COLOR_NEAR(220 / 2, 215, GLColor(210, 200, 0, 255), 1);
2194 
2195     EXPECT_PIXEL_COLOR_NEAR((254 + xOffset) / 2, 255 + yOffset,
2196                             GLColor(254 + (2 * xOffset), 255 + (2 * yOffset), 0, 255), 1);
2197     EXPECT_PIXEL_COLOR_NEAR(254 / 2, 240, GLColor(244, 225, 0, 255), 1);
2198 
2199     // Almost Red
2200     EXPECT_PIXEL_COLOR_NEAR(254 / 2, -yOffset, GLColor(254 + xOffset, 0, 0, 255), 1);
2201     // Almost Green
2202     EXPECT_PIXEL_COLOR_NEAR(-xOffset / 2, 255, GLColor(0, 255 + yOffset, 0, 255), 1);
2203     // Almost Yellow
2204     EXPECT_PIXEL_COLOR_NEAR(254 / 2, 255, GLColor(254 + xOffset, 255 + yOffset, 0, 255), 1);
2205 
2206     ASSERT_GL_NO_ERROR();
2207 
2208     ASSERT_EGL_SUCCESS();
2209 }
2210 
2211 // Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x300
2212 // window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with source and FBO
2213 // coordinates that are partially out-of-bounds of the source
TEST_P(EGLPreRotationBlitFramebufferTest,FboDestOutOfBoundsSourceAndDestBlitFramebuffer)2214 TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceAndDestBlitFramebuffer)
2215 {
2216     // http://anglebug.com/42263074
2217     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2218 
2219     // Flaky on Linux SwANGLE http://anglebug.com/42263074
2220     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
2221 
2222     // To aid in debugging, we want this window visible
2223     setWindowVisible(mOSWindow, true);
2224 
2225     initializeDisplay();
2226     initializeSurfaceWithRGBA8888Config();
2227 
2228     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
2229     ASSERT_EGL_SUCCESS();
2230 
2231     // Init program
2232     GLuint program = createProgram();
2233     ASSERT_NE(0u, program);
2234     glUseProgram(program);
2235 
2236     GLBuffer indexBuffer;
2237     GLVertexArray vertexArray;
2238     GLBuffer vertexBuffers[2];
2239     initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);
2240     ASSERT_GL_NO_ERROR();
2241 
2242     // Create a texture-backed FBO and render the predictable pattern to it
2243     GLFramebuffer fbo;
2244     GLTexture texture;
2245     initializeFBO(&fbo, &texture);
2246     ASSERT_GL_NO_ERROR();
2247 
2248     glViewport(0, 0, mSize, mSize);
2249     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
2250     ASSERT_GL_NO_ERROR();
2251 
2252     // Ensure the predictable pattern seems correct in the FBO
2253     test256x256PredictablePattern(0, 0);
2254     ASSERT_GL_NO_ERROR();
2255 
2256     // Prepare to blit to the default framebuffer and read from the FBO
2257     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2258     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
2259     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2260     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2261 
2262     // Blit to the origin of the 400x300 window
2263     GLint xOffset = 0;
2264     GLint yOffset = 0;
2265 
2266     //
2267     // Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)
2268     //
2269 
2270     // To get the entire predictable pattern into the default framebuffer at the desired offset,
2271     // blit it from the FBO
2272     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2273     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
2274     glViewport(xOffset, yOffset, mSize, mSize);
2275     glClear(GL_COLOR_BUFFER_BIT);
2276     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
2277                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2278     // Swap buffers to put the image in the window (so the test can be visually checked)
2279     eglSwapBuffers(mDisplay, mWindowSurface);
2280     ASSERT_GL_NO_ERROR();
2281     // Blit again to check the colors in the back buffer
2282     glClear(GL_COLOR_BUFFER_BIT);
2283     glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,
2284                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2285 
2286     // Clear the FBO to black and blit from the window to the FBO, but give source coordinates that
2287     // are partially outside of the window, and give destination coordinates that are partially
2288     // outside of the FBO
2289     xOffset = -10;
2290     yOffset = -15;
2291     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
2292     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2293     glViewport(0, 0, mSize, mSize);
2294     glClear(GL_COLOR_BUFFER_BIT);
2295     glBlitFramebuffer(xOffset, yOffset, (2 * xOffset) + mSize, (2 * yOffset) + mSize, -xOffset,
2296                       -yOffset, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);
2297 
2298     // Ensure the predictable pattern seems correct in the FBO
2299     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2300     // NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to
2301     // the source coordinates that were outside of the source.  The strip of black is xOffset*2
2302     // pixels wide on the left side, and yOffset*2 pixels tall on the bottom side.
2303     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2304     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::black);
2305     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 0, GLColor::black);
2306     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 255, GLColor::black);
2307     EXPECT_PIXEL_COLOR_EQ(0, (-yOffset * 2) - 1, GLColor::black);
2308     EXPECT_PIXEL_COLOR_EQ(255, (-yOffset * 2) - 1, GLColor::black);
2309     EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 0, GLColor::black);
2310     EXPECT_PIXEL_COLOR_EQ(255 + xOffset, (-yOffset * 2) - 1, GLColor::black);
2311     EXPECT_PIXEL_COLOR_EQ(0, 255 + yOffset, GLColor::black);
2312     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 255 + yOffset, GLColor::black);
2313 
2314     // FBO coordinate (-xOffset*2, -yOffset*2) (or (20, 30)) has the values from the bottom-left
2315     // corner of the source (which happens to be black).  Thus, the following two tests are
2316     // equivalent:
2317     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2), (-yOffset * 2), GLColor::black);
2318     EXPECT_PIXEL_COLOR_EQ(20, 30, GLColor::black);
2319 
2320     // Note: the following is equivalent to (0, 0):
2321     EXPECT_PIXEL_COLOR_EQ(20 + (xOffset * 2), 30 + (yOffset * 2), GLColor::black);
2322 
2323     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 1, (-yOffset * 2) + 1, GLColor(1, 1, 0, 255));
2324     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 10, (-yOffset * 2) + 10, GLColor(10, 10, 0, 255));
2325     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 20, (-yOffset * 2) + 20, GLColor(20, 20, 0, 255));
2326     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 100, (-yOffset * 2) + 100, GLColor(100, 100, 0, 255));
2327     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 200, (-yOffset * 2) + 200, GLColor(200, 200, 0, 255));
2328     EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 230, (-yOffset * 2) + 225, GLColor(230, 225, 0, 255));
2329 
2330     // Almost Red
2331     EXPECT_PIXEL_COLOR_EQ(255, -yOffset * 2, GLColor(255 + (xOffset * 2), 0, 0, 255));
2332     // Almost Green
2333     EXPECT_PIXEL_COLOR_EQ(-xOffset * 2, 255, GLColor(0, 255 + (yOffset * 2), 0, 255));
2334     // Almost Yellow
2335     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor(255 + (xOffset * 2), 255 + (yOffset * 2), 0, 255));
2336 
2337     ASSERT_GL_NO_ERROR();
2338 
2339     ASSERT_EGL_SUCCESS();
2340 }
2341 
2342 class EGLPreRotationInterpolateAtOffsetTest : public EGLPreRotationSurfaceTest
2343 {
2344   protected:
EGLPreRotationInterpolateAtOffsetTest()2345     EGLPreRotationInterpolateAtOffsetTest() {}
2346 
createProgram()2347     GLuint createProgram()
2348     {
2349         // Init program
2350         constexpr char kVS[] =
2351             "#version 310 es\n"
2352             "#extension GL_OES_shader_multisample_interpolation : require\n"
2353             "in highp vec2 position;\n"
2354             "uniform float screen_width;\n"
2355             "uniform float screen_height;\n"
2356             "out highp vec2 v_screenPosition;\n"
2357             "out highp vec2 v_offset;\n"
2358             "void main (void)\n"
2359             "{\n"
2360             "   gl_Position = vec4(position, 0, 1);\n"
2361             "   v_screenPosition = (position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(screen_width, "
2362             "screen_height);\n"
2363             "   v_offset = position.xy * 0.5f;\n"
2364             "}";
2365 
2366         constexpr char kFS[] =
2367             "#version 310 es\n"
2368             "#extension GL_OES_shader_multisample_interpolation : require\n"
2369             "in highp vec2 v_screenPosition;\n"
2370             "in highp vec2 v_offset;\n"
2371             "layout(location = 0) out mediump vec4 FragColor;\n"
2372             "void main() {\n"
2373             "   const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits "
2374             "+ 0.03125 for other errors\n"
2375             "\n"
2376             "   highp vec2 pixelCenter = floor(v_screenPosition) + vec2(0.5, 0.5);\n"
2377             "   highp vec2 offsetValue = interpolateAtOffset(v_screenPosition, v_offset);\n"
2378             "   highp vec2 refValue = pixelCenter + v_offset;\n"
2379             "\n"
2380             "   bool valuesEqual = all(lessThan(abs(offsetValue - refValue), vec2(threshold)));\n"
2381             "   if (valuesEqual)\n"
2382             "       FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
2383             "   else\n"
2384             "       FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
2385             "}";
2386 
2387         return CompileProgram(kVS, kFS);
2388     }
initializeGeometry(GLuint program,GLBuffer * indexBuffer,GLVertexArray * vertexArray,GLBuffer * vertexBuffers)2389     void initializeGeometry(GLuint program,
2390                             GLBuffer *indexBuffer,
2391                             GLVertexArray *vertexArray,
2392                             GLBuffer *vertexBuffers)
2393     {
2394         GLint positionLocation = glGetAttribLocation(program, "position");
2395         ASSERT_NE(-1, positionLocation);
2396 
2397         GLuint screenWidthId  = glGetUniformLocation(program, "screen_width");
2398         GLuint screenHeightId = glGetUniformLocation(program, "screen_height");
2399 
2400         glUniform1f(screenWidthId, (GLfloat)mSize);
2401         glUniform1f(screenHeightId, (GLfloat)mSize);
2402 
2403         glBindVertexArray(*vertexArray);
2404 
2405         std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};
2406         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
2407         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],
2408                      GL_STATIC_DRAW);
2409 
2410         std::vector<GLfloat> positionData = {// quad vertices
2411                                              -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};
2412 
2413         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
2414         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
2415                      GL_STATIC_DRAW);
2416         glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,
2417                               nullptr);
2418         glEnableVertexAttribArray(positionLocation);
2419     }
2420 };
2421 
2422 // Draw with interpolateAtOffset() builtin function to pre-rotated default FBO
TEST_P(EGLPreRotationInterpolateAtOffsetTest,InterpolateAtOffsetWithDefaultFBO)2423 TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithDefaultFBO)
2424 {
2425     // http://anglebug.com/42263074
2426     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2427 
2428     // Flaky on Linux SwANGLE http://anglebug.com/42263074
2429     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
2430 
2431     // To aid in debugging, we want this window visible
2432     setWindowVisible(mOSWindow, true);
2433 
2434     initializeDisplay();
2435     initializeSurfaceWithRGBA8888Config();
2436 
2437     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
2438     ASSERT_EGL_SUCCESS();
2439 
2440     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation"));
2441 
2442     // Init program
2443     GLuint program = createProgram();
2444     ASSERT_NE(0u, program);
2445     glUseProgram(program);
2446 
2447     GLBuffer indexBuffer;
2448     GLVertexArray vertexArray;
2449     GLBuffer vertexBuffers;
2450     initializeGeometry(program, &indexBuffer, &vertexArray, &vertexBuffers);
2451     ASSERT_GL_NO_ERROR();
2452 
2453     glViewport(0, 0, mSize, mSize);
2454     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
2455 
2456     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 255));
2457     EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor(0, 255, 0, 255));
2458     EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor(0, 255, 0, 255));
2459     EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor(0, 255, 0, 255));
2460     ASSERT_GL_NO_ERROR();
2461 
2462     // Make the image visible
2463     eglSwapBuffers(mDisplay, mWindowSurface);
2464     ASSERT_EGL_SUCCESS();
2465 }
2466 
2467 // Draw with interpolateAtOffset() builtin function to pre-rotated custom FBO
TEST_P(EGLPreRotationInterpolateAtOffsetTest,InterpolateAtOffsetWithCustomFBO)2468 TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithCustomFBO)
2469 {
2470     // http://anglebug.com/42263074
2471     ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2472 
2473     // Flaky on Linux SwANGLE http://anglebug.com/42263074
2474     ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
2475 
2476     // To aid in debugging, we want this window visible
2477     setWindowVisible(mOSWindow, true);
2478 
2479     initializeDisplay();
2480     initializeSurfaceWithRGBA8888Config();
2481 
2482     eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
2483     ASSERT_EGL_SUCCESS();
2484 
2485     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation"));
2486 
2487     // Init program
2488     GLuint program = createProgram();
2489     ASSERT_NE(0u, program);
2490     glUseProgram(program);
2491 
2492     GLBuffer indexBuffer;
2493     GLVertexArray vertexArray;
2494     GLBuffer vertexBuffers;
2495     initializeGeometry(program, &indexBuffer, &vertexArray, &vertexBuffers);
2496     ASSERT_GL_NO_ERROR();
2497 
2498     // Create a texture-backed FBO
2499     GLFramebuffer fbo;
2500     GLTexture texture;
2501     glBindTexture(GL_TEXTURE_2D, texture);
2502     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2503     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2504     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2505     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2506     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mSize, mSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2507     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2508     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2509     ASSERT_GL_NO_ERROR();
2510 
2511     glViewport(0, 0, mSize, mSize);
2512     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
2513 
2514     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 255));
2515     EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor(0, 255, 0, 255));
2516     EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor(0, 255, 0, 255));
2517     EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor(0, 255, 0, 255));
2518     ASSERT_GL_NO_ERROR();
2519 }
2520 
2521 }  // anonymous namespace
2522 
2523 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationInterpolateAtOffsetTest);
2524 ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationInterpolateAtOffsetTest,
2525                                  PrintToStringParamName,
2526                                  testing::Bool(),
2527                                  WithNoFixture(ES31_VULKAN()));
2528 
2529 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationSurfaceTest);
2530 ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationSurfaceTest,
2531                                  PrintToStringParamName,
2532                                  testing::Bool(),
2533                                  WithNoFixture(ES2_VULKAN()),
2534                                  WithNoFixture(ES3_VULKAN()),
2535                                  WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2536 
2537 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationLargeSurfaceTest);
2538 ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationLargeSurfaceTest,
2539                                  PrintToStringParamName,
2540                                  testing::Bool(),
2541                                  WithNoFixture(ES2_VULKAN()),
2542                                  WithNoFixture(ES3_VULKAN()),
2543                                  WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2544 
2545 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationBlitFramebufferTest);
2546 ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationBlitFramebufferTest,
2547                                  PrintToStringParamName,
2548                                  testing::Bool(),
2549                                  WithNoFixture(ES2_VULKAN()),
2550                                  WithNoFixture(ES3_VULKAN()),
2551                                  WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2552