Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/tests/egl_tests/EGLSyncTest.cpp
1693 views
1
//
2
// Copyright 2019 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
// EGLSyncTest.cpp:
7
// Tests of EGL_KHR_fence_sync and EGL_KHR_wait_sync extensions.
8
9
#include <gtest/gtest.h>
10
11
#include "test_utils/ANGLETest.h"
12
#include "test_utils/angle_test_configs.h"
13
#include "util/EGLWindow.h"
14
15
using namespace angle;
16
17
class EGLSyncTest : public ANGLETest
18
{
19
protected:
20
bool hasFenceSyncExtension() const
21
{
22
return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_fence_sync");
23
}
24
bool hasWaitSyncExtension() const
25
{
26
return hasFenceSyncExtension() &&
27
IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_wait_sync");
28
}
29
bool hasGLSyncExtension() const { return IsGLExtensionEnabled("GL_OES_EGL_sync"); }
30
31
bool hasAndroidNativeFenceSyncExtension() const
32
{
33
return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
34
"EGL_ANDROID_native_fence_sync");
35
}
36
};
37
38
// Test error cases for all EGL_KHR_fence_sync functions
39
TEST_P(EGLSyncTest, FenceSyncErrors)
40
{
41
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
42
43
EGLDisplay display = getEGLWindow()->getDisplay();
44
45
// If the client API doesn't have the necessary extension, test that sync creation fails and
46
// ignore the rest of the tests.
47
if (!hasGLSyncExtension())
48
{
49
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
50
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
51
}
52
53
ANGLE_SKIP_TEST_IF(!hasGLSyncExtension());
54
55
EGLContext context = eglGetCurrentContext();
56
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
57
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
58
59
EXPECT_NE(context, EGL_NO_CONTEXT);
60
EXPECT_NE(drawSurface, EGL_NO_SURFACE);
61
EXPECT_NE(readSurface, EGL_NO_SURFACE);
62
63
// CreateSync with no attribute shouldn't cause an error
64
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
65
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
66
67
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
68
69
// CreateSync with empty attribute shouldn't cause an error
70
const EGLint emptyAttributes[] = {EGL_NONE};
71
sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, emptyAttributes);
72
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
73
74
// DestroySync generates BAD_PARAMETER if the sync is not valid
75
EXPECT_EGL_FALSE(eglDestroySyncKHR(display, reinterpret_cast<EGLSyncKHR>(20)));
76
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
77
78
// CreateSync generates BAD_DISPLAY if display is not valid
79
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(EGL_NO_DISPLAY, EGL_SYNC_FENCE_KHR, nullptr));
80
EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
81
82
// CreateSync generates BAD_ATTRIBUTE if attribute is neither nullptr nor empty.
83
const EGLint nonEmptyAttributes[] = {
84
EGL_CL_EVENT_HANDLE,
85
0,
86
EGL_NONE,
87
};
88
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nonEmptyAttributes));
89
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
90
91
// CreateSync generates BAD_ATTRIBUTE if type is not valid
92
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, 0, nullptr));
93
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
94
95
// CreateSync generates BAD_MATCH if no context is current
96
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
97
EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
98
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
99
eglMakeCurrent(display, drawSurface, readSurface, context);
100
101
// ClientWaitSync generates EGL_BAD_PARAMETER if the sync object is not valid
102
EXPECT_EGL_FALSE(eglClientWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(30), 0, 0));
103
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
104
105
// GetSyncAttrib generates EGL_BAD_PARAMETER if the sync object is not valid, and value is not
106
// modified
107
constexpr EGLint kSentinelAttribValue = 123456789;
108
EGLint attribValue = kSentinelAttribValue;
109
EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, reinterpret_cast<EGLSyncKHR>(40),
110
EGL_SYNC_TYPE_KHR, &attribValue));
111
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
112
EXPECT_EQ(attribValue, kSentinelAttribValue);
113
114
// GetSyncAttrib generates EGL_BAD_ATTRIBUTE if the attribute is not valid, and value is not
115
// modified
116
EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, sync, EGL_CL_EVENT_HANDLE, &attribValue));
117
EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
118
EXPECT_EQ(attribValue, kSentinelAttribValue);
119
120
// GetSyncAttrib generates EGL_BAD_MATCH if the attribute is valid for sync, but not the
121
// particular sync type. We don't have such a case at the moment.
122
123
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
124
}
125
126
// Test error cases for all EGL_KHR_wait_sync functions
127
TEST_P(EGLSyncTest, WaitSyncErrors)
128
{
129
// The client API that shows support for eglWaitSyncKHR is the same as the one required for
130
// eglCreateSyncKHR. As such, there is no way to create a sync and not be able to wait on it.
131
// This would have created an EGL_BAD_MATCH error.
132
ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
133
134
EGLDisplay display = getEGLWindow()->getDisplay();
135
EGLContext context = eglGetCurrentContext();
136
EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
137
EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
138
139
EXPECT_NE(context, EGL_NO_CONTEXT);
140
EXPECT_NE(drawSurface, EGL_NO_SURFACE);
141
EXPECT_NE(readSurface, EGL_NO_SURFACE);
142
143
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
144
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
145
146
// WaitSync generates BAD_MATCH if no context is current
147
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
148
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 0));
149
EXPECT_EGL_ERROR(EGL_BAD_MATCH);
150
eglMakeCurrent(display, drawSurface, readSurface, context);
151
152
// WaitSync generates BAD_PARAMETER if the sync is not valid
153
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(20), 0));
154
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
155
156
// WaitSync generates BAD_PARAMETER if flags is non-zero
157
EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 1));
158
EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
159
160
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
161
}
162
163
// Test usage of eglGetSyncAttribKHR
164
TEST_P(EGLSyncTest, GetSyncAttrib)
165
{
166
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
167
168
EGLDisplay display = getEGLWindow()->getDisplay();
169
170
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
171
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
172
173
// Fence sync attributes are:
174
//
175
// EGL_SYNC_TYPE_KHR: EGL_SYNC_FENCE_KHR
176
// EGL_SYNC_STATUS_KHR: EGL_UNSIGNALED_KHR or EGL_SIGNALED_KHR
177
// EGL_SYNC_CONDITION_KHR: EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
178
179
constexpr EGLint kSentinelAttribValue = 123456789;
180
EGLint attribValue = kSentinelAttribValue;
181
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_TYPE_KHR, &attribValue));
182
EXPECT_EQ(attribValue, EGL_SYNC_FENCE_KHR);
183
184
attribValue = kSentinelAttribValue;
185
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_CONDITION_KHR, &attribValue));
186
EXPECT_EQ(attribValue, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR);
187
188
attribValue = kSentinelAttribValue;
189
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &attribValue));
190
191
// Hack around EXPECT_* not having an "either this or that" variant:
192
if (attribValue != EGL_SIGNALED_KHR)
193
{
194
EXPECT_EQ(attribValue, EGL_UNSIGNALED_KHR);
195
}
196
197
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
198
}
199
200
// Test that basic usage works and doesn't generate errors or crash
201
TEST_P(EGLSyncTest, BasicOperations)
202
{
203
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
204
205
EGLDisplay display = getEGLWindow()->getDisplay();
206
207
EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
208
EXPECT_NE(sync, EGL_NO_SYNC_KHR);
209
210
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
211
212
glClear(GL_COLOR_BUFFER_BIT);
213
EXPECT_EGL_TRUE(eglWaitSyncKHR(display, sync, 0));
214
215
glFlush();
216
217
glClear(GL_COLOR_BUFFER_BIT);
218
219
// Don't wait forever to make sure the test terminates
220
constexpr GLuint64 kTimeout = 1'000'000'000; // 1 second
221
EGLint value = 0;
222
ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR,
223
eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, kTimeout));
224
225
for (size_t i = 0; i < 20; i++)
226
{
227
glClear(GL_COLOR_BUFFER_BIT);
228
EXPECT_EQ(
229
EGL_CONDITION_SATISFIED_KHR,
230
eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR));
231
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &value));
232
EXPECT_EQ(value, EGL_SIGNALED_KHR);
233
}
234
235
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
236
}
237
238
// Test eglWaitClient api
239
TEST_P(EGLSyncTest, WaitClient)
240
{
241
// Clear to red color
242
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
243
244
glClear(GL_COLOR_BUFFER_BIT);
245
EXPECT_EGL_TRUE(eglWaitClient());
246
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
247
248
EGLDisplay display = getEGLWindow()->getDisplay();
249
EGLContext context = getEGLWindow()->getContext();
250
EGLSurface surface = getEGLWindow()->getSurface();
251
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
252
EXPECT_EGL_TRUE(eglWaitClient());
253
eglMakeCurrent(display, surface, surface, context);
254
}
255
256
// Test eglWaitGL api
257
TEST_P(EGLSyncTest, WaitGL)
258
{
259
// Clear to red color
260
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
261
262
glClear(GL_COLOR_BUFFER_BIT);
263
EXPECT_EGL_TRUE(eglWaitGL());
264
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
265
266
EGLDisplay display = getEGLWindow()->getDisplay();
267
EGLContext context = getEGLWindow()->getContext();
268
EGLSurface surface = getEGLWindow()->getSurface();
269
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
270
EXPECT_EGL_TRUE(eglWaitGL());
271
eglMakeCurrent(display, surface, surface, context);
272
}
273
274
// Test eglWaitNative api
275
TEST_P(EGLSyncTest, WaitNative)
276
{
277
// Clear to red color
278
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
279
280
glClear(GL_COLOR_BUFFER_BIT);
281
EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
282
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
283
284
EGLDisplay display = getEGLWindow()->getDisplay();
285
EGLContext context = getEGLWindow()->getContext();
286
EGLSurface surface = getEGLWindow()->getSurface();
287
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
288
EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
289
eglMakeCurrent(display, surface, surface, context);
290
}
291
292
// Verify eglDupNativeFence for EGL_ANDROID_native_fence_sync
293
TEST_P(EGLSyncTest, AndroidNativeFence_DupNativeFenceFD)
294
{
295
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
296
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
297
ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
298
299
EGLDisplay display = getEGLWindow()->getDisplay();
300
301
// We can ClientWait on this
302
EGLSyncKHR syncWithGeneratedFD =
303
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
304
EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
305
306
int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
307
EXPECT_EGL_SUCCESS();
308
309
// Clean up created objects.
310
if (fd != EGL_NO_NATIVE_FENCE_FD_ANDROID)
311
{
312
close(fd);
313
}
314
315
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
316
}
317
318
// Verify CreateSync and ClientWait for EGL_ANDROID_native_fence_sync
319
TEST_P(EGLSyncTest, AndroidNativeFence_ClientWait)
320
{
321
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
322
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
323
ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
324
325
EGLint value = 0;
326
EGLDisplay display = getEGLWindow()->getDisplay();
327
328
// We can ClientWait on this
329
EGLSyncKHR syncWithGeneratedFD =
330
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
331
EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
332
333
// Create work to do
334
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
335
glClear(GL_COLOR_BUFFER_BIT);
336
glFlush();
337
338
// Wait for draw to complete
339
EXPECT_EQ(EGL_CONDITION_SATISFIED,
340
eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
341
1000000000));
342
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
343
EXPECT_EQ(value, EGL_SIGNALED_KHR);
344
345
// Clean up created objects.
346
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
347
}
348
349
// Verify WaitSync with EGL_ANDROID_native_fence_sync
350
// Simulate passing FDs across processes by passing across Contexts.
351
TEST_P(EGLSyncTest, AndroidNativeFence_WaitSync)
352
{
353
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
354
ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
355
ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
356
357
EGLint value = 0;
358
EGLDisplay display = getEGLWindow()->getDisplay();
359
EGLSurface surface = getEGLWindow()->getSurface();
360
361
/*- First Context ------------------------*/
362
363
// We can ClientWait on this
364
EGLSyncKHR syncWithGeneratedFD =
365
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
366
EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
367
368
int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
369
EXPECT_EGL_SUCCESS(); // Can return -1 (when signaled) or valid FD.
370
371
// Create work to do
372
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
373
glClear(GL_COLOR_BUFFER_BIT);
374
glFlush();
375
376
/*- Second Context ------------------------*/
377
if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
378
{
379
EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
380
381
EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT);
382
EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
383
384
// We can eglWaitSync on this - import FD from first sync.
385
EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
386
EGLSyncKHR syncWithDupFD =
387
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
388
EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);
389
390
// Second draw waits for first to complete. May already be signaled - ignore error.
391
if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
392
{
393
// Create work to do
394
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
395
glClear(GL_COLOR_BUFFER_BIT);
396
glFlush();
397
}
398
399
// Wait for second draw to complete
400
EXPECT_EQ(EGL_CONDITION_SATISFIED,
401
eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
402
1000000000));
403
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
404
EXPECT_EQ(value, EGL_SIGNALED_KHR);
405
406
// Reset to default context and surface.
407
EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
408
EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));
409
410
// Clean up created objects.
411
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
412
EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
413
}
414
415
// Wait for first draw to complete
416
EXPECT_EQ(EGL_CONDITION_SATISFIED,
417
eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
418
1000000000));
419
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
420
EXPECT_EQ(value, EGL_SIGNALED_KHR);
421
422
// Clean up created objects.
423
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
424
}
425
426
// Verify EGL_ANDROID_native_fence_sync
427
// Simulate passing FDs across processes by passing across Contexts.
428
TEST_P(EGLSyncTest, AndroidNativeFence_withFences)
429
{
430
ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
431
ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
432
ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
433
434
EGLint value = 0;
435
EGLDisplay display = getEGLWindow()->getDisplay();
436
EGLSurface surface = getEGLWindow()->getSurface();
437
438
/*- First Context ------------------------*/
439
440
// Extra fence syncs to ensure that Fence and Android Native fences work together
441
EGLSyncKHR syncFence1 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
442
EXPECT_NE(syncFence1, EGL_NO_SYNC_KHR);
443
444
// We can ClientWait on this
445
EGLSyncKHR syncWithGeneratedFD =
446
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
447
EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
448
449
int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
450
EXPECT_EGL_SUCCESS(); // Can return -1 (when signaled) or valid FD.
451
452
EGLSyncKHR syncFence2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
453
EXPECT_NE(syncFence2, EGL_NO_SYNC_KHR);
454
455
// Create work to do
456
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
457
glClear(GL_COLOR_BUFFER_BIT);
458
glFlush();
459
460
/*- Second Context ------------------------*/
461
if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
462
{
463
EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
464
465
EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT);
466
EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
467
468
// check that Fence and Android fences work together
469
EGLSyncKHR syncFence3 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
470
EXPECT_NE(syncFence3, EGL_NO_SYNC_KHR);
471
472
// We can eglWaitSync on this
473
EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
474
EGLSyncKHR syncWithDupFD =
475
eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
476
EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);
477
478
EGLSyncKHR syncFence4 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
479
EXPECT_NE(syncFence4, EGL_NO_SYNC_KHR);
480
481
// Second draw waits for first to complete. May already be signaled - ignore error.
482
if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
483
{
484
// Create work to do
485
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
486
glClear(GL_COLOR_BUFFER_BIT);
487
glFlush();
488
}
489
490
// Wait for second draw to complete
491
EXPECT_EQ(EGL_CONDITION_SATISFIED,
492
eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
493
1000000000));
494
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
495
EXPECT_EQ(value, EGL_SIGNALED_KHR);
496
497
// Reset to default context and surface.
498
EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
499
EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));
500
501
// Clean up created objects.
502
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence3));
503
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence4));
504
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
505
EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
506
}
507
508
// Wait for first draw to complete
509
EXPECT_EQ(EGL_CONDITION_SATISFIED,
510
eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
511
1000000000));
512
EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
513
EXPECT_EQ(value, EGL_SIGNALED_KHR);
514
515
// Clean up created objects.
516
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence1));
517
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence2));
518
EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
519
}
520
521
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EGLSyncTest);
522
523