Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLSurfaceTest.cpp
1693 views
1
//
2
// Copyright 2015 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
// EGLSurfaceTest:
7
// Tests pertaining to egl::Surface.
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
22
#if defined(ANGLE_ENABLE_D3D11)
23
# define INITGUID
24
# include <guiddef.h>
25
26
# include <d3d11.h>
27
# include <dcomp.h>
28
#endif
29
30
using namespace angle;
31
32
namespace
33
{
34
35
class EGLSurfaceTest : public ANGLETest
36
{
37
protected:
38
EGLSurfaceTest()
39
: mDisplay(EGL_NO_DISPLAY),
40
mWindowSurface(EGL_NO_SURFACE),
41
mPbufferSurface(EGL_NO_SURFACE),
42
mContext(EGL_NO_CONTEXT),
43
mSecondContext(EGL_NO_CONTEXT),
44
mOSWindow(nullptr)
45
{}
46
47
void testSetUp() override
48
{
49
mOSWindow = OSWindow::New();
50
mOSWindow->initialize("EGLSurfaceTest", 64, 64);
51
}
52
53
void tearDownContextAndSurface()
54
{
55
if (mDisplay == EGL_NO_DISPLAY)
56
{
57
return;
58
}
59
60
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
61
62
if (mWindowSurface != EGL_NO_SURFACE)
63
{
64
eglDestroySurface(mDisplay, mWindowSurface);
65
mWindowSurface = EGL_NO_SURFACE;
66
}
67
68
if (mPbufferSurface != EGL_NO_SURFACE)
69
{
70
eglDestroySurface(mDisplay, mPbufferSurface);
71
mPbufferSurface = EGL_NO_SURFACE;
72
}
73
74
if (mContext != EGL_NO_CONTEXT)
75
{
76
eglDestroyContext(mDisplay, mContext);
77
mContext = EGL_NO_CONTEXT;
78
}
79
80
if (mSecondContext != EGL_NO_CONTEXT)
81
{
82
eglDestroyContext(mDisplay, mSecondContext);
83
mSecondContext = EGL_NO_CONTEXT;
84
}
85
}
86
87
// Release any resources created in the test body
88
void testTearDown() override
89
{
90
tearDownContextAndSurface();
91
92
if (mDisplay != EGL_NO_DISPLAY)
93
{
94
eglTerminate(mDisplay);
95
mDisplay = EGL_NO_DISPLAY;
96
}
97
98
mOSWindow->destroy();
99
OSWindow::Delete(&mOSWindow);
100
101
ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT);
102
}
103
104
void initializeDisplay()
105
{
106
GLenum platformType = GetParam().getRenderer();
107
GLenum deviceType = GetParam().getDeviceType();
108
109
std::vector<EGLint> displayAttributes;
110
displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
111
displayAttributes.push_back(platformType);
112
displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);
113
displayAttributes.push_back(EGL_DONT_CARE);
114
displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);
115
displayAttributes.push_back(EGL_DONT_CARE);
116
displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
117
displayAttributes.push_back(deviceType);
118
displayAttributes.push_back(EGL_NONE);
119
120
mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
121
reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
122
displayAttributes.data());
123
ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
124
125
EGLint majorVersion, minorVersion;
126
ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);
127
128
eglBindAPI(EGL_OPENGL_ES_API);
129
ASSERT_EGL_SUCCESS();
130
}
131
132
void initializeSingleContext(EGLContext *context)
133
{
134
EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, GetParam().majorVersion, EGL_NONE};
135
136
*context = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
137
ASSERT_EGL_SUCCESS();
138
}
139
140
void initializeContext()
141
{
142
// Only initialize the contexts once.
143
if (mContext == EGL_NO_CONTEXT)
144
{
145
initializeSingleContext(&mContext);
146
}
147
if (mSecondContext == EGL_NO_CONTEXT)
148
{
149
initializeSingleContext(&mSecondContext);
150
}
151
}
152
153
void initializeWindowSurfaceWithAttribs(EGLConfig config,
154
const std::vector<EGLint> &additionalAttributes,
155
EGLenum expectedResult)
156
{
157
ASSERT_EQ(mWindowSurface, EGL_NO_SURFACE);
158
159
EGLint surfaceType = EGL_NONE;
160
eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
161
162
if (surfaceType & EGL_WINDOW_BIT)
163
{
164
std::vector<EGLint> windowAttributes = additionalAttributes;
165
windowAttributes.push_back(EGL_NONE);
166
167
// Create first window surface
168
mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
169
windowAttributes.data());
170
}
171
172
ASSERT_EGLENUM_EQ(eglGetError(), expectedResult);
173
}
174
175
void initializeSurfaceWithAttribs(EGLConfig config,
176
const std::vector<EGLint> &additionalAttributes)
177
{
178
mConfig = config;
179
180
EGLint surfaceType = EGL_NONE;
181
eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
182
183
if (surfaceType & EGL_WINDOW_BIT)
184
{
185
initializeWindowSurfaceWithAttribs(config, additionalAttributes, EGL_SUCCESS);
186
}
187
188
if (surfaceType & EGL_PBUFFER_BIT)
189
{
190
std::vector<EGLint> pbufferAttributes = additionalAttributes;
191
192
// Give pbuffer non-zero dimensions.
193
pbufferAttributes.push_back(EGL_WIDTH);
194
pbufferAttributes.push_back(64);
195
pbufferAttributes.push_back(EGL_HEIGHT);
196
pbufferAttributes.push_back(64);
197
pbufferAttributes.push_back(EGL_NONE);
198
199
mPbufferSurface = eglCreatePbufferSurface(mDisplay, mConfig, pbufferAttributes.data());
200
ASSERT_EGL_SUCCESS();
201
}
202
203
initializeContext();
204
}
205
206
void initializeSurface(EGLConfig config)
207
{
208
std::vector<EGLint> additionalAttributes;
209
initializeSurfaceWithAttribs(config, additionalAttributes);
210
}
211
212
EGLConfig chooseDefaultConfig(bool requireWindowSurface) const
213
{
214
const EGLint configAttributes[] = {EGL_RED_SIZE,
215
EGL_DONT_CARE,
216
EGL_GREEN_SIZE,
217
EGL_DONT_CARE,
218
EGL_BLUE_SIZE,
219
EGL_DONT_CARE,
220
EGL_ALPHA_SIZE,
221
EGL_DONT_CARE,
222
EGL_DEPTH_SIZE,
223
EGL_DONT_CARE,
224
EGL_STENCIL_SIZE,
225
EGL_DONT_CARE,
226
EGL_SAMPLE_BUFFERS,
227
0,
228
EGL_SURFACE_TYPE,
229
requireWindowSurface ? EGL_WINDOW_BIT : EGL_DONT_CARE,
230
EGL_NONE};
231
232
EGLint configCount;
233
EGLConfig config;
234
if (eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) != EGL_TRUE)
235
return nullptr;
236
if (configCount != 1)
237
return nullptr;
238
return config;
239
}
240
241
void initializeSurfaceWithDefaultConfig(bool requireWindowSurface)
242
{
243
EGLConfig defaultConfig = chooseDefaultConfig(requireWindowSurface);
244
ASSERT_NE(defaultConfig, nullptr);
245
initializeSurface(defaultConfig);
246
}
247
248
GLuint createProgram()
249
{
250
return CompileProgram(angle::essl1_shaders::vs::Simple(), angle::essl1_shaders::fs::Red());
251
}
252
253
void drawWithProgram(GLuint program)
254
{
255
glClearColor(0, 0, 0, 1);
256
glClear(GL_COLOR_BUFFER_BIT);
257
258
GLint positionLocation =
259
glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());
260
261
glUseProgram(program);
262
263
const GLfloat vertices[] = {
264
-1.0f, 1.0f, 0.5f, -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
265
266
-1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f,
267
};
268
269
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
270
glEnableVertexAttribArray(positionLocation);
271
272
glDrawArrays(GL_TRIANGLES, 0, 6);
273
274
glDisableVertexAttribArray(positionLocation);
275
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
276
277
EXPECT_PIXEL_EQ(mOSWindow->getWidth() / 2, mOSWindow->getHeight() / 2, 255, 0, 0, 255);
278
}
279
280
void runMessageLoopTest(EGLSurface secondSurface, EGLContext secondContext)
281
{
282
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
283
ASSERT_EGL_SUCCESS();
284
285
// Make a second context current
286
eglMakeCurrent(mDisplay, secondSurface, secondSurface, secondContext);
287
eglDestroySurface(mDisplay, mWindowSurface);
288
289
// Create second window surface
290
std::vector<EGLint> surfaceAttributes;
291
surfaceAttributes.push_back(EGL_NONE);
292
surfaceAttributes.push_back(EGL_NONE);
293
294
mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
295
&surfaceAttributes[0]);
296
ASSERT_EGL_SUCCESS();
297
298
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
299
ASSERT_EGL_SUCCESS();
300
301
mOSWindow->signalTestEvent();
302
mOSWindow->messageLoop();
303
ASSERT_TRUE(mOSWindow->didTestEventFire());
304
305
// Simple operation to test the FBO is set appropriately
306
glClear(GL_COLOR_BUFFER_BIT);
307
}
308
309
void drawQuadThenTearDown();
310
311
EGLDisplay mDisplay;
312
EGLSurface mWindowSurface;
313
EGLSurface mPbufferSurface;
314
EGLContext mContext;
315
EGLContext mSecondContext;
316
EGLConfig mConfig;
317
OSWindow *mOSWindow;
318
};
319
320
class EGLFloatSurfaceTest : public EGLSurfaceTest
321
{
322
protected:
323
EGLFloatSurfaceTest() : EGLSurfaceTest()
324
{
325
setWindowWidth(512);
326
setWindowHeight(512);
327
}
328
329
void testSetUp() override
330
{
331
mOSWindow = OSWindow::New();
332
mOSWindow->initialize("EGLFloatSurfaceTest", 64, 64);
333
}
334
335
void testTearDown() override
336
{
337
EGLSurfaceTest::testTearDown();
338
glDeleteProgram(mProgram);
339
}
340
341
GLuint createProgram()
342
{
343
constexpr char kFS[] =
344
"precision highp float;\n"
345
"void main()\n"
346
"{\n"
347
" gl_FragColor = vec4(1.0, 2.0, 3.0, 4.0);\n"
348
"}\n";
349
return CompileProgram(angle::essl1_shaders::vs::Simple(), kFS);
350
}
351
352
bool initializeSurfaceWithFloatConfig()
353
{
354
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
355
EGL_WINDOW_BIT,
356
EGL_RED_SIZE,
357
16,
358
EGL_GREEN_SIZE,
359
16,
360
EGL_BLUE_SIZE,
361
16,
362
EGL_ALPHA_SIZE,
363
16,
364
EGL_COLOR_COMPONENT_TYPE_EXT,
365
EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
366
EGL_NONE,
367
EGL_NONE};
368
369
initializeDisplay();
370
EGLConfig config;
371
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
372
{
373
std::cout << "EGLConfig for a float surface is not supported, skipping test"
374
<< std::endl;
375
return false;
376
}
377
378
initializeSurface(config);
379
380
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
381
mProgram = createProgram();
382
return true;
383
}
384
385
GLuint mProgram;
386
};
387
388
// Test clearing and checking the color is correct
389
TEST_P(EGLFloatSurfaceTest, Clearing)
390
{
391
ANGLE_SKIP_TEST_IF(!initializeSurfaceWithFloatConfig());
392
393
ASSERT_NE(0u, mProgram) << "shader compilation failed.";
394
ASSERT_GL_NO_ERROR();
395
396
GLColor32F clearColor(0.0f, 1.0f, 2.0f, 3.0f);
397
glClearColor(clearColor.R, clearColor.G, clearColor.B, clearColor.A);
398
glClear(GL_COLOR_BUFFER_BIT);
399
ASSERT_GL_NO_ERROR();
400
401
EXPECT_PIXEL_COLOR32F_EQ(0, 0, clearColor);
402
}
403
404
// Test drawing and checking the color is correct
405
TEST_P(EGLFloatSurfaceTest, Drawing)
406
{
407
ANGLE_SKIP_TEST_IF(!initializeSurfaceWithFloatConfig());
408
409
ASSERT_NE(0u, mProgram) << "shader compilation failed.";
410
ASSERT_GL_NO_ERROR();
411
412
glUseProgram(mProgram);
413
drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
414
415
EXPECT_PIXEL_32F_EQ(0, 0, 1.0f, 2.0f, 3.0f, 4.0f);
416
}
417
418
class EGLSurfaceTest3 : public EGLSurfaceTest
419
{};
420
421
// Test a surface bug where we could have two Window surfaces active
422
// at one time, blocking message loops. See http://crbug.com/475085
423
TEST_P(EGLSurfaceTest, MessageLoopBug)
424
{
425
// http://anglebug.com/3123
426
ANGLE_SKIP_TEST_IF(IsAndroid());
427
428
// http://anglebug.com/3138
429
ANGLE_SKIP_TEST_IF(IsOzone());
430
431
// http://anglebug.com/5485
432
ANGLE_SKIP_TEST_IF(IsIOS());
433
434
initializeDisplay();
435
initializeSurfaceWithDefaultConfig(true);
436
437
runMessageLoopTest(EGL_NO_SURFACE, EGL_NO_CONTEXT);
438
}
439
440
// Tests the message loop bug, but with setting a second context
441
// instead of null.
442
TEST_P(EGLSurfaceTest, MessageLoopBugContext)
443
{
444
// http://anglebug.com/3123
445
ANGLE_SKIP_TEST_IF(IsAndroid());
446
447
// http://anglebug.com/3138
448
ANGLE_SKIP_TEST_IF(IsOzone());
449
450
// http://anglebug.com/5485
451
ANGLE_SKIP_TEST_IF(IsIOS());
452
453
initializeDisplay();
454
initializeSurfaceWithDefaultConfig(true);
455
456
ANGLE_SKIP_TEST_IF(!mPbufferSurface);
457
runMessageLoopTest(mPbufferSurface, mSecondContext);
458
}
459
460
// Test a bug where calling makeCurrent twice would release the surface
461
TEST_P(EGLSurfaceTest, MakeCurrentTwice)
462
{
463
initializeDisplay();
464
initializeSurfaceWithDefaultConfig(false);
465
466
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
467
ASSERT_EGL_SUCCESS();
468
469
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
470
ASSERT_EGL_SUCCESS();
471
472
// Simple operation to test the FBO is set appropriately
473
glClear(GL_COLOR_BUFFER_BIT);
474
}
475
476
// Test that the window surface is correctly resized after calling swapBuffers
477
TEST_P(EGLSurfaceTest, ResizeWindow)
478
{
479
// http://anglebug.com/4453
480
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());
481
// Flaky on Linux SwANGLE http://anglebug.com/4453
482
ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
483
// http://anglebug.com/5485
484
ANGLE_SKIP_TEST_IF(IsIOS());
485
ANGLE_SKIP_TEST_IF(IsLinux() && IsARM());
486
487
// Necessary for a window resizing test if there is no per-frame window size query
488
setWindowVisible(mOSWindow, true);
489
490
GLenum platform = GetParam().getRenderer();
491
bool platformSupportsZeroSize = platform == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
492
platform == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
493
int minSize = platformSupportsZeroSize ? 0 : 1;
494
495
initializeDisplay();
496
initializeSurfaceWithDefaultConfig(true);
497
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
498
499
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
500
eglSwapBuffers(mDisplay, mWindowSurface);
501
ASSERT_EGL_SUCCESS();
502
503
EGLint height;
504
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
505
ASSERT_EGL_SUCCESS();
506
ASSERT_EQ(64, height); // initial size
507
508
// set window's height to 0 (if possible) or 1
509
mOSWindow->resize(64, minSize);
510
511
eglSwapBuffers(mDisplay, mWindowSurface);
512
ASSERT_EGL_SUCCESS();
513
514
// TODO(syoussefi): the GLX implementation still reads the window size as 64x64 through
515
// XGetGeometry. http://anglebug.com/3122
516
ANGLE_SKIP_TEST_IF(IsLinux() && IsOpenGL());
517
518
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
519
ASSERT_EGL_SUCCESS();
520
ASSERT_EQ(minSize, height);
521
522
// restore window's height
523
mOSWindow->resize(64, 64);
524
525
eglSwapBuffers(mDisplay, mWindowSurface);
526
ASSERT_EGL_SUCCESS();
527
528
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
529
ASSERT_EGL_SUCCESS();
530
ASSERT_EQ(64, height);
531
}
532
533
// Test that the backbuffer is correctly resized after calling swapBuffers
534
TEST_P(EGLSurfaceTest, ResizeWindowWithDraw)
535
{
536
// http://anglebug.com/4453
537
ANGLE_SKIP_TEST_IF(IsLinux());
538
// http://anglebug.com/5485
539
ANGLE_SKIP_TEST_IF(IsIOS());
540
541
// Necessary for a window resizing test if there is no per-frame window size query
542
setWindowVisible(mOSWindow, true);
543
544
initializeDisplay();
545
initializeSurfaceWithDefaultConfig(true);
546
initializeContext();
547
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
548
549
int size = 64;
550
EGLint height = 0;
551
EGLint width = 0;
552
553
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
554
eglSwapBuffers(mDisplay, mWindowSurface);
555
ASSERT_EGL_SUCCESS();
556
557
// Clear to red
558
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
559
glClear(GL_COLOR_BUFFER_BIT);
560
561
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
562
eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &width);
563
ASSERT_EGL_SUCCESS();
564
565
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
566
EXPECT_PIXEL_COLOR_EQ(size - 1, 0, GLColor::red);
567
EXPECT_PIXEL_COLOR_EQ(size - 1, size - 1, GLColor::red);
568
EXPECT_PIXEL_COLOR_EQ(0, size - 1, GLColor::red);
569
EXPECT_PIXEL_COLOR_EQ(-1, -1, GLColor::transparentBlack);
570
EXPECT_PIXEL_COLOR_EQ(size, 0, GLColor::transparentBlack);
571
EXPECT_PIXEL_COLOR_EQ(0, size, GLColor::transparentBlack);
572
EXPECT_PIXEL_COLOR_EQ(size, size, GLColor::transparentBlack);
573
574
// set window's size small
575
size = 1;
576
mOSWindow->resize(size, size);
577
578
eglSwapBuffers(mDisplay, mWindowSurface);
579
ASSERT_EGL_SUCCESS();
580
581
// Clear to green
582
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
583
glClear(GL_COLOR_BUFFER_BIT);
584
585
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
586
eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &width);
587
ASSERT_EGL_SUCCESS();
588
589
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
590
EXPECT_PIXEL_COLOR_EQ(size - 1, 0, GLColor::green);
591
EXPECT_PIXEL_COLOR_EQ(size - 1, size - 1, GLColor::green);
592
EXPECT_PIXEL_COLOR_EQ(0, size - 1, GLColor::green);
593
EXPECT_PIXEL_COLOR_EQ(-1, -1, GLColor::transparentBlack);
594
EXPECT_PIXEL_COLOR_EQ(size, 0, GLColor::transparentBlack);
595
EXPECT_PIXEL_COLOR_EQ(0, size, GLColor::transparentBlack);
596
EXPECT_PIXEL_COLOR_EQ(size, size, GLColor::transparentBlack);
597
598
// set window's height large
599
size = 128;
600
mOSWindow->resize(size, size);
601
602
eglSwapBuffers(mDisplay, mWindowSurface);
603
ASSERT_EGL_SUCCESS();
604
605
// Clear to blue
606
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
607
glClear(GL_COLOR_BUFFER_BIT);
608
609
eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &height);
610
eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &width);
611
ASSERT_EGL_SUCCESS();
612
613
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
614
EXPECT_PIXEL_COLOR_EQ(size - 1, 0, GLColor::blue);
615
EXPECT_PIXEL_COLOR_EQ(size - 1, size - 1, GLColor::blue);
616
EXPECT_PIXEL_COLOR_EQ(0, size - 1, GLColor::blue);
617
EXPECT_PIXEL_COLOR_EQ(-1, -1, GLColor::transparentBlack);
618
EXPECT_PIXEL_COLOR_EQ(size, 0, GLColor::transparentBlack);
619
EXPECT_PIXEL_COLOR_EQ(0, size, GLColor::transparentBlack);
620
EXPECT_PIXEL_COLOR_EQ(size, size, GLColor::transparentBlack);
621
}
622
623
// Test that the window can be reset repeatedly before surface creation.
624
TEST_P(EGLSurfaceTest, ResetNativeWindow)
625
{
626
setWindowVisible(mOSWindow, true);
627
628
initializeDisplay();
629
630
for (int i = 0; i < 10; ++i)
631
{
632
mOSWindow->resetNativeWindow();
633
}
634
635
initializeSurfaceWithDefaultConfig(true);
636
initializeContext();
637
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
638
639
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
640
641
eglSwapBuffers(mDisplay, mWindowSurface);
642
ASSERT_EGL_SUCCESS();
643
}
644
645
// Test creating a surface that supports a EGLConfig with 16bit
646
// support GL_RGB565
647
TEST_P(EGLSurfaceTest, CreateWithEGLConfig5650Support)
648
{
649
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
650
EGL_WINDOW_BIT,
651
EGL_RED_SIZE,
652
5,
653
EGL_GREEN_SIZE,
654
6,
655
EGL_BLUE_SIZE,
656
5,
657
EGL_ALPHA_SIZE,
658
0,
659
EGL_DEPTH_SIZE,
660
0,
661
EGL_STENCIL_SIZE,
662
0,
663
EGL_SAMPLE_BUFFERS,
664
0,
665
EGL_NONE};
666
667
initializeDisplay();
668
EGLConfig config;
669
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
670
{
671
std::cout << "EGLConfig for a GL_RGB565 surface is not supported, skipping test"
672
<< std::endl;
673
return;
674
}
675
676
initializeSurface(config);
677
678
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
679
ASSERT_EGL_SUCCESS();
680
681
GLuint program = createProgram();
682
ASSERT_NE(0u, program);
683
drawWithProgram(program);
684
EXPECT_GL_NO_ERROR();
685
glDeleteProgram(program);
686
}
687
688
// Test creating a surface that supports a EGLConfig with 16bit
689
// support GL_RGBA4
690
TEST_P(EGLSurfaceTest, CreateWithEGLConfig4444Support)
691
{
692
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
693
EGL_WINDOW_BIT,
694
EGL_RED_SIZE,
695
4,
696
EGL_GREEN_SIZE,
697
4,
698
EGL_BLUE_SIZE,
699
4,
700
EGL_ALPHA_SIZE,
701
4,
702
EGL_DEPTH_SIZE,
703
0,
704
EGL_STENCIL_SIZE,
705
0,
706
EGL_SAMPLE_BUFFERS,
707
0,
708
EGL_NONE};
709
710
initializeDisplay();
711
EGLConfig config;
712
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
713
{
714
std::cout << "EGLConfig for a GL_RGBA4 surface is not supported, skipping test"
715
<< std::endl;
716
return;
717
}
718
719
initializeSurface(config);
720
721
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
722
ASSERT_EGL_SUCCESS();
723
724
GLuint program = createProgram();
725
ASSERT_NE(0u, program);
726
drawWithProgram(program);
727
EXPECT_GL_NO_ERROR();
728
glDeleteProgram(program);
729
}
730
731
// Test creating a surface that supports a EGLConfig with 16bit
732
// support GL_RGB5_A1
733
TEST_P(EGLSurfaceTest, CreateWithEGLConfig5551Support)
734
{
735
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
736
EGL_WINDOW_BIT,
737
EGL_RED_SIZE,
738
5,
739
EGL_GREEN_SIZE,
740
5,
741
EGL_BLUE_SIZE,
742
5,
743
EGL_ALPHA_SIZE,
744
1,
745
EGL_DEPTH_SIZE,
746
0,
747
EGL_STENCIL_SIZE,
748
0,
749
EGL_SAMPLE_BUFFERS,
750
0,
751
EGL_NONE};
752
753
initializeDisplay();
754
EGLConfig config;
755
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
756
{
757
std::cout << "EGLConfig for a GL_RGB5_A1 surface is not supported, skipping test"
758
<< std::endl;
759
return;
760
}
761
762
initializeSurface(config);
763
764
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
765
ASSERT_EGL_SUCCESS();
766
767
GLuint program = createProgram();
768
ASSERT_NE(0u, program);
769
drawWithProgram(program);
770
EXPECT_GL_NO_ERROR();
771
glDeleteProgram(program);
772
}
773
774
// Test creating a surface that supports a EGLConfig without alpha support
775
TEST_P(EGLSurfaceTest, CreateWithEGLConfig8880Support)
776
{
777
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
778
EGL_WINDOW_BIT,
779
EGL_RED_SIZE,
780
8,
781
EGL_GREEN_SIZE,
782
8,
783
EGL_BLUE_SIZE,
784
8,
785
EGL_ALPHA_SIZE,
786
0,
787
EGL_DEPTH_SIZE,
788
0,
789
EGL_STENCIL_SIZE,
790
0,
791
EGL_SAMPLE_BUFFERS,
792
0,
793
EGL_NONE};
794
795
initializeDisplay();
796
EGLConfig config;
797
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
798
{
799
std::cout << "EGLConfig for a GL_RGB8_OES surface is not supported, skipping test"
800
<< std::endl;
801
return;
802
}
803
804
initializeSurface(config);
805
806
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
807
ASSERT_EGL_SUCCESS();
808
809
GLuint program = createProgram();
810
ASSERT_NE(0u, program);
811
drawWithProgram(program);
812
EXPECT_GL_NO_ERROR();
813
glDeleteProgram(program);
814
}
815
816
TEST_P(EGLSurfaceTest, FixedSizeWindow)
817
{
818
const EGLint configAttributes[] = {EGL_SURFACE_TYPE,
819
EGL_WINDOW_BIT,
820
EGL_RED_SIZE,
821
8,
822
EGL_GREEN_SIZE,
823
8,
824
EGL_BLUE_SIZE,
825
8,
826
EGL_ALPHA_SIZE,
827
0,
828
EGL_DEPTH_SIZE,
829
0,
830
EGL_STENCIL_SIZE,
831
0,
832
EGL_SAMPLE_BUFFERS,
833
0,
834
EGL_NONE};
835
836
initializeDisplay();
837
ANGLE_SKIP_TEST_IF(EGLWindow::FindEGLConfig(mDisplay, configAttributes, &mConfig) == EGL_FALSE);
838
839
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_window_fixed_size"));
840
841
constexpr EGLint kInitialSize = 64;
842
constexpr EGLint kUpdateSize = 32;
843
844
EGLint surfaceAttributes[] = {
845
EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, kInitialSize, EGL_HEIGHT, kInitialSize, EGL_NONE,
846
};
847
848
// Create first window surface
849
mWindowSurface =
850
eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(), surfaceAttributes);
851
ASSERT_EGL_SUCCESS();
852
ASSERT_NE(EGL_NO_SURFACE, mWindowSurface);
853
854
initializeContext();
855
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext));
856
ASSERT_EGL_SUCCESS();
857
858
EGLint queryIsFixedSize = 0;
859
EXPECT_EGL_TRUE(
860
eglQuerySurface(mDisplay, mWindowSurface, EGL_FIXED_SIZE_ANGLE, &queryIsFixedSize));
861
ASSERT_EGL_SUCCESS();
862
EXPECT_EGL_TRUE(queryIsFixedSize);
863
864
EGLint queryWidth = 0;
865
EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &queryWidth));
866
ASSERT_EGL_SUCCESS();
867
EXPECT_EQ(kInitialSize, queryWidth);
868
869
EGLint queryHeight = 0;
870
EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &queryHeight));
871
ASSERT_EGL_SUCCESS();
872
EXPECT_EQ(kInitialSize, queryHeight);
873
874
// Update the size
875
EXPECT_EGL_TRUE(eglSurfaceAttrib(mDisplay, mWindowSurface, EGL_WIDTH, kUpdateSize));
876
ASSERT_EGL_SUCCESS();
877
878
EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
879
ASSERT_EGL_SUCCESS();
880
881
EGLint queryUpdatedWidth = 0;
882
EXPECT_EGL_TRUE(eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &queryUpdatedWidth));
883
ASSERT_EGL_SUCCESS();
884
EXPECT_EQ(kUpdateSize, queryUpdatedWidth);
885
}
886
887
TEST_P(EGLSurfaceTest3, MakeCurrentDifferentSurfaces)
888
{
889
const EGLint configAttributes[] = {
890
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
891
EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};
892
EGLSurface firstPbufferSurface;
893
EGLSurface secondPbufferSurface;
894
895
initializeDisplay();
896
ANGLE_SKIP_TEST_IF(EGLWindow::FindEGLConfig(mDisplay, configAttributes, &mConfig) == EGL_FALSE);
897
898
EGLint surfaceType = 0;
899
eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);
900
bool supportsPbuffers = (surfaceType & EGL_PBUFFER_BIT) != 0;
901
EGLint bindToTextureRGBA = 0;
902
eglGetConfigAttrib(mDisplay, mConfig, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA);
903
bool supportsBindTexImage = (bindToTextureRGBA == EGL_TRUE);
904
905
const EGLint pBufferAttributes[] = {
906
EGL_WIDTH, 64,
907
EGL_HEIGHT, 64,
908
EGL_TEXTURE_FORMAT, supportsPbuffers ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
909
EGL_TEXTURE_TARGET, supportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
910
EGL_NONE, EGL_NONE,
911
};
912
913
// Create the surfaces
914
firstPbufferSurface = eglCreatePbufferSurface(mDisplay, mConfig, pBufferAttributes);
915
ASSERT_EGL_SUCCESS();
916
ASSERT_NE(EGL_NO_SURFACE, firstPbufferSurface);
917
secondPbufferSurface = eglCreatePbufferSurface(mDisplay, mConfig, pBufferAttributes);
918
ASSERT_EGL_SUCCESS();
919
ASSERT_NE(EGL_NO_SURFACE, secondPbufferSurface);
920
921
initializeContext();
922
923
// Use the same surface for both draw and read
924
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, firstPbufferSurface, firstPbufferSurface, mContext));
925
926
// TODO(http://www.anglebug.com/6284): Failing with OpenGL ES backend on Android.
927
// Must be after the eglMakeCurrent() so the renderer string is initialized.
928
ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
929
930
glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
931
glClear(GL_COLOR_BUFFER_BIT);
932
ASSERT_GL_NO_ERROR();
933
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
934
935
// Use different surfaces for draw and read, read should stay the same
936
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, secondPbufferSurface, firstPbufferSurface, mContext));
937
glClearColor(GLColor::blue.R, GLColor::blue.G, GLColor::blue.B, GLColor::blue.A);
938
glClear(GL_COLOR_BUFFER_BIT);
939
ASSERT_GL_NO_ERROR();
940
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
941
// Verify draw surface was cleared
942
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, secondPbufferSurface, secondPbufferSurface, mContext));
943
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
944
945
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, firstPbufferSurface, secondPbufferSurface, mContext));
946
ASSERT_EGL_SUCCESS();
947
948
// Blit the source surface to the destination surface
949
glBlitFramebuffer(0, 0, 64, 64, 0, 0, 64, 64, GL_COLOR_BUFFER_BIT, GL_NEAREST);
950
ASSERT_GL_NO_ERROR();
951
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, firstPbufferSurface, firstPbufferSurface, mContext));
952
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
953
}
954
955
#if defined(ANGLE_ENABLE_D3D11)
956
class EGLSurfaceTestD3D11 : public EGLSurfaceTest
957
{};
958
959
// Test that rendering to an IDCompositionSurface using a pbuffer works.
960
TEST_P(EGLSurfaceTestD3D11, CreateDirectCompositionSurface)
961
{
962
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_platform_angle_d3d"));
963
initializeDisplay();
964
965
EGLAttrib device = 0;
966
EGLAttrib newEglDevice = 0;
967
ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &newEglDevice));
968
ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(newEglDevice),
969
EGL_D3D11_DEVICE_ANGLE, &device));
970
angle::ComPtr<ID3D11Device> d3d11Device(reinterpret_cast<ID3D11Device *>(device));
971
ASSERT_TRUE(!!d3d11Device);
972
973
HMODULE dcompLibrary = LoadLibraryA("dcomp.dll");
974
if (!dcompLibrary)
975
{
976
std::cout << "DirectComposition not supported" << std::endl;
977
return;
978
}
979
typedef HRESULT(WINAPI * PFN_DCOMPOSITION_CREATE_DEVICE2)(IUnknown * dxgiDevice, REFIID iid,
980
void **dcompositionDevice);
981
PFN_DCOMPOSITION_CREATE_DEVICE2 createDComp = reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE2>(
982
GetProcAddress(dcompLibrary, "DCompositionCreateDevice2"));
983
if (!createDComp)
984
{
985
std::cout << "DirectComposition2 not supported" << std::endl;
986
FreeLibrary(dcompLibrary);
987
return;
988
}
989
990
angle::ComPtr<IDCompositionDevice> dcompDevice;
991
HRESULT hr = createDComp(d3d11Device.Get(), IID_PPV_ARGS(dcompDevice.GetAddressOf()));
992
ASSERT_TRUE(SUCCEEDED(hr));
993
994
angle::ComPtr<IDCompositionSurface> dcompSurface;
995
hr = dcompDevice->CreateSurface(100, 100, DXGI_FORMAT_B8G8R8A8_UNORM,
996
DXGI_ALPHA_MODE_PREMULTIPLIED, dcompSurface.GetAddressOf());
997
ASSERT_TRUE(SUCCEEDED(hr));
998
999
angle::ComPtr<ID3D11Texture2D> texture;
1000
POINT updateOffset;
1001
hr = dcompSurface->BeginDraw(nullptr, IID_PPV_ARGS(texture.GetAddressOf()), &updateOffset);
1002
ASSERT_TRUE(SUCCEEDED(hr));
1003
1004
const EGLint configAttributes[] = {
1005
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
1006
EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};
1007
1008
EGLConfig config;
1009
ASSERT_EGL_TRUE(EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config));
1010
1011
const EGLint surfaceAttributes[] = {EGL_WIDTH,
1012
100,
1013
EGL_HEIGHT,
1014
100,
1015
EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE,
1016
EGL_TRUE,
1017
EGL_TEXTURE_OFFSET_X_ANGLE,
1018
updateOffset.x,
1019
EGL_TEXTURE_OFFSET_Y_ANGLE,
1020
updateOffset.y,
1021
EGL_NONE};
1022
1023
EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture.Get());
1024
mPbufferSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_ANGLE, buffer,
1025
config, surfaceAttributes);
1026
ASSERT_EGL_SUCCESS();
1027
1028
mConfig = config;
1029
initializeContext();
1030
1031
eglMakeCurrent(mDisplay, mPbufferSurface, mPbufferSurface, mContext);
1032
ASSERT_EGL_SUCCESS();
1033
1034
GLuint program = createProgram();
1035
ASSERT_NE(0u, program);
1036
drawWithProgram(program);
1037
EXPECT_GL_NO_ERROR();
1038
glDeleteProgram(program);
1039
}
1040
1041
TEST_P(EGLSurfaceTestD3D11, CreateSurfaceWithTextureOffset)
1042
{
1043
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_platform_angle_d3d"));
1044
initializeDisplay();
1045
1046
const EGLint configAttributes[] = {
1047
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
1048
EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};
1049
1050
EGLConfig config;
1051
ASSERT_EGL_TRUE(EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config));
1052
1053
mConfig = config;
1054
initializeContext();
1055
1056
EGLAttrib device = 0;
1057
EGLAttrib newEglDevice = 0;
1058
ASSERT_EGL_TRUE(eglQueryDisplayAttribEXT(mDisplay, EGL_DEVICE_EXT, &newEglDevice));
1059
ASSERT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(newEglDevice),
1060
EGL_D3D11_DEVICE_ANGLE, &device));
1061
angle::ComPtr<ID3D11Device> d3d11Device(reinterpret_cast<ID3D11Device *>(device));
1062
ASSERT_TRUE(!!d3d11Device);
1063
1064
constexpr UINT kTextureWidth = 100;
1065
constexpr UINT kTextureHeight = 100;
1066
constexpr Color<uint8_t> kOpaqueBlack(0, 0, 0, 255);
1067
std::vector<Color<uint8_t>> textureData(kTextureWidth * kTextureHeight, kOpaqueBlack);
1068
1069
D3D11_SUBRESOURCE_DATA initialData = {};
1070
initialData.pSysMem = textureData.data();
1071
initialData.SysMemPitch = kTextureWidth * sizeof(kOpaqueBlack);
1072
1073
D3D11_TEXTURE2D_DESC desc = {};
1074
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
1075
desc.Width = kTextureWidth;
1076
desc.Height = kTextureHeight;
1077
desc.ArraySize = 1;
1078
desc.MipLevels = 1;
1079
desc.SampleDesc.Count = 1;
1080
desc.Usage = D3D11_USAGE_DEFAULT;
1081
desc.BindFlags = D3D11_BIND_RENDER_TARGET;
1082
angle::ComPtr<ID3D11Texture2D> texture;
1083
HRESULT hr = d3d11Device->CreateTexture2D(&desc, &initialData, &texture);
1084
ASSERT_TRUE(SUCCEEDED(hr));
1085
1086
angle::ComPtr<ID3D11DeviceContext> d3d11Context;
1087
d3d11Device->GetImmediateContext(&d3d11Context);
1088
1089
// Specify a texture offset of (50, 50) when rendering to the pbuffer surface.
1090
const EGLint surfaceAttributes[] = {EGL_WIDTH,
1091
kTextureWidth,
1092
EGL_HEIGHT,
1093
kTextureHeight,
1094
EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE,
1095
EGL_TRUE,
1096
EGL_TEXTURE_OFFSET_X_ANGLE,
1097
50,
1098
EGL_TEXTURE_OFFSET_Y_ANGLE,
1099
50,
1100
EGL_NONE};
1101
EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture.Get());
1102
mPbufferSurface = eglCreatePbufferFromClientBuffer(mDisplay, EGL_D3D_TEXTURE_ANGLE, buffer,
1103
config, surfaceAttributes);
1104
ASSERT_EGL_SUCCESS();
1105
1106
eglMakeCurrent(mDisplay, mPbufferSurface, mPbufferSurface, mContext);
1107
ASSERT_EGL_SUCCESS();
1108
1109
// glClear should only clear subrect at offset (50, 50) without explicit scissor.
1110
glClearColor(0, 0, 1, 1); // Blue
1111
glClear(GL_COLOR_BUFFER_BIT);
1112
EXPECT_PIXEL_EQ(25, 25, 0, 0, 0, 255);
1113
EXPECT_PIXEL_EQ(75, 75, 0, 0, 255, 255);
1114
EXPECT_GL_NO_ERROR();
1115
1116
// Drawing with a shader should also update the same subrect only without explicit viewport.
1117
GLuint program = createProgram(); // Red
1118
ASSERT_NE(0u, program);
1119
GLint positionLocation = glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());
1120
glUseProgram(program);
1121
const GLfloat vertices[] = {
1122
-1.0f, 1.0f, 0.5f, -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, 0.5f,
1123
-1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, 1.0f, 1.0f, 0.5f,
1124
};
1125
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
1126
glEnableVertexAttribArray(positionLocation);
1127
glDrawArrays(GL_TRIANGLES, 0, 6);
1128
glDisableVertexAttribArray(positionLocation);
1129
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1130
1131
EXPECT_PIXEL_EQ(25, 25, 0, 0, 0, 255);
1132
EXPECT_PIXEL_EQ(75, 75, 255, 0, 0, 255);
1133
EXPECT_GL_NO_ERROR();
1134
1135
glDeleteProgram(program);
1136
EXPECT_GL_NO_ERROR();
1137
1138
// Blit framebuffer should also blit to the same subrect despite the dstX/Y arguments.
1139
GLRenderbuffer renderBuffer;
1140
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
1141
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 50, 50);
1142
EXPECT_GL_NO_ERROR();
1143
1144
GLFramebuffer framebuffer;
1145
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1146
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer);
1147
EXPECT_GL_NO_ERROR();
1148
1149
glClearColor(0, 1, 0, 1); // Green
1150
glClear(GL_COLOR_BUFFER_BIT);
1151
EXPECT_PIXEL_EQ(25, 25, 0, 255, 0, 255);
1152
EXPECT_GL_NO_ERROR();
1153
1154
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0u);
1155
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1156
glBlitFramebuffer(0, 0, 50, 50, 0, 0, 50, 50, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1157
EXPECT_GL_NO_ERROR();
1158
1159
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0u);
1160
EXPECT_PIXEL_EQ(25, 25, 0, 0, 0, 255);
1161
EXPECT_PIXEL_EQ(75, 75, 0, 255, 0, 255);
1162
EXPECT_GL_NO_ERROR();
1163
}
1164
1165
TEST_P(EGLSurfaceTestD3D11, CreateSurfaceWithMSAA)
1166
{
1167
ANGLE_SKIP_TEST_IF(!IsEGLClientExtensionEnabled("EGL_ANGLE_platform_angle_d3d"));
1168
1169
// clang-format off
1170
const EGLint configAttributes[] =
1171
{
1172
EGL_RED_SIZE, 8,
1173
EGL_GREEN_SIZE, 8,
1174
EGL_BLUE_SIZE, 8,
1175
EGL_ALPHA_SIZE, 0,
1176
EGL_DEPTH_SIZE, 0,
1177
EGL_STENCIL_SIZE, 0,
1178
EGL_SAMPLE_BUFFERS, 1,
1179
EGL_SAMPLES, 4,
1180
EGL_NONE
1181
};
1182
// clang-format on
1183
1184
initializeDisplay();
1185
EGLConfig config;
1186
if (EGLWindow::FindEGLConfig(mDisplay, configAttributes, &config) == EGL_FALSE)
1187
{
1188
std::cout << "EGLConfig for 4xMSAA is not supported, skipping test" << std::endl;
1189
return;
1190
}
1191
1192
initializeSurface(config);
1193
1194
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1195
ASSERT_EGL_SUCCESS();
1196
1197
GLuint program = createProgram();
1198
ASSERT_NE(0u, program);
1199
1200
glClearColor(0, 0, 0, 1);
1201
glClear(GL_COLOR_BUFFER_BIT);
1202
1203
GLint positionLocation = glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());
1204
ASSERT_NE(-1, positionLocation);
1205
1206
glUseProgram(program);
1207
1208
const GLfloat halfPixelOffset = 0.5f * 2.0f / mOSWindow->getWidth();
1209
// clang-format off
1210
const GLfloat vertices[] =
1211
{
1212
-1.0f + halfPixelOffset, 1.0f, 0.5f,
1213
-1.0f + halfPixelOffset, -1.0f, 0.5f,
1214
1.0f, -1.0f, 0.5f
1215
};
1216
// clang-format on
1217
1218
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
1219
glEnableVertexAttribArray(positionLocation);
1220
1221
glDrawArrays(GL_TRIANGLES, 0, 3);
1222
1223
glDisableVertexAttribArray(positionLocation);
1224
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1225
1226
EXPECT_PIXEL_NEAR(0, 0, 127, 0, 0, 255, 10);
1227
EXPECT_GL_NO_ERROR();
1228
1229
glDeleteProgram(program);
1230
}
1231
1232
#endif // ANGLE_ENABLE_D3D11
1233
1234
// Verify bliting between two surfaces works correctly.
1235
TEST_P(EGLSurfaceTest3, BlitBetweenSurfaces)
1236
{
1237
initializeDisplay();
1238
ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
1239
1240
initializeSurfaceWithDefaultConfig(true);
1241
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
1242
ASSERT_NE(mContext, EGL_NO_CONTEXT);
1243
1244
EGLSurface surface1;
1245
EGLSurface surface2;
1246
1247
const EGLint surfaceAttributes[] = {
1248
EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE,
1249
};
1250
1251
surface1 = eglCreatePbufferSurface(mDisplay, mConfig, surfaceAttributes);
1252
ASSERT_EGL_SUCCESS();
1253
surface2 = eglCreatePbufferSurface(mDisplay, mConfig, surfaceAttributes);
1254
ASSERT_EGL_SUCCESS();
1255
1256
// Clear surface1.
1257
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface1, surface1, mContext));
1258
1259
// TODO(http://www.anglebug.com/6284): Failing with OpenGL ES backend on Android and Windows.
1260
// Must be after the eglMakeCurrent() so the renderer string is initialized.
1261
ANGLE_SKIP_TEST_IF(IsOpenGLES() && (IsAndroid() || IsWindows()));
1262
1263
glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
1264
glClear(GL_COLOR_BUFFER_BIT);
1265
ASSERT_GL_NO_ERROR();
1266
1267
// Blit from surface1 to surface2.
1268
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface2, surface1, mContext));
1269
glBlitFramebuffer(0, 0, 64, 64, 0, 0, 64, 64, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1270
ASSERT_GL_NO_ERROR();
1271
1272
// Confirm surface1 has the clear color.
1273
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface1, surface1, mContext));
1274
EXPECT_PIXEL_COLOR_EQ(32, 32, GLColor::red);
1275
1276
// Confirm surface2 has the blited clear color.
1277
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface2, surface2, mContext));
1278
EXPECT_PIXEL_COLOR_EQ(32, 32, GLColor::red);
1279
1280
eglDestroySurface(mDisplay, surface1);
1281
eglDestroySurface(mDisplay, surface2);
1282
}
1283
1284
// Verify bliting between two surfaces works correctly.
1285
TEST_P(EGLSurfaceTest3, BlitBetweenSurfacesWithDeferredClear)
1286
{
1287
initializeDisplay();
1288
ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
1289
1290
initializeSurfaceWithDefaultConfig(true);
1291
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
1292
ASSERT_NE(mContext, EGL_NO_CONTEXT);
1293
1294
EGLSurface surface1;
1295
EGLSurface surface2;
1296
1297
const EGLint surfaceAttributes[] = {
1298
EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE,
1299
};
1300
1301
surface1 = eglCreatePbufferSurface(mDisplay, mConfig, surfaceAttributes);
1302
ASSERT_EGL_SUCCESS();
1303
surface2 = eglCreatePbufferSurface(mDisplay, mConfig, surfaceAttributes);
1304
ASSERT_EGL_SUCCESS();
1305
1306
// Clear surface1.
1307
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface1, surface1, mContext));
1308
1309
// TODO(http://www.anglebug.com/6284): Failing with OpenGL ES backend on Android and Windows.
1310
// Must be after the eglMakeCurrent() so the renderer string is initialized.
1311
ANGLE_SKIP_TEST_IF(IsOpenGLES() && (IsAndroid() || IsWindows()));
1312
1313
glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
1314
glClear(GL_COLOR_BUFFER_BIT);
1315
ASSERT_GL_NO_ERROR();
1316
// Force the clear to be flushed
1317
EXPECT_PIXEL_COLOR_EQ(32, 32, GLColor::red);
1318
1319
// Clear to green, but don't read it back so the clear is deferred.
1320
glClearColor(GLColor::green.R, GLColor::green.G, GLColor::green.B, GLColor::green.A);
1321
glClear(GL_COLOR_BUFFER_BIT);
1322
ASSERT_GL_NO_ERROR();
1323
1324
// Blit from surface1 to surface2.
1325
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface2, surface1, mContext));
1326
glBlitFramebuffer(0, 0, 64, 64, 0, 0, 64, 64, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1327
ASSERT_GL_NO_ERROR();
1328
1329
// Confirm surface1 has the clear color.
1330
EXPECT_PIXEL_COLOR_EQ(32, 32, GLColor::green);
1331
1332
// Confirm surface2 has the blited clear color.
1333
EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, surface2, surface2, mContext));
1334
EXPECT_PIXEL_COLOR_EQ(32, 32, GLColor::green);
1335
1336
eglDestroySurface(mDisplay, surface1);
1337
eglDestroySurface(mDisplay, surface2);
1338
}
1339
1340
// Verify switching between a surface with robust resource init and one without still clears alpha.
1341
TEST_P(EGLSurfaceTest, RobustResourceInitAndEmulatedAlpha)
1342
{
1343
// http://anglebug.com/5279
1344
ANGLE_SKIP_TEST_IF(IsNVIDIA() && isGLRenderer() && IsLinux());
1345
1346
// http://anglebug.com/5280
1347
ANGLE_SKIP_TEST_IF(IsAndroid() && IsNexus5X() && isGLESRenderer());
1348
1349
initializeDisplay();
1350
ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
1351
1352
ANGLE_SKIP_TEST_IF(
1353
!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_robust_resource_initialization"));
1354
1355
// Initialize and draw red to a Surface with robust resource init enabled.
1356
constexpr EGLint kRGBAAttributes[] = {EGL_RED_SIZE, 8,
1357
EGL_GREEN_SIZE, 8,
1358
EGL_BLUE_SIZE, 8,
1359
EGL_ALPHA_SIZE, 8,
1360
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1361
EGL_NONE};
1362
1363
EGLint configCount = 0;
1364
EGLConfig rgbaConfig = nullptr;
1365
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, kRGBAAttributes, &rgbaConfig, 1, &configCount));
1366
ASSERT_EQ(configCount, 1);
1367
ASSERT_NE(rgbaConfig, nullptr);
1368
1369
std::vector<EGLint> robustInitAttribs;
1370
robustInitAttribs.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE);
1371
robustInitAttribs.push_back(EGL_TRUE);
1372
1373
initializeSurfaceWithAttribs(rgbaConfig, robustInitAttribs);
1374
ASSERT_EGL_SUCCESS();
1375
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
1376
1377
initializeSingleContext(&mContext);
1378
ASSERT_EGL_SUCCESS();
1379
ASSERT_NE(mContext, EGL_NO_CONTEXT);
1380
1381
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1382
ASSERT_EGL_SUCCESS();
1383
eglSwapBuffers(mDisplay, mWindowSurface);
1384
1385
// RGBA robust init setup complete. Draw red and verify.
1386
{
1387
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1388
glUseProgram(program);
1389
1390
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1391
ASSERT_GL_NO_ERROR();
1392
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1393
1394
eglSwapBuffers(mDisplay, mWindowSurface);
1395
}
1396
1397
tearDownContextAndSurface();
1398
1399
// Create second RGB surface with robust resource disabled.
1400
constexpr EGLint kRGBAttributes[] = {EGL_RED_SIZE, 8,
1401
EGL_GREEN_SIZE, 8,
1402
EGL_BLUE_SIZE, 8,
1403
EGL_ALPHA_SIZE, 0,
1404
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
1405
EGL_NONE};
1406
1407
configCount = 0;
1408
EGLConfig rgbConfig = nullptr;
1409
ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, kRGBAttributes, &rgbConfig, 1, &configCount));
1410
ASSERT_EQ(configCount, 1);
1411
ASSERT_NE(rgbConfig, nullptr);
1412
1413
initializeSurface(rgbConfig);
1414
ASSERT_EGL_SUCCESS();
1415
ASSERT_NE(mWindowSurface, EGL_NO_SURFACE);
1416
1417
initializeSingleContext(&mContext);
1418
ASSERT_EGL_SUCCESS();
1419
ASSERT_NE(mContext, EGL_NO_CONTEXT);
1420
1421
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1422
ASSERT_EGL_SUCCESS();
1423
1424
// RGB non-robust init setup complete. Draw red and verify.
1425
{
1426
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1427
glUseProgram(program);
1428
1429
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1430
ASSERT_GL_NO_ERROR();
1431
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1432
1433
eglSwapBuffers(mDisplay, mWindowSurface);
1434
}
1435
}
1436
1437
void EGLSurfaceTest::drawQuadThenTearDown()
1438
{
1439
initializeSingleContext(&mContext);
1440
1441
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
1442
ASSERT_EGL_SUCCESS();
1443
1444
{
1445
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1446
drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
1447
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1448
eglSwapBuffers(mDisplay, mWindowSurface);
1449
ASSERT_EGL_SUCCESS();
1450
}
1451
1452
tearDownContextAndSurface();
1453
}
1454
1455
// Tests the EGL_ANGLE_create_surface_swap_interval extension if available.
1456
TEST_P(EGLSurfaceTest, CreateSurfaceSwapIntervalANGLE)
1457
{
1458
initializeDisplay();
1459
ASSERT_NE(mDisplay, EGL_NO_DISPLAY);
1460
1461
mConfig = chooseDefaultConfig(true);
1462
ASSERT_NE(mConfig, nullptr);
1463
1464
if (IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_create_surface_swap_interval"))
1465
{
1466
// Test error conditions.
1467
EGLint minSwapInterval = 0;
1468
eglGetConfigAttrib(mDisplay, mConfig, EGL_MIN_SWAP_INTERVAL, &minSwapInterval);
1469
ASSERT_EGL_SUCCESS();
1470
1471
if (minSwapInterval > 0)
1472
{
1473
std::vector<EGLint> min1SwapAttribs = {EGL_SWAP_INTERVAL_ANGLE, minSwapInterval - 1};
1474
initializeWindowSurfaceWithAttribs(mConfig, min1SwapAttribs, EGL_BAD_ATTRIBUTE);
1475
}
1476
1477
EGLint maxSwapInterval = 0;
1478
eglGetConfigAttrib(mDisplay, mConfig, EGL_MAX_SWAP_INTERVAL, &maxSwapInterval);
1479
ASSERT_EGL_SUCCESS();
1480
1481
if (maxSwapInterval < std::numeric_limits<EGLint>::max())
1482
{
1483
std::vector<EGLint> max1SwapAttribs = {EGL_SWAP_INTERVAL_ANGLE, maxSwapInterval + 1};
1484
initializeWindowSurfaceWithAttribs(mConfig, max1SwapAttribs, EGL_BAD_ATTRIBUTE);
1485
}
1486
1487
// Test valid min/max usage.
1488
{
1489
std::vector<EGLint> minSwapAttribs = {EGL_SWAP_INTERVAL_ANGLE, minSwapInterval};
1490
initializeWindowSurfaceWithAttribs(mConfig, minSwapAttribs, EGL_SUCCESS);
1491
drawQuadThenTearDown();
1492
}
1493
1494
if (minSwapInterval != maxSwapInterval)
1495
{
1496
std::vector<EGLint> maxSwapAttribs = {EGL_SWAP_INTERVAL_ANGLE, maxSwapInterval};
1497
initializeWindowSurfaceWithAttribs(mConfig, maxSwapAttribs, EGL_SUCCESS);
1498
drawQuadThenTearDown();
1499
}
1500
}
1501
else
1502
{
1503
// Test extension unavailable error.
1504
std::vector<EGLint> swapInterval1Attribs = {EGL_SWAP_INTERVAL_ANGLE, 1};
1505
initializeWindowSurfaceWithAttribs(mConfig, swapInterval1Attribs, EGL_BAD_ATTRIBUTE);
1506
}
1507
}
1508
} // anonymous namespace
1509
1510
ANGLE_INSTANTIATE_TEST(EGLSurfaceTest,
1511
WithNoFixture(ES2_D3D9()),
1512
WithNoFixture(ES2_D3D11()),
1513
WithNoFixture(ES3_D3D11()),
1514
WithNoFixture(ES2_OPENGL()),
1515
WithNoFixture(ES3_OPENGL()),
1516
WithNoFixture(ES2_OPENGLES()),
1517
WithNoFixture(ES3_OPENGLES()),
1518
WithNoFixture(ES2_VULKAN()),
1519
WithNoFixture(ES3_VULKAN()),
1520
WithNoFixture(ES2_VULKAN_SWIFTSHADER()),
1521
WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
1522
1523
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLFloatSurfaceTest);
1524
ANGLE_INSTANTIATE_TEST(EGLFloatSurfaceTest,
1525
WithNoFixture(ES2_OPENGL()),
1526
WithNoFixture(ES3_OPENGL()),
1527
WithNoFixture(ES2_VULKAN()),
1528
WithNoFixture(ES3_VULKAN()));
1529
1530
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLSurfaceTest3);
1531
ANGLE_INSTANTIATE_TEST(EGLSurfaceTest3,
1532
WithNoFixture(ES3_D3D11()),
1533
WithNoFixture(ES3_OPENGLES()),
1534
WithNoFixture(ES3_VULKAN()),
1535
WithNoFixture(ES3_VULKAN_SWIFTSHADER()));
1536
1537
#if defined(ANGLE_ENABLE_D3D11)
1538
ANGLE_INSTANTIATE_TEST(EGLSurfaceTestD3D11, WithNoFixture(ES2_D3D11()), WithNoFixture(ES3_D3D11()));
1539
#endif
1540
1541