Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLPreRotationTest.cpp
1693 views
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
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 ANGLETestWithParam<EGLPreRotationSurfaceTestParams>
57
{
58
protected:
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
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
96
void testSetUp() override
97
{
98
mOSWindow = OSWindow::New();
99
mOSWindow->initialize("EGLSurfaceTest", mSize, mSize);
100
}
101
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
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
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
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
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
294
TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDraw)
295
{
296
// http://anglebug.com/4453
297
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
298
299
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
// +------------+------------+ +--------+--------+
380
TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDerivativeDraw)
381
{
382
// http://anglebug.com/4453
383
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
384
385
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
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:
642
EGLPreRotationLargeSurfaceTest() : mSize(256) {}
643
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
654
TEST_P(EGLPreRotationLargeSurfaceTest, OrientedWindowWithFragCoordDraw)
655
{
656
// http://anglebug.com/4453
657
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
658
659
// Flaky on Linux SwANGLE http://anglebug.com/4453
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:
740
EGLPreRotationBlitFramebufferTest() {}
741
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
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
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.
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
836
TEST_P(EGLPreRotationBlitFramebufferTest, BasicBlitFramebuffer)
837
{
838
// http://anglebug.com/4453
839
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
840
841
// Flaky on Linux SwANGLE http://anglebug.com/4453
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.
927
TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithRotation)
928
{
929
// http://anglebug.com/4453
930
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
931
932
// Flaky on Linux SwANGLE http://anglebug.com/4453
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/5044
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.
1016
TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleStencilWithRotation)
1017
{
1018
// http://anglebug.com/4453
1019
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1020
1021
// Flaky on Linux SwANGLE http://anglebug.com/4453
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/5044
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.
1107
TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithFlip)
1108
{
1109
// http://anglebug.com/4453
1110
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1111
1112
// Flaky on Linux SwANGLE http://anglebug.com/4453
1113
ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
1114
1115
// We need to fix blit with pre-rotation. http://anglebug.com/5044
1116
ANGLE_SKIP_TEST_IF(IsAndroid() || 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.
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.
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.
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.
1424
TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithLinearFilter)
1425
{
1426
// http://anglebug.com/4453
1427
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1428
1429
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
1482
TEST_P(EGLPreRotationBlitFramebufferTest, LeftAndRightBlitFramebuffer)
1483
{
1484
// http://anglebug.com/4453
1485
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1486
1487
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
1600
TEST_P(EGLPreRotationBlitFramebufferTest, TopAndBottomBlitFramebuffer)
1601
{
1602
// http://anglebug.com/4453
1603
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1604
1605
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
1719
TEST_P(EGLPreRotationBlitFramebufferTest, ScaledBlitFramebuffer)
1720
{
1721
// http://anglebug.com/4453
1722
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1723
1724
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
1842
TEST_P(EGLPreRotationBlitFramebufferTest, FboDestBlitFramebuffer)
1843
{
1844
// http://anglebug.com/4453
1845
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1846
1847
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
1933
TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceBlitFramebuffer)
1934
{
1935
// http://anglebug.com/4453
1936
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
1937
1938
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
2090
TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceWithStretchBlitFramebuffer)
2091
{
2092
// http://anglebug.com/4453
2093
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2094
2095
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
2214
TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceAndDestBlitFramebuffer)
2215
{
2216
// http://anglebug.com/4453
2217
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2218
2219
// Flaky on Linux SwANGLE http://anglebug.com/4453
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:
2345
EGLPreRotationInterpolateAtOffsetTest() {}
2346
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
}
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
2423
TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithDefaultFBO)
2424
{
2425
// http://anglebug.com/4453
2426
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2427
2428
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
2468
TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithCustomFBO)
2469
{
2470
// http://anglebug.com/4453
2471
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
2472
2473
// Flaky on Linux SwANGLE http://anglebug.com/4453
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
#ifdef Bool
2524
// X11 ridiculousness.
2525
# undef Bool
2526
#endif
2527
2528
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationInterpolateAtOffsetTest);
2529
ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationInterpolateAtOffsetTest,
2530
PrintToStringParamName,
2531
testing::Bool(),
2532
WithNoFixture(ES31_VULKAN()));
2533
2534
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationSurfaceTest);
2535
ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationSurfaceTest,
2536
PrintToStringParamName,
2537
testing::Bool(),
2538
WithNoFixture(ES2_VULKAN()),
2539
WithNoFixture(ES3_VULKAN()),
2540
WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2541
2542
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationLargeSurfaceTest);
2543
ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationLargeSurfaceTest,
2544
PrintToStringParamName,
2545
testing::Bool(),
2546
WithNoFixture(ES2_VULKAN()),
2547
WithNoFixture(ES3_VULKAN()),
2548
WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2549
2550
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationBlitFramebufferTest);
2551
ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationBlitFramebufferTest,
2552
PrintToStringParamName,
2553
testing::Bool(),
2554
WithNoFixture(ES2_VULKAN()),
2555
WithNoFixture(ES3_VULKAN()),
2556
WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
2557
2558