1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // EGLSyncTest.cpp:
7*8975f5c5SAndroid Build Coastguard Worker // Tests of EGL_KHR_fence_sync and EGL_KHR_wait_sync extensions.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include <gtest/gtest.h>
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/angle_test_configs.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/EGLWindow.h"
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker class EGLSyncTest : public ANGLETest<>
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker protected:
hasFenceSyncExtension() const21*8975f5c5SAndroid Build Coastguard Worker bool hasFenceSyncExtension() const
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_fence_sync");
24*8975f5c5SAndroid Build Coastguard Worker }
hasWaitSyncExtension() const25*8975f5c5SAndroid Build Coastguard Worker bool hasWaitSyncExtension() const
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker return hasFenceSyncExtension() &&
28*8975f5c5SAndroid Build Coastguard Worker IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_wait_sync");
29*8975f5c5SAndroid Build Coastguard Worker }
hasGLSyncExtension() const30*8975f5c5SAndroid Build Coastguard Worker bool hasGLSyncExtension() const { return IsGLExtensionEnabled("GL_OES_EGL_sync"); }
31*8975f5c5SAndroid Build Coastguard Worker
hasAndroidNativeFenceSyncExtension() const32*8975f5c5SAndroid Build Coastguard Worker bool hasAndroidNativeFenceSyncExtension() const
33*8975f5c5SAndroid Build Coastguard Worker {
34*8975f5c5SAndroid Build Coastguard Worker return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
35*8975f5c5SAndroid Build Coastguard Worker "EGL_ANDROID_native_fence_sync");
36*8975f5c5SAndroid Build Coastguard Worker }
37*8975f5c5SAndroid Build Coastguard Worker };
38*8975f5c5SAndroid Build Coastguard Worker
39*8975f5c5SAndroid Build Coastguard Worker // Test error cases for all EGL_KHR_fence_sync functions
TEST_P(EGLSyncTest,FenceSyncErrors)40*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, FenceSyncErrors)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
43*8975f5c5SAndroid Build Coastguard Worker
44*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker // If the client API doesn't have the necessary extension, test that sync creation fails and
47*8975f5c5SAndroid Build Coastguard Worker // ignore the rest of the tests.
48*8975f5c5SAndroid Build Coastguard Worker if (!hasGLSyncExtension())
49*8975f5c5SAndroid Build Coastguard Worker {
50*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
51*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_MATCH);
52*8975f5c5SAndroid Build Coastguard Worker }
53*8975f5c5SAndroid Build Coastguard Worker
54*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasGLSyncExtension());
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker EGLContext context = eglGetCurrentContext();
57*8975f5c5SAndroid Build Coastguard Worker EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
58*8975f5c5SAndroid Build Coastguard Worker EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
59*8975f5c5SAndroid Build Coastguard Worker
60*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(context, EGL_NO_CONTEXT);
61*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(drawSurface, EGL_NO_SURFACE);
62*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(readSurface, EGL_NO_SURFACE);
63*8975f5c5SAndroid Build Coastguard Worker
64*8975f5c5SAndroid Build Coastguard Worker // CreateSync with no attribute shouldn't cause an error
65*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
66*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker // CreateSync with empty attribute shouldn't cause an error
71*8975f5c5SAndroid Build Coastguard Worker const EGLint emptyAttributes[] = {EGL_NONE};
72*8975f5c5SAndroid Build Coastguard Worker sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, emptyAttributes);
73*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker // DestroySync generates BAD_PARAMETER if the sync is not valid
76*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglDestroySyncKHR(display, reinterpret_cast<EGLSyncKHR>(20)));
77*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
78*8975f5c5SAndroid Build Coastguard Worker
79*8975f5c5SAndroid Build Coastguard Worker // CreateSync generates BAD_DISPLAY if display is not valid
80*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(EGL_NO_DISPLAY, EGL_SYNC_FENCE_KHR, nullptr));
81*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);
82*8975f5c5SAndroid Build Coastguard Worker
83*8975f5c5SAndroid Build Coastguard Worker // CreateSync generates BAD_ATTRIBUTE if attribute is neither nullptr nor empty.
84*8975f5c5SAndroid Build Coastguard Worker const EGLint nonEmptyAttributes[] = {
85*8975f5c5SAndroid Build Coastguard Worker EGL_CL_EVENT_HANDLE,
86*8975f5c5SAndroid Build Coastguard Worker 0,
87*8975f5c5SAndroid Build Coastguard Worker EGL_NONE,
88*8975f5c5SAndroid Build Coastguard Worker };
89*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nonEmptyAttributes));
90*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker // CreateSync generates BAD_ATTRIBUTE if type is not valid
93*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, 0, nullptr));
94*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker // CreateSync generates BAD_MATCH if no context is current
97*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
98*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
99*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_MATCH);
100*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, drawSurface, readSurface, context);
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker // ClientWaitSync generates EGL_BAD_PARAMETER if the sync object is not valid
103*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglClientWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(30), 0, 0));
104*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
105*8975f5c5SAndroid Build Coastguard Worker
106*8975f5c5SAndroid Build Coastguard Worker // GetSyncAttrib generates EGL_BAD_PARAMETER if the sync object is not valid, and value is not
107*8975f5c5SAndroid Build Coastguard Worker // modified
108*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kSentinelAttribValue = 123456789;
109*8975f5c5SAndroid Build Coastguard Worker EGLint attribValue = kSentinelAttribValue;
110*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, reinterpret_cast<EGLSyncKHR>(40),
111*8975f5c5SAndroid Build Coastguard Worker EGL_SYNC_TYPE_KHR, &attribValue));
112*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
113*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(attribValue, kSentinelAttribValue);
114*8975f5c5SAndroid Build Coastguard Worker
115*8975f5c5SAndroid Build Coastguard Worker // GetSyncAttrib generates EGL_BAD_ATTRIBUTE if the attribute is not valid, and value is not
116*8975f5c5SAndroid Build Coastguard Worker // modified
117*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, sync, EGL_CL_EVENT_HANDLE, &attribValue));
118*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
119*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(attribValue, kSentinelAttribValue);
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker // GetSyncAttrib generates EGL_BAD_MATCH if the attribute is valid for sync, but not the
122*8975f5c5SAndroid Build Coastguard Worker // particular sync type. We don't have such a case at the moment.
123*8975f5c5SAndroid Build Coastguard Worker
124*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
125*8975f5c5SAndroid Build Coastguard Worker }
126*8975f5c5SAndroid Build Coastguard Worker
127*8975f5c5SAndroid Build Coastguard Worker // Test error cases for all EGL_KHR_wait_sync functions
TEST_P(EGLSyncTest,WaitSyncErrors)128*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, WaitSyncErrors)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker // The client API that shows support for eglWaitSyncKHR is the same as the one required for
131*8975f5c5SAndroid Build Coastguard Worker // eglCreateSyncKHR. As such, there is no way to create a sync and not be able to wait on it.
132*8975f5c5SAndroid Build Coastguard Worker // This would have created an EGL_BAD_MATCH error.
133*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
134*8975f5c5SAndroid Build Coastguard Worker
135*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
136*8975f5c5SAndroid Build Coastguard Worker EGLContext context = eglGetCurrentContext();
137*8975f5c5SAndroid Build Coastguard Worker EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
138*8975f5c5SAndroid Build Coastguard Worker EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);
139*8975f5c5SAndroid Build Coastguard Worker
140*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(context, EGL_NO_CONTEXT);
141*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(drawSurface, EGL_NO_SURFACE);
142*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(readSurface, EGL_NO_SURFACE);
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
145*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Worker // WaitSync generates BAD_MATCH if no context is current
148*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
149*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 0));
150*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_MATCH);
151*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, drawSurface, readSurface, context);
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker // WaitSync generates BAD_PARAMETER if the sync is not valid
154*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(20), 0));
155*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker // WaitSync generates BAD_PARAMETER if flags is non-zero
158*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 1));
159*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
160*8975f5c5SAndroid Build Coastguard Worker
161*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker
164*8975f5c5SAndroid Build Coastguard Worker // Test usage of eglGetSyncAttribKHR
TEST_P(EGLSyncTest,GetSyncAttrib)165*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, GetSyncAttrib)
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
170*8975f5c5SAndroid Build Coastguard Worker
171*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
172*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
173*8975f5c5SAndroid Build Coastguard Worker
174*8975f5c5SAndroid Build Coastguard Worker // Fence sync attributes are:
175*8975f5c5SAndroid Build Coastguard Worker //
176*8975f5c5SAndroid Build Coastguard Worker // EGL_SYNC_TYPE_KHR: EGL_SYNC_FENCE_KHR
177*8975f5c5SAndroid Build Coastguard Worker // EGL_SYNC_STATUS_KHR: EGL_UNSIGNALED_KHR or EGL_SIGNALED_KHR
178*8975f5c5SAndroid Build Coastguard Worker // EGL_SYNC_CONDITION_KHR: EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR
179*8975f5c5SAndroid Build Coastguard Worker
180*8975f5c5SAndroid Build Coastguard Worker constexpr EGLint kSentinelAttribValue = 123456789;
181*8975f5c5SAndroid Build Coastguard Worker EGLint attribValue = kSentinelAttribValue;
182*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_TYPE_KHR, &attribValue));
183*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(attribValue, EGL_SYNC_FENCE_KHR);
184*8975f5c5SAndroid Build Coastguard Worker
185*8975f5c5SAndroid Build Coastguard Worker attribValue = kSentinelAttribValue;
186*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_CONDITION_KHR, &attribValue));
187*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(attribValue, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR);
188*8975f5c5SAndroid Build Coastguard Worker
189*8975f5c5SAndroid Build Coastguard Worker attribValue = kSentinelAttribValue;
190*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &attribValue));
191*8975f5c5SAndroid Build Coastguard Worker
192*8975f5c5SAndroid Build Coastguard Worker // Hack around EXPECT_* not having an "either this or that" variant:
193*8975f5c5SAndroid Build Coastguard Worker if (attribValue != EGL_SIGNALED_KHR)
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(attribValue, EGL_UNSIGNALED_KHR);
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker
201*8975f5c5SAndroid Build Coastguard Worker // Test that basic usage works and doesn't generate errors or crash
TEST_P(EGLSyncTest,BasicOperations)202*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, BasicOperations)
203*8975f5c5SAndroid Build Coastguard Worker {
204*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
207*8975f5c5SAndroid Build Coastguard Worker
208*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
209*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
210*8975f5c5SAndroid Build Coastguard Worker
211*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
214*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitSyncKHR(display, sync, 0));
215*8975f5c5SAndroid Build Coastguard Worker
216*8975f5c5SAndroid Build Coastguard Worker glFlush();
217*8975f5c5SAndroid Build Coastguard Worker
218*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
219*8975f5c5SAndroid Build Coastguard Worker
220*8975f5c5SAndroid Build Coastguard Worker // Don't wait forever to make sure the test terminates
221*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint64 kTimeout = 1'000'000'000; // 1 second
222*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
223*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR,
224*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, kTimeout));
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 20; i++)
227*8975f5c5SAndroid Build Coastguard Worker {
228*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
229*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(
230*8975f5c5SAndroid Build Coastguard Worker EGL_CONDITION_SATISFIED_KHR,
231*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR));
232*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &value));
233*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
234*8975f5c5SAndroid Build Coastguard Worker }
235*8975f5c5SAndroid Build Coastguard Worker
236*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
237*8975f5c5SAndroid Build Coastguard Worker }
238*8975f5c5SAndroid Build Coastguard Worker
239*8975f5c5SAndroid Build Coastguard Worker // Test that eglClientWaitSync* APIs work.
TEST_P(EGLSyncTest,EglClientWaitSync)240*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, EglClientWaitSync)
241*8975f5c5SAndroid Build Coastguard Worker {
242*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
243*8975f5c5SAndroid Build Coastguard Worker
244*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
245*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
246*8975f5c5SAndroid Build Coastguard Worker
247*8975f5c5SAndroid Build Coastguard Worker // Test eglClientWaitSyncKHR
248*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; i++)
249*8975f5c5SAndroid Build Coastguard Worker {
250*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
251*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
252*8975f5c5SAndroid Build Coastguard Worker drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
253*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
254*8975f5c5SAndroid Build Coastguard Worker
255*8975f5c5SAndroid Build Coastguard Worker // Don't wait forever to make sure the test terminates
256*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint64 kTimeout = 1'000'000'000; // 1 second
257*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR clientWaitSync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
258*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(clientWaitSync, EGL_NO_SYNC_KHR);
259*8975f5c5SAndroid Build Coastguard Worker
260*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR,
261*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, clientWaitSync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
262*8975f5c5SAndroid Build Coastguard Worker kTimeout));
263*8975f5c5SAndroid Build Coastguard Worker
264*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, clientWaitSync));
265*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
266*8975f5c5SAndroid Build Coastguard Worker }
267*8975f5c5SAndroid Build Coastguard Worker
268*8975f5c5SAndroid Build Coastguard Worker // Test eglClientWaitSync
269*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 5; i++)
270*8975f5c5SAndroid Build Coastguard Worker {
271*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
272*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
273*8975f5c5SAndroid Build Coastguard Worker drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
274*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
275*8975f5c5SAndroid Build Coastguard Worker
276*8975f5c5SAndroid Build Coastguard Worker // Don't wait forever to make sure the test terminates
277*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint64 kTimeout = 1'000'000'000; // 1 second
278*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR clientWaitSync = eglCreateSync(display, EGL_SYNC_FENCE, nullptr);
279*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(clientWaitSync, EGL_NO_SYNC);
280*8975f5c5SAndroid Build Coastguard Worker
281*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(
282*8975f5c5SAndroid Build Coastguard Worker EGL_CONDITION_SATISFIED,
283*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSync(display, clientWaitSync, EGL_SYNC_FLUSH_COMMANDS_BIT, kTimeout));
284*8975f5c5SAndroid Build Coastguard Worker
285*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySync(display, clientWaitSync));
286*8975f5c5SAndroid Build Coastguard Worker ASSERT_EGL_SUCCESS();
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker }
289*8975f5c5SAndroid Build Coastguard Worker
290*8975f5c5SAndroid Build Coastguard Worker // Test eglWaitClient api
TEST_P(EGLSyncTest,WaitClient)291*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, WaitClient)
292*8975f5c5SAndroid Build Coastguard Worker {
293*8975f5c5SAndroid Build Coastguard Worker // Clear to red color
294*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
295*8975f5c5SAndroid Build Coastguard Worker
296*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
297*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitClient());
298*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
299*8975f5c5SAndroid Build Coastguard Worker
300*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
301*8975f5c5SAndroid Build Coastguard Worker EGLContext context = getEGLWindow()->getContext();
302*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = getEGLWindow()->getSurface();
303*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
304*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitClient());
305*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, surface, surface, context);
306*8975f5c5SAndroid Build Coastguard Worker }
307*8975f5c5SAndroid Build Coastguard Worker
308*8975f5c5SAndroid Build Coastguard Worker // Test eglWaitGL api
TEST_P(EGLSyncTest,WaitGL)309*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, WaitGL)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker // Clear to red color
312*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
313*8975f5c5SAndroid Build Coastguard Worker
314*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
315*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitGL());
316*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
317*8975f5c5SAndroid Build Coastguard Worker
318*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
319*8975f5c5SAndroid Build Coastguard Worker EGLContext context = getEGLWindow()->getContext();
320*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = getEGLWindow()->getSurface();
321*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
322*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitGL());
323*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, surface, surface, context);
324*8975f5c5SAndroid Build Coastguard Worker }
325*8975f5c5SAndroid Build Coastguard Worker
326*8975f5c5SAndroid Build Coastguard Worker // Test eglWaitNative api
TEST_P(EGLSyncTest,WaitNative)327*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, WaitNative)
328*8975f5c5SAndroid Build Coastguard Worker {
329*8975f5c5SAndroid Build Coastguard Worker // Clear to red color
330*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
331*8975f5c5SAndroid Build Coastguard Worker
332*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
333*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
334*8975f5c5SAndroid Build Coastguard Worker EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
335*8975f5c5SAndroid Build Coastguard Worker
336*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
337*8975f5c5SAndroid Build Coastguard Worker EGLContext context = getEGLWindow()->getContext();
338*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = getEGLWindow()->getSurface();
339*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
340*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
341*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, surface, surface, context);
342*8975f5c5SAndroid Build Coastguard Worker }
343*8975f5c5SAndroid Build Coastguard Worker
344*8975f5c5SAndroid Build Coastguard Worker // Verify eglDupNativeFence for EGL_ANDROID_native_fence_sync
TEST_P(EGLSyncTest,AndroidNativeFence_DupNativeFenceFD)345*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_DupNativeFenceFD)
346*8975f5c5SAndroid Build Coastguard Worker {
347*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
348*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
349*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
350*8975f5c5SAndroid Build Coastguard Worker
351*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
352*8975f5c5SAndroid Build Coastguard Worker
353*8975f5c5SAndroid Build Coastguard Worker // We can ClientWait on this
354*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
355*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
356*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
357*8975f5c5SAndroid Build Coastguard Worker
358*8975f5c5SAndroid Build Coastguard Worker int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
359*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_SUCCESS();
360*8975f5c5SAndroid Build Coastguard Worker
361*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
362*8975f5c5SAndroid Build Coastguard Worker if (fd != EGL_NO_NATIVE_FENCE_FD_ANDROID)
363*8975f5c5SAndroid Build Coastguard Worker {
364*8975f5c5SAndroid Build Coastguard Worker close(fd);
365*8975f5c5SAndroid Build Coastguard Worker }
366*8975f5c5SAndroid Build Coastguard Worker
367*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
368*8975f5c5SAndroid Build Coastguard Worker }
369*8975f5c5SAndroid Build Coastguard Worker
370*8975f5c5SAndroid Build Coastguard Worker // Verify CreateSync and ClientWait for EGL_ANDROID_native_fence_sync
TEST_P(EGLSyncTest,AndroidNativeFence_ClientWait)371*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_ClientWait)
372*8975f5c5SAndroid Build Coastguard Worker {
373*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
374*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
375*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
376*8975f5c5SAndroid Build Coastguard Worker
377*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
378*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
379*8975f5c5SAndroid Build Coastguard Worker
380*8975f5c5SAndroid Build Coastguard Worker // We can ClientWait on this
381*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
382*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
383*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
384*8975f5c5SAndroid Build Coastguard Worker
385*8975f5c5SAndroid Build Coastguard Worker // Create work to do
386*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
387*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
388*8975f5c5SAndroid Build Coastguard Worker glFlush();
389*8975f5c5SAndroid Build Coastguard Worker
390*8975f5c5SAndroid Build Coastguard Worker // Wait for draw to complete
391*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
392*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
393*8975f5c5SAndroid Build Coastguard Worker 1'000'000'000));
394*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
395*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
396*8975f5c5SAndroid Build Coastguard Worker
397*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
398*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
399*8975f5c5SAndroid Build Coastguard Worker }
400*8975f5c5SAndroid Build Coastguard Worker
401*8975f5c5SAndroid Build Coastguard Worker // Verify WaitSync with EGL_ANDROID_native_fence_sync
402*8975f5c5SAndroid Build Coastguard Worker // Simulate passing FDs across processes by passing across Contexts.
TEST_P(EGLSyncTest,AndroidNativeFence_WaitSync)403*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_WaitSync)
404*8975f5c5SAndroid Build Coastguard Worker {
405*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
406*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
407*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
408*8975f5c5SAndroid Build Coastguard Worker
409*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
410*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
411*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = getEGLWindow()->getSurface();
412*8975f5c5SAndroid Build Coastguard Worker
413*8975f5c5SAndroid Build Coastguard Worker /*- First Context ------------------------*/
414*8975f5c5SAndroid Build Coastguard Worker
415*8975f5c5SAndroid Build Coastguard Worker // We can ClientWait on this
416*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
417*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
418*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
419*8975f5c5SAndroid Build Coastguard Worker
420*8975f5c5SAndroid Build Coastguard Worker int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
421*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_SUCCESS(); // Can return -1 (when signaled) or valid FD.
422*8975f5c5SAndroid Build Coastguard Worker
423*8975f5c5SAndroid Build Coastguard Worker // Create work to do
424*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
425*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
426*8975f5c5SAndroid Build Coastguard Worker glFlush();
427*8975f5c5SAndroid Build Coastguard Worker
428*8975f5c5SAndroid Build Coastguard Worker /*- Second Context ------------------------*/
429*8975f5c5SAndroid Build Coastguard Worker if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
430*8975f5c5SAndroid Build Coastguard Worker {
431*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
432*8975f5c5SAndroid Build Coastguard Worker
433*8975f5c5SAndroid Build Coastguard Worker EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT, nullptr);
434*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
435*8975f5c5SAndroid Build Coastguard Worker
436*8975f5c5SAndroid Build Coastguard Worker // We can eglWaitSync on this - import FD from first sync.
437*8975f5c5SAndroid Build Coastguard Worker EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
438*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithDupFD =
439*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
440*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);
441*8975f5c5SAndroid Build Coastguard Worker
442*8975f5c5SAndroid Build Coastguard Worker // Second draw waits for first to complete. May already be signaled - ignore error.
443*8975f5c5SAndroid Build Coastguard Worker if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
444*8975f5c5SAndroid Build Coastguard Worker {
445*8975f5c5SAndroid Build Coastguard Worker // Create work to do
446*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
447*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
448*8975f5c5SAndroid Build Coastguard Worker glFlush();
449*8975f5c5SAndroid Build Coastguard Worker }
450*8975f5c5SAndroid Build Coastguard Worker
451*8975f5c5SAndroid Build Coastguard Worker // Wait for second draw to complete
452*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
453*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
454*8975f5c5SAndroid Build Coastguard Worker 1000000000));
455*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
456*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
457*8975f5c5SAndroid Build Coastguard Worker
458*8975f5c5SAndroid Build Coastguard Worker // Reset to default context and surface.
459*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
460*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));
461*8975f5c5SAndroid Build Coastguard Worker
462*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
463*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
464*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
465*8975f5c5SAndroid Build Coastguard Worker }
466*8975f5c5SAndroid Build Coastguard Worker
467*8975f5c5SAndroid Build Coastguard Worker // Wait for first draw to complete
468*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
469*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
470*8975f5c5SAndroid Build Coastguard Worker 1000000000));
471*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
472*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
473*8975f5c5SAndroid Build Coastguard Worker
474*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
475*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
476*8975f5c5SAndroid Build Coastguard Worker }
477*8975f5c5SAndroid Build Coastguard Worker
478*8975f5c5SAndroid Build Coastguard Worker // Verify EGL_ANDROID_native_fence_sync
479*8975f5c5SAndroid Build Coastguard Worker // Simulate passing FDs across processes by passing across Contexts.
TEST_P(EGLSyncTest,AndroidNativeFence_withFences)480*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_withFences)
481*8975f5c5SAndroid Build Coastguard Worker {
482*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
483*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
484*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
485*8975f5c5SAndroid Build Coastguard Worker
486*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
487*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
488*8975f5c5SAndroid Build Coastguard Worker EGLSurface surface = getEGLWindow()->getSurface();
489*8975f5c5SAndroid Build Coastguard Worker
490*8975f5c5SAndroid Build Coastguard Worker /*- First Context ------------------------*/
491*8975f5c5SAndroid Build Coastguard Worker
492*8975f5c5SAndroid Build Coastguard Worker // Extra fence syncs to ensure that Fence and Android Native fences work together
493*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncFence1 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
494*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncFence1, EGL_NO_SYNC_KHR);
495*8975f5c5SAndroid Build Coastguard Worker
496*8975f5c5SAndroid Build Coastguard Worker // We can ClientWait on this
497*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
498*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
499*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
500*8975f5c5SAndroid Build Coastguard Worker
501*8975f5c5SAndroid Build Coastguard Worker int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
502*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_SUCCESS(); // Can return -1 (when signaled) or valid FD.
503*8975f5c5SAndroid Build Coastguard Worker
504*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncFence2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
505*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncFence2, EGL_NO_SYNC_KHR);
506*8975f5c5SAndroid Build Coastguard Worker
507*8975f5c5SAndroid Build Coastguard Worker // Create work to do
508*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
509*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
510*8975f5c5SAndroid Build Coastguard Worker glFlush();
511*8975f5c5SAndroid Build Coastguard Worker
512*8975f5c5SAndroid Build Coastguard Worker /*- Second Context ------------------------*/
513*8975f5c5SAndroid Build Coastguard Worker if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
514*8975f5c5SAndroid Build Coastguard Worker {
515*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
516*8975f5c5SAndroid Build Coastguard Worker
517*8975f5c5SAndroid Build Coastguard Worker EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT, nullptr);
518*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
519*8975f5c5SAndroid Build Coastguard Worker
520*8975f5c5SAndroid Build Coastguard Worker // check that Fence and Android fences work together
521*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncFence3 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
522*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncFence3, EGL_NO_SYNC_KHR);
523*8975f5c5SAndroid Build Coastguard Worker
524*8975f5c5SAndroid Build Coastguard Worker // We can eglWaitSync on this
525*8975f5c5SAndroid Build Coastguard Worker EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
526*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithDupFD =
527*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
528*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);
529*8975f5c5SAndroid Build Coastguard Worker
530*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncFence4 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
531*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncFence4, EGL_NO_SYNC_KHR);
532*8975f5c5SAndroid Build Coastguard Worker
533*8975f5c5SAndroid Build Coastguard Worker // Second draw waits for first to complete. May already be signaled - ignore error.
534*8975f5c5SAndroid Build Coastguard Worker if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker // Create work to do
537*8975f5c5SAndroid Build Coastguard Worker glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
538*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
539*8975f5c5SAndroid Build Coastguard Worker glFlush();
540*8975f5c5SAndroid Build Coastguard Worker }
541*8975f5c5SAndroid Build Coastguard Worker
542*8975f5c5SAndroid Build Coastguard Worker // Wait for second draw to complete
543*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
544*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
545*8975f5c5SAndroid Build Coastguard Worker 1000000000));
546*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
547*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
548*8975f5c5SAndroid Build Coastguard Worker
549*8975f5c5SAndroid Build Coastguard Worker // Reset to default context and surface.
550*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
551*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));
552*8975f5c5SAndroid Build Coastguard Worker
553*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
554*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence3));
555*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence4));
556*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
557*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
558*8975f5c5SAndroid Build Coastguard Worker }
559*8975f5c5SAndroid Build Coastguard Worker
560*8975f5c5SAndroid Build Coastguard Worker // Wait for first draw to complete
561*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
562*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
563*8975f5c5SAndroid Build Coastguard Worker 1000000000));
564*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
565*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
566*8975f5c5SAndroid Build Coastguard Worker
567*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
568*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence1));
569*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence2));
570*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
571*8975f5c5SAndroid Build Coastguard Worker }
572*8975f5c5SAndroid Build Coastguard Worker
573*8975f5c5SAndroid Build Coastguard Worker // Verify that VkSemaphore is not destroyed before used for waiting
TEST_P(EGLSyncTest,AndroidNativeFence_VkSemaphoreDestroyBug)574*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_VkSemaphoreDestroyBug)
575*8975f5c5SAndroid Build Coastguard Worker {
576*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsVulkan());
577*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
578*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
579*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
580*8975f5c5SAndroid Build Coastguard Worker
581*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
582*8975f5c5SAndroid Build Coastguard Worker
583*8975f5c5SAndroid Build Coastguard Worker glFinish(); // Ensure no pending commands
584*8975f5c5SAndroid Build Coastguard Worker
585*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
586*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
587*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
588*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglWaitSyncKHR(display, syncWithGeneratedFD, 0));
589*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
590*8975f5c5SAndroid Build Coastguard Worker glFinish(); // May destroy VkSemaphore if bug is present.
591*8975f5c5SAndroid Build Coastguard Worker
592*8975f5c5SAndroid Build Coastguard Worker // Create work to do
593*8975f5c5SAndroid Build Coastguard Worker glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
594*8975f5c5SAndroid Build Coastguard Worker glClear(GL_COLOR_BUFFER_BIT);
595*8975f5c5SAndroid Build Coastguard Worker glFinish(); // Will submit destroyed Semaphores.
596*8975f5c5SAndroid Build Coastguard Worker }
597*8975f5c5SAndroid Build Coastguard Worker
598*8975f5c5SAndroid Build Coastguard Worker // Verify that no VVL errors are generated when External Fence Handle is used to track submissions
TEST_P(EGLSyncTest,AndroidNativeFence_ExternalFenceWaitVVLBug)599*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, AndroidNativeFence_ExternalFenceWaitVVLBug)
600*8975f5c5SAndroid Build Coastguard Worker {
601*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsVulkan());
602*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
603*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());
604*8975f5c5SAndroid Build Coastguard Worker
605*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
606*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
607*8975f5c5SAndroid Build Coastguard Worker
608*8975f5c5SAndroid Build Coastguard Worker // Create work to do
609*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
610*8975f5c5SAndroid Build Coastguard Worker drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
611*8975f5c5SAndroid Build Coastguard Worker ASSERT_GL_NO_ERROR();
612*8975f5c5SAndroid Build Coastguard Worker
613*8975f5c5SAndroid Build Coastguard Worker // We can ClientWait on this
614*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR syncWithGeneratedFD =
615*8975f5c5SAndroid Build Coastguard Worker eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
616*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
617*8975f5c5SAndroid Build Coastguard Worker
618*8975f5c5SAndroid Build Coastguard Worker // Wait for draw to complete
619*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED,
620*8975f5c5SAndroid Build Coastguard Worker eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
621*8975f5c5SAndroid Build Coastguard Worker 1'000'000'000));
622*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
623*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
624*8975f5c5SAndroid Build Coastguard Worker
625*8975f5c5SAndroid Build Coastguard Worker // Clean up created objects.
626*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
627*8975f5c5SAndroid Build Coastguard Worker
628*8975f5c5SAndroid Build Coastguard Worker // Finish to cleanup internal garbage in the backend.
629*8975f5c5SAndroid Build Coastguard Worker glFinish();
630*8975f5c5SAndroid Build Coastguard Worker }
631*8975f5c5SAndroid Build Coastguard Worker
632*8975f5c5SAndroid Build Coastguard Worker // Test functionality of EGL_ANGLE_global_fence_sync.
TEST_P(EGLSyncTest,GlobalFenceSync)633*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, GlobalFenceSync)
634*8975f5c5SAndroid Build Coastguard Worker {
635*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
636*8975f5c5SAndroid Build Coastguard Worker
637*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
638*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_global_fence_sync"));
639*8975f5c5SAndroid Build Coastguard Worker
640*8975f5c5SAndroid Build Coastguard Worker // Create a second context
641*8975f5c5SAndroid Build Coastguard Worker EGLContext context1 = eglGetCurrentContext();
642*8975f5c5SAndroid Build Coastguard Worker EGLSurface drawSurface1 = eglGetCurrentSurface(EGL_DRAW);
643*8975f5c5SAndroid Build Coastguard Worker EGLSurface readSurface1 = eglGetCurrentSurface(EGL_READ);
644*8975f5c5SAndroid Build Coastguard Worker EGLConfig config = getEGLWindow()->getConfig();
645*8975f5c5SAndroid Build Coastguard Worker
646*8975f5c5SAndroid Build Coastguard Worker const EGLint contextAttribs[] = {
647*8975f5c5SAndroid Build Coastguard Worker EGL_CONTEXT_CLIENT_VERSION, getEGLWindow()->getClientMajorVersion(),
648*8975f5c5SAndroid Build Coastguard Worker EGL_CONTEXT_MINOR_VERSION_KHR, getEGLWindow()->getClientMinorVersion(), EGL_NONE};
649*8975f5c5SAndroid Build Coastguard Worker
650*8975f5c5SAndroid Build Coastguard Worker EGLContext context2 = eglCreateContext(display, config, context1, contextAttribs);
651*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(EGL_NO_CONTEXT, context2);
652*8975f5c5SAndroid Build Coastguard Worker
653*8975f5c5SAndroid Build Coastguard Worker const EGLint pbufferAttribs[] = {EGL_WIDTH, getWindowWidth(), EGL_HEIGHT, getWindowHeight(),
654*8975f5c5SAndroid Build Coastguard Worker EGL_NONE};
655*8975f5c5SAndroid Build Coastguard Worker EGLSurface drawSurface2 = eglCreatePbufferSurface(display, config, pbufferAttribs);
656*8975f5c5SAndroid Build Coastguard Worker ASSERT_NE(EGL_NO_SURFACE, drawSurface2);
657*8975f5c5SAndroid Build Coastguard Worker
658*8975f5c5SAndroid Build Coastguard Worker // Do an expensive draw in context 2
659*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, drawSurface2, drawSurface2, context2);
660*8975f5c5SAndroid Build Coastguard Worker
661*8975f5c5SAndroid Build Coastguard Worker constexpr char kCostlyVS[] = R"(attribute highp vec4 position;
662*8975f5c5SAndroid Build Coastguard Worker varying highp vec4 testPos;
663*8975f5c5SAndroid Build Coastguard Worker void main(void)
664*8975f5c5SAndroid Build Coastguard Worker {
665*8975f5c5SAndroid Build Coastguard Worker testPos = position;
666*8975f5c5SAndroid Build Coastguard Worker gl_Position = position;
667*8975f5c5SAndroid Build Coastguard Worker })";
668*8975f5c5SAndroid Build Coastguard Worker
669*8975f5c5SAndroid Build Coastguard Worker constexpr char kCostlyFS[] = R"(precision highp float;
670*8975f5c5SAndroid Build Coastguard Worker varying highp vec4 testPos;
671*8975f5c5SAndroid Build Coastguard Worker void main(void)
672*8975f5c5SAndroid Build Coastguard Worker {
673*8975f5c5SAndroid Build Coastguard Worker vec4 test = testPos;
674*8975f5c5SAndroid Build Coastguard Worker for (int i = 0; i < 500; i++)
675*8975f5c5SAndroid Build Coastguard Worker {
676*8975f5c5SAndroid Build Coastguard Worker test = sqrt(test);
677*8975f5c5SAndroid Build Coastguard Worker }
678*8975f5c5SAndroid Build Coastguard Worker gl_FragColor = test;
679*8975f5c5SAndroid Build Coastguard Worker })";
680*8975f5c5SAndroid Build Coastguard Worker
681*8975f5c5SAndroid Build Coastguard Worker ANGLE_GL_PROGRAM(expensiveProgram, kCostlyVS, kCostlyFS);
682*8975f5c5SAndroid Build Coastguard Worker drawQuad(expensiveProgram, "position", 0.0f);
683*8975f5c5SAndroid Build Coastguard Worker
684*8975f5c5SAndroid Build Coastguard Worker // Signal a fence sync for testing
685*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker // Switch to context 1, and create a global fence sync
688*8975f5c5SAndroid Build Coastguard Worker eglMakeCurrent(display, drawSurface1, readSurface1, context1);
689*8975f5c5SAndroid Build Coastguard Worker
690*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync1 = eglCreateSyncKHR(display, EGL_SYNC_GLOBAL_FENCE_ANGLE, nullptr);
691*8975f5c5SAndroid Build Coastguard Worker
692*8975f5c5SAndroid Build Coastguard Worker // Wait for the global fence sync to finish.
693*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint64 kTimeout = 1'000'000'000; // 1 second
694*8975f5c5SAndroid Build Coastguard Worker ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync1, 0, kTimeout));
695*8975f5c5SAndroid Build Coastguard Worker
696*8975f5c5SAndroid Build Coastguard Worker // If the global fence sync is signaled, then the signal from context2 must also be signaled.
697*8975f5c5SAndroid Build Coastguard Worker // Note that if sync1 was an EGL_SYNC_FENCE_KHR, this would not necessarily be true.
698*8975f5c5SAndroid Build Coastguard Worker EGLint value = 0;
699*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync2, EGL_SYNC_STATUS_KHR, &value));
700*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(value, EGL_SIGNALED_KHR);
701*8975f5c5SAndroid Build Coastguard Worker
702*8975f5c5SAndroid Build Coastguard Worker EXPECT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync2, 0, 0));
703*8975f5c5SAndroid Build Coastguard Worker
704*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync1));
705*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync2));
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroySurface(display, drawSurface2));
708*8975f5c5SAndroid Build Coastguard Worker EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
709*8975f5c5SAndroid Build Coastguard Worker }
710*8975f5c5SAndroid Build Coastguard Worker
711*8975f5c5SAndroid Build Coastguard Worker // Test that leaked fences are cleaned up in a safe way. Regression test for sync objects using tail
712*8975f5c5SAndroid Build Coastguard Worker // calls for destruction.
TEST_P(EGLSyncTest,DISABLED_LeakSyncToDisplayDestruction)713*8975f5c5SAndroid Build Coastguard Worker TEST_P(EGLSyncTest, DISABLED_LeakSyncToDisplayDestruction)
714*8975f5c5SAndroid Build Coastguard Worker {
715*8975f5c5SAndroid Build Coastguard Worker ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
716*8975f5c5SAndroid Build Coastguard Worker
717*8975f5c5SAndroid Build Coastguard Worker EGLDisplay display = getEGLWindow()->getDisplay();
718*8975f5c5SAndroid Build Coastguard Worker
719*8975f5c5SAndroid Build Coastguard Worker EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
720*8975f5c5SAndroid Build Coastguard Worker EXPECT_NE(sync, EGL_NO_SYNC_KHR);
721*8975f5c5SAndroid Build Coastguard Worker }
722*8975f5c5SAndroid Build Coastguard Worker
723*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EGLSyncTest);
724