• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 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 
7 // entry_points_ext.cpp : Implements the EGL extension entry points.
8 
9 #include "libGLESv2/entry_points_egl_ext.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Device.h"
14 #include "libANGLE/Display.h"
15 #include "libANGLE/EGLSync.h"
16 #include "libANGLE/Stream.h"
17 #include "libANGLE/Surface.h"
18 #include "libANGLE/Thread.h"
19 #include "libANGLE/entry_points_utils.h"
20 #include "libANGLE/queryutils.h"
21 #include "libANGLE/validationEGL.h"
22 #include "libGLESv2/global_state.h"
23 
24 using namespace egl;
25 
26 extern "C" {
27 
28 // EGL_ANGLE_query_surface_pointer
EGL_QuerySurfacePointerANGLE(EGLDisplay dpy,EGLSurface surface,EGLint attribute,void ** value)29 EGLBoolean EGLAPIENTRY EGL_QuerySurfacePointerANGLE(EGLDisplay dpy,
30                                                     EGLSurface surface,
31                                                     EGLint attribute,
32                                                     void **value)
33 {
34     ANGLE_SCOPED_GLOBAL_LOCK();
35     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
36                ", EGLint attribute = %d, void "
37                "**value = 0x%016" PRIxPTR,
38                (uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
39     Thread *thread = egl::GetCurrentThread();
40 
41     egl::Display *display = static_cast<egl::Display *>(dpy);
42     Surface *eglSurface   = static_cast<Surface *>(surface);
43 
44     Error error = ValidateSurface(display, eglSurface);
45     if (error.isError())
46     {
47         thread->setError(error, GetDebug(), "eglQuerySurfacePointerANGLE",
48                          GetSurfaceIfValid(display, eglSurface));
49         return EGL_FALSE;
50     }
51 
52     if (!display->getExtensions().querySurfacePointer)
53     {
54         thread->setSuccess();
55         return EGL_FALSE;
56     }
57 
58     if (surface == EGL_NO_SURFACE)
59     {
60         thread->setError(EglBadSurface(), GetDebug(), "eglQuerySurfacePointerANGLE",
61                          GetSurfaceIfValid(display, eglSurface));
62         return EGL_FALSE;
63     }
64 
65     // validate the attribute parameter
66     switch (attribute)
67     {
68         case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
69             if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
70             {
71                 thread->setError(EglBadAttribute(), GetDebug(), "eglQuerySurfacePointerANGLE",
72                                  GetSurfaceIfValid(display, eglSurface));
73                 return EGL_FALSE;
74             }
75             break;
76         case EGL_DXGI_KEYED_MUTEX_ANGLE:
77             if (!display->getExtensions().keyedMutex)
78             {
79                 thread->setError(EglBadAttribute(), GetDebug(), "eglQuerySurfacePointerANGLE",
80                                  GetSurfaceIfValid(display, eglSurface));
81                 return EGL_FALSE;
82             }
83             break;
84         default:
85             thread->setError(EglBadAttribute(), GetDebug(), "eglQuerySurfacePointerANGLE",
86                              GetSurfaceIfValid(display, eglSurface));
87             return EGL_FALSE;
88     }
89 
90     error = eglSurface->querySurfacePointerANGLE(attribute, value);
91     if (error.isError())
92     {
93         thread->setError(error, GetDebug(), "eglQuerySurfacePointerANGLE",
94                          GetSurfaceIfValid(display, eglSurface));
95         return EGL_FALSE;
96     }
97 
98     thread->setSuccess();
99     return EGL_TRUE;
100 }
101 
102 // EGL_NV_post_sub_buffer
EGL_PostSubBufferNV(EGLDisplay dpy,EGLSurface surface,EGLint x,EGLint y,EGLint width,EGLint height)103 EGLBoolean EGLAPIENTRY EGL_PostSubBufferNV(EGLDisplay dpy,
104                                            EGLSurface surface,
105                                            EGLint x,
106                                            EGLint y,
107                                            EGLint width,
108                                            EGLint height)
109 {
110     ANGLE_SCOPED_GLOBAL_LOCK();
111     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
112                ", EGLint x = %d, EGLint y = %d, "
113                "EGLint width = %d, EGLint height = %d",
114                (uintptr_t)dpy, (uintptr_t)surface, x, y, width, height);
115     Thread *thread        = egl::GetCurrentThread();
116     egl::Display *display = static_cast<egl::Display *>(dpy);
117     Surface *eglSurface   = static_cast<Surface *>(surface);
118 
119     if (x < 0 || y < 0 || width < 0 || height < 0)
120     {
121         thread->setError(EglBadParameter(), GetDebug(), "eglPostSubBufferNV",
122                          GetSurfaceIfValid(display, eglSurface));
123         return EGL_FALSE;
124     }
125 
126     Error error = ValidateSurface(display, eglSurface);
127     if (error.isError())
128     {
129         thread->setError(error, GetDebug(), "eglPostSubBufferNV",
130                          GetSurfaceIfValid(display, eglSurface));
131         return EGL_FALSE;
132     }
133 
134     if (display->testDeviceLost())
135     {
136         thread->setError(EglContextLost(), GetDebug(), "eglPostSubBufferNV",
137                          GetSurfaceIfValid(display, eglSurface));
138         return EGL_FALSE;
139     }
140 
141     if (surface == EGL_NO_SURFACE)
142     {
143         thread->setError(EglBadSurface(), GetDebug(), "eglPostSubBufferNV",
144                          GetSurfaceIfValid(display, eglSurface));
145         return EGL_FALSE;
146     }
147 
148     if (!display->getExtensions().postSubBuffer)
149     {
150         // Spec is not clear about how this should be handled.
151         thread->setSuccess();
152         return EGL_TRUE;
153     }
154 
155     // TODO(jmadill): Validate Surface is bound to the thread.
156     error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
157     if (error.isError())
158     {
159         thread->setError(error, GetDebug(), "eglPostSubBufferNV",
160                          GetSurfaceIfValid(display, eglSurface));
161         return EGL_FALSE;
162     }
163 
164     thread->setSuccess();
165     return EGL_TRUE;
166 }
167 
168 // EGL_EXT_platform_base
EGL_GetPlatformDisplayEXT(EGLenum platform,void * native_display,const EGLint * attrib_list)169 EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplayEXT(EGLenum platform,
170                                                  void *native_display,
171                                                  const EGLint *attrib_list)
172 {
173     ANGLE_SCOPED_GLOBAL_LOCK();
174     FUNC_EVENT("EGLenum platform = %d, void* native_display = 0x%016" PRIxPTR
175                ", const EGLint* attrib_list = "
176                "0x%016" PRIxPTR,
177                platform, (uintptr_t)native_display, (uintptr_t)attrib_list);
178     Thread *thread = egl::GetCurrentThread();
179 
180     Error err = ValidateGetPlatformDisplayEXT(platform, native_display, attrib_list);
181     thread->setError(err, GetDebug(), "eglGetPlatformDisplayEXT", GetThreadIfValid(thread));
182     if (err.isError())
183     {
184         return EGL_NO_DISPLAY;
185     }
186 
187     const auto &attribMap = AttributeMap::CreateFromIntArray(attrib_list);
188     if (platform == EGL_PLATFORM_ANGLE_ANGLE)
189     {
190         return egl::Display::GetDisplayFromNativeDisplay(
191             gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
192     }
193     else if (platform == EGL_PLATFORM_DEVICE_EXT)
194     {
195         Device *eglDevice = static_cast<Device *>(native_display);
196         return egl::Display::GetDisplayFromDevice(eglDevice, attribMap);
197     }
198     else
199     {
200         UNREACHABLE();
201         return EGL_NO_DISPLAY;
202     }
203 }
204 
EGL_CreatePlatformWindowSurfaceEXT(EGLDisplay dpy,EGLConfig config,void * native_window,const EGLint * attrib_list)205 EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurfaceEXT(EGLDisplay dpy,
206                                                           EGLConfig config,
207                                                           void *native_window,
208                                                           const EGLint *attrib_list)
209 {
210     ANGLE_SCOPED_GLOBAL_LOCK();
211     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
212                ", void *native_window = 0x%016" PRIxPTR
213                ", "
214                "const EGLint *attrib_list = 0x%016" PRIxPTR,
215                (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_window, (uintptr_t)attrib_list);
216     Thread *thread = egl::GetCurrentThread();
217 
218     egl::Display *display   = static_cast<egl::Display *>(dpy);
219     Config *configuration   = static_cast<Config *>(config);
220     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
221 
222     ANGLE_EGL_TRY_RETURN(
223         thread,
224         ValidateCreatePlatformWindowSurfaceEXT(display, configuration, native_window, attributes),
225         "eglCreatePlatformWindowSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
226 
227     thread->setError(EglBadDisplay() << "CreatePlatformWindowSurfaceEXT unimplemented.", GetDebug(),
228                      "eglCreatePlatformWindowSurfaceEXT", GetDisplayIfValid(display));
229     return EGL_NO_SURFACE;
230 }
231 
EGL_CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,EGLConfig config,void * native_pixmap,const EGLint * attrib_list)232 EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,
233                                                           EGLConfig config,
234                                                           void *native_pixmap,
235                                                           const EGLint *attrib_list)
236 {
237     ANGLE_SCOPED_GLOBAL_LOCK();
238     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
239                ", void *native_pixmap = 0x%016" PRIxPTR
240                ", "
241                "const EGLint *attrib_list = 0x%016" PRIxPTR,
242                (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_pixmap, (uintptr_t)attrib_list);
243     Thread *thread = egl::GetCurrentThread();
244 
245     egl::Display *display   = static_cast<egl::Display *>(dpy);
246     Config *configuration   = static_cast<Config *>(config);
247     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
248 
249     ANGLE_EGL_TRY_RETURN(
250         thread,
251         ValidateCreatePlatformPixmapSurfaceEXT(display, configuration, native_pixmap, attributes),
252         "eglCreatePlatformPixmapSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
253 
254     thread->setError(EglBadDisplay() << "CreatePlatformPixmapSurfaceEXT unimplemented.", GetDebug(),
255                      "eglCreatePlatformPixmapSurfaceEXT", GetDisplayIfValid(display));
256     return EGL_NO_SURFACE;
257 }
258 
259 // EGL_EXT_device_query
EGL_QueryDeviceAttribEXT(EGLDeviceEXT device,EGLint attribute,EGLAttrib * value)260 EGLBoolean EGLAPIENTRY EGL_QueryDeviceAttribEXT(EGLDeviceEXT device,
261                                                 EGLint attribute,
262                                                 EGLAttrib *value)
263 {
264     ANGLE_SCOPED_GLOBAL_LOCK();
265     FUNC_EVENT("EGLDeviceEXT device = 0x%016" PRIxPTR
266                ", EGLint attribute = %d, EGLAttrib *value = 0x%016" PRIxPTR,
267                (uintptr_t)device, attribute, (uintptr_t)value);
268     Thread *thread = egl::GetCurrentThread();
269 
270     Device *dev = static_cast<Device *>(device);
271 
272     Error error = ValidateDevice(dev);
273     if (error.isError())
274     {
275         thread->setError(error, GetDebug(), "eglQueryDeviceAttribEXT", GetDeviceIfValid(dev));
276         return EGL_FALSE;
277     }
278 
279     // If the device was created by (and is owned by) a display, and that display doesn't support
280     // device querying, then this call should fail
281     egl::Display *owningDisplay = dev->getOwningDisplay();
282     if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery)
283     {
284         thread->setError(EglBadAccess() << "Device wasn't created using eglCreateDeviceANGLE, "
285                                            "and the egl::Display that created it doesn't support "
286                                            "device querying",
287                          GetDebug(), "eglQueryDeviceAttribEXT", GetDeviceIfValid(dev));
288         return EGL_FALSE;
289     }
290 
291     // validate the attribute parameter
292     switch (attribute)
293     {
294         case EGL_D3D11_DEVICE_ANGLE:
295         case EGL_D3D9_DEVICE_ANGLE:
296             if (!dev->getExtensions().deviceD3D || dev->getType() != attribute)
297             {
298                 thread->setError(EglBadAttribute(), GetDebug(), "eglQueryDeviceAttribEXT",
299                                  GetDeviceIfValid(dev));
300                 return EGL_FALSE;
301             }
302             error = dev->getAttribute(attribute, value);
303             break;
304         case EGL_EAGL_CONTEXT_ANGLE:
305             if (!dev->getExtensions().deviceEAGL)
306             {
307                 thread->setError(EglBadAttribute(), GetDebug(), "eglQueryDeviceAttribEXT",
308                                  GetDeviceIfValid(dev));
309                 return EGL_FALSE;
310             }
311             error = dev->getAttribute(attribute, value);
312             break;
313         case EGL_CGL_CONTEXT_ANGLE:
314         case EGL_CGL_PIXEL_FORMAT_ANGLE:
315             if (!dev->getExtensions().deviceCGL)
316             {
317                 thread->setError(EglBadAttribute(), GetDebug(), "eglQueryDeviceAttribEXT",
318                                  GetDeviceIfValid(dev));
319                 return EGL_FALSE;
320             }
321             error = dev->getAttribute(attribute, value);
322             break;
323         default:
324             thread->setError(EglBadAttribute(), GetDebug(), "eglQueryDeviceAttribEXT",
325                              GetDeviceIfValid(dev));
326             return EGL_FALSE;
327     }
328 
329     if (error.isError())
330     {
331         thread->setError(error, GetDebug(), "eglQueryDeviceAttribEXT", GetDeviceIfValid(dev));
332         return EGL_FALSE;
333     }
334     thread->setSuccess();
335     return EGL_TRUE;
336 }
337 
338 // EGL_EXT_device_query
EGL_QueryDeviceStringEXT(EGLDeviceEXT device,EGLint name)339 const char *EGLAPIENTRY EGL_QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
340 {
341     ANGLE_SCOPED_GLOBAL_LOCK();
342     FUNC_EVENT("EGLDeviceEXT device = 0x%016" PRIxPTR ", EGLint name = %d", (uintptr_t)device,
343                name);
344     Thread *thread = egl::GetCurrentThread();
345 
346     Device *dev = static_cast<Device *>(device);
347 
348     Error error = ValidateDevice(dev);
349     if (error.isError())
350     {
351         thread->setError(error, GetDebug(), "eglQueryDeviceStringEXT", GetDeviceIfValid(dev));
352         return EGL_FALSE;
353     }
354 
355     const char *result;
356     switch (name)
357     {
358         case EGL_EXTENSIONS:
359             result = dev->getExtensionString().c_str();
360             break;
361         default:
362             thread->setError(EglBadDevice(), GetDebug(), "eglQueryDeviceStringEXT",
363                              GetDeviceIfValid(dev));
364             return nullptr;
365     }
366 
367     thread->setSuccess();
368     return result;
369 }
370 
371 // EGL_EXT_device_query
EGL_QueryDisplayAttribEXT(EGLDisplay dpy,EGLint attribute,EGLAttrib * value)372 EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
373 {
374     ANGLE_SCOPED_GLOBAL_LOCK();
375     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR
376                ", EGLint attribute = %d, EGLAttrib *value = 0x%016" PRIxPTR,
377                (uintptr_t)dpy, attribute, (uintptr_t)value);
378 
379     egl::Display *display = static_cast<egl::Display *>(dpy);
380     Thread *thread        = egl::GetCurrentThread();
381 
382     ANGLE_EGL_TRY_RETURN(thread, ValidateQueryDisplayAttribEXT(display, attribute),
383                          "eglQueryDisplayAttribEXT", GetDisplayIfValid(display), EGL_FALSE);
384 
385     *value = display->queryAttrib(attribute);
386     thread->setSuccess();
387     return EGL_TRUE;
388 }
389 
390 // EGL_ANGLE_feature_control
EGL_QueryDisplayAttribANGLE(EGLDisplay dpy,EGLint attribute,EGLAttrib * value)391 EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribANGLE(EGLDisplay dpy,
392                                                    EGLint attribute,
393                                                    EGLAttrib *value)
394 {
395     ANGLE_SCOPED_GLOBAL_LOCK();
396     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR
397                ", EGLint attribute = %d, EGLAttrib *value = 0x%016" PRIxPTR,
398                (uintptr_t)dpy, attribute, (uintptr_t)value);
399 
400     egl::Display *display = static_cast<egl::Display *>(dpy);
401     Thread *thread        = egl::GetCurrentThread();
402 
403     ANGLE_EGL_TRY_RETURN(thread, ValidateQueryDisplayAttribANGLE(display, attribute),
404                          "eglQueryDisplayAttribANGLE", GetDisplayIfValid(display), EGL_FALSE);
405 
406     *value = display->queryAttrib(attribute);
407     thread->setSuccess();
408     return EGL_TRUE;
409 }
410 
EGL_CreateImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)411 ANGLE_EXPORT EGLImageKHR EGLAPIENTRY EGL_CreateImageKHR(EGLDisplay dpy,
412                                                         EGLContext ctx,
413                                                         EGLenum target,
414                                                         EGLClientBuffer buffer,
415                                                         const EGLint *attrib_list)
416 {
417     ANGLE_SCOPED_GLOBAL_LOCK();
418     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR
419                ", EGLContext ctx = %d"
420                ", EGLenum target = 0x%X, "
421                "EGLClientBuffer buffer = 0x%016" PRIxPTR
422                ", const EGLAttrib *attrib_list = 0x%016" PRIxPTR,
423                (uintptr_t)dpy, CID(dpy, ctx), target, (uintptr_t)buffer, (uintptr_t)attrib_list);
424     Thread *thread = egl::GetCurrentThread();
425 
426     egl::Display *display   = static_cast<egl::Display *>(dpy);
427     gl::Context *context    = static_cast<gl::Context *>(ctx);
428     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
429 
430     Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes);
431     if (error.isError())
432     {
433         thread->setError(error, GetDebug(), "eglCreateImageKHR", GetDisplayIfValid(display));
434         return EGL_NO_IMAGE;
435     }
436 
437     Image *image = nullptr;
438     error        = display->createImage(context, target, buffer, attributes, &image);
439     if (error.isError())
440     {
441         thread->setError(error, GetDebug(), "eglCreateImageKHR", GetDisplayIfValid(display));
442         return EGL_NO_IMAGE;
443     }
444 
445     thread->setSuccess();
446     return static_cast<EGLImage>(image);
447 }
448 
EGL_DestroyImageKHR(EGLDisplay dpy,EGLImageKHR image)449 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
450 {
451     ANGLE_SCOPED_GLOBAL_LOCK();
452     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLImage image = 0x%016" PRIxPTR,
453                (uintptr_t)dpy, (uintptr_t)image);
454     Thread *thread = egl::GetCurrentThread();
455 
456     egl::Display *display = static_cast<egl::Display *>(dpy);
457     Image *img            = static_cast<Image *>(image);
458 
459     Error error = ValidateDestroyImageKHR(display, img);
460     if (error.isError())
461     {
462         thread->setError(error, GetDebug(), "eglDestroyImageKHR", GetImageIfValid(display, img));
463         return EGL_FALSE;
464     }
465 
466     display->destroyImage(img);
467 
468     thread->setSuccess();
469     return EGL_TRUE;
470 }
471 
EGL_CreateDeviceANGLE(EGLint device_type,void * native_device,const EGLAttrib * attrib_list)472 ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY EGL_CreateDeviceANGLE(EGLint device_type,
473                                                             void *native_device,
474                                                             const EGLAttrib *attrib_list)
475 {
476     ANGLE_SCOPED_GLOBAL_LOCK();
477     FUNC_EVENT("EGLint device_type = %d, void* native_device = 0x%016" PRIxPTR
478                ", const EGLAttrib* attrib_list = "
479                "0x%016" PRIxPTR,
480                device_type, (uintptr_t)native_device, (uintptr_t)attrib_list);
481     Thread *thread = egl::GetCurrentThread();
482 
483     Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list);
484     if (error.isError())
485     {
486         thread->setError(error, GetDebug(), "eglCreateDeviceANGLE", GetThreadIfValid(thread));
487         return EGL_NO_DEVICE_EXT;
488     }
489 
490     Device *device = nullptr;
491     error          = Device::CreateDevice(device_type, native_device, &device);
492     if (error.isError())
493     {
494         ASSERT(device == nullptr);
495         thread->setError(error, GetDebug(), "eglCreateDeviceANGLE", GetThreadIfValid(thread));
496         return EGL_NO_DEVICE_EXT;
497     }
498 
499     thread->setSuccess();
500     return device;
501 }
502 
EGL_ReleaseDeviceANGLE(EGLDeviceEXT device)503 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ReleaseDeviceANGLE(EGLDeviceEXT device)
504 {
505     ANGLE_SCOPED_GLOBAL_LOCK();
506     FUNC_EVENT("EGLDeviceEXT device = 0x%016" PRIxPTR, (uintptr_t)device);
507     Thread *thread = egl::GetCurrentThread();
508 
509     Device *dev = static_cast<Device *>(device);
510 
511     Error error = ValidateReleaseDeviceANGLE(dev);
512     if (error.isError())
513     {
514         thread->setError(error, GetDebug(), "eglReleaseDeviceANGLE", GetDeviceIfValid(dev));
515         return EGL_FALSE;
516     }
517 
518     SafeDelete(dev);
519 
520     thread->setSuccess();
521     return EGL_TRUE;
522 }
523 
524 // EGL_KHR_stream
EGL_CreateStreamKHR(EGLDisplay dpy,const EGLint * attrib_list)525 EGLStreamKHR EGLAPIENTRY EGL_CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
526 {
527     ANGLE_SCOPED_GLOBAL_LOCK();
528     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", const EGLAttrib* attrib_list = 0x%016" PRIxPTR,
529                (uintptr_t)dpy, (uintptr_t)attrib_list);
530     Thread *thread = egl::GetCurrentThread();
531 
532     egl::Display *display   = static_cast<egl::Display *>(dpy);
533     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
534 
535     Error error = ValidateCreateStreamKHR(display, attributes);
536     if (error.isError())
537     {
538         thread->setError(error, GetDebug(), "eglCreateStreamKHR", GetDisplayIfValid(display));
539         return EGL_NO_STREAM_KHR;
540     }
541 
542     Stream *stream;
543     error = display->createStream(attributes, &stream);
544     if (error.isError())
545     {
546         thread->setError(error, GetDebug(), "eglCreateStreamKHR", GetDisplayIfValid(display));
547         return EGL_NO_STREAM_KHR;
548     }
549 
550     thread->setSuccess();
551     return static_cast<EGLStreamKHR>(stream);
552 }
553 
EGL_DestroyStreamKHR(EGLDisplay dpy,EGLStreamKHR stream)554 EGLBoolean EGLAPIENTRY EGL_DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
555 {
556     ANGLE_SCOPED_GLOBAL_LOCK();
557     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR = 0x%016" PRIxPTR, (uintptr_t)dpy,
558                (uintptr_t)stream);
559     Thread *thread = egl::GetCurrentThread();
560 
561     egl::Display *display = static_cast<egl::Display *>(dpy);
562     Stream *streamObject  = static_cast<Stream *>(stream);
563 
564     Error error = ValidateDestroyStreamKHR(display, streamObject);
565     if (error.isError())
566     {
567         thread->setError(error, GetDebug(), "eglDestroyStreamKHR",
568                          GetStreamIfValid(display, streamObject));
569         return EGL_FALSE;
570     }
571 
572     display->destroyStream(streamObject);
573 
574     thread->setSuccess();
575     return EGL_TRUE;
576 }
577 
EGL_StreamAttribKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)578 EGLBoolean EGLAPIENTRY EGL_StreamAttribKHR(EGLDisplay dpy,
579                                            EGLStreamKHR stream,
580                                            EGLenum attribute,
581                                            EGLint value)
582 {
583     ANGLE_SCOPED_GLOBAL_LOCK();
584     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
585                ", EGLenum attribute = 0x%X, "
586                "EGLint value = 0x%X",
587                (uintptr_t)dpy, (uintptr_t)stream, attribute, value);
588     Thread *thread = egl::GetCurrentThread();
589 
590     egl::Display *display = static_cast<egl::Display *>(dpy);
591     Stream *streamObject  = static_cast<Stream *>(stream);
592 
593     Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value);
594     if (error.isError())
595     {
596         thread->setError(error, GetDebug(), "eglStreamAttribKHR",
597                          GetStreamIfValid(display, streamObject));
598         return EGL_FALSE;
599     }
600 
601     switch (attribute)
602     {
603         case EGL_CONSUMER_LATENCY_USEC_KHR:
604             streamObject->setConsumerLatency(value);
605             break;
606         case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
607             streamObject->setConsumerAcquireTimeout(value);
608             break;
609         default:
610             UNREACHABLE();
611     }
612 
613     thread->setSuccess();
614     return EGL_TRUE;
615 }
616 
EGL_QueryStreamKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)617 EGLBoolean EGLAPIENTRY EGL_QueryStreamKHR(EGLDisplay dpy,
618                                           EGLStreamKHR stream,
619                                           EGLenum attribute,
620                                           EGLint *value)
621 {
622     ANGLE_SCOPED_GLOBAL_LOCK();
623     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
624                ", EGLenum attribute = 0x%X, "
625                "EGLint value = 0x%016" PRIxPTR,
626                (uintptr_t)dpy, (uintptr_t)stream, attribute, (uintptr_t)value);
627     Thread *thread = egl::GetCurrentThread();
628 
629     egl::Display *display = static_cast<egl::Display *>(dpy);
630     Stream *streamObject  = static_cast<Stream *>(stream);
631 
632     Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value);
633     if (error.isError())
634     {
635         thread->setError(error, GetDebug(), "eglQueryStreamKHR",
636                          GetStreamIfValid(display, streamObject));
637         return EGL_FALSE;
638     }
639 
640     switch (attribute)
641     {
642         case EGL_STREAM_STATE_KHR:
643             *value = streamObject->getState();
644             break;
645         case EGL_CONSUMER_LATENCY_USEC_KHR:
646             *value = streamObject->getConsumerLatency();
647             break;
648         case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
649             *value = streamObject->getConsumerAcquireTimeout();
650             break;
651         default:
652             UNREACHABLE();
653     }
654 
655     thread->setSuccess();
656     return EGL_TRUE;
657 }
658 
EGL_QueryStreamu64KHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)659 EGLBoolean EGLAPIENTRY EGL_QueryStreamu64KHR(EGLDisplay dpy,
660                                              EGLStreamKHR stream,
661                                              EGLenum attribute,
662                                              EGLuint64KHR *value)
663 {
664     ANGLE_SCOPED_GLOBAL_LOCK();
665     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
666                ", EGLenum attribute = 0x%X, "
667                "EGLuint64KHR value = 0x%016" PRIxPTR,
668                (uintptr_t)dpy, (uintptr_t)stream, attribute, (uintptr_t)value);
669     Thread *thread = egl::GetCurrentThread();
670 
671     egl::Display *display = static_cast<egl::Display *>(dpy);
672     Stream *streamObject  = static_cast<Stream *>(stream);
673 
674     Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value);
675     if (error.isError())
676     {
677         thread->setError(error, GetDebug(), "eglQueryStreamu64KHR",
678                          GetStreamIfValid(display, streamObject));
679         return EGL_FALSE;
680     }
681 
682     switch (attribute)
683     {
684         case EGL_PRODUCER_FRAME_KHR:
685             *value = streamObject->getProducerFrame();
686             break;
687         case EGL_CONSUMER_FRAME_KHR:
688             *value = streamObject->getConsumerFrame();
689             break;
690         default:
691             UNREACHABLE();
692     }
693 
694     thread->setSuccess();
695     return EGL_TRUE;
696 }
697 
EGL_StreamConsumerGLTextureExternalKHR(EGLDisplay dpy,EGLStreamKHR stream)698 EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream)
699 {
700     ANGLE_SCOPED_GLOBAL_LOCK();
701     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR = 0x%016" PRIxPTR, (uintptr_t)dpy,
702                (uintptr_t)stream);
703     Thread *thread = egl::GetCurrentThread();
704 
705     egl::Display *display = static_cast<egl::Display *>(dpy);
706     Stream *streamObject  = static_cast<Stream *>(stream);
707     gl::Context *context  = gl::GetValidGlobalContext();
708 
709     Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject);
710     if (error.isError())
711     {
712         thread->setError(error, GetDebug(), "eglStreamConsumerGLTextureExternalKHR",
713                          GetStreamIfValid(display, streamObject));
714         return EGL_FALSE;
715     }
716 
717     error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context);
718     if (error.isError())
719     {
720         thread->setError(error, GetDebug(), "eglStreamConsumerGLTextureExternalKHR",
721                          GetStreamIfValid(display, streamObject));
722         return EGL_FALSE;
723     }
724 
725     thread->setSuccess();
726     return EGL_TRUE;
727 }
728 
EGL_StreamConsumerAcquireKHR(EGLDisplay dpy,EGLStreamKHR stream)729 EGLBoolean EGLAPIENTRY EGL_StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream)
730 {
731     ANGLE_SCOPED_GLOBAL_LOCK();
732     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR = 0x%016" PRIxPTR, (uintptr_t)dpy,
733                (uintptr_t)stream);
734     Thread *thread = egl::GetCurrentThread();
735 
736     egl::Display *display = static_cast<egl::Display *>(dpy);
737     Stream *streamObject  = static_cast<Stream *>(stream);
738     gl::Context *context  = gl::GetValidGlobalContext();
739 
740     Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject);
741     if (error.isError())
742     {
743         thread->setError(error, GetDebug(), "eglStreamConsumerAcquireKHR",
744                          GetStreamIfValid(display, streamObject));
745         return EGL_FALSE;
746     }
747 
748     error = streamObject->consumerAcquire(context);
749     if (error.isError())
750     {
751         thread->setError(error, GetDebug(), "eglStreamConsumerAcquireKHR",
752                          GetStreamIfValid(display, streamObject));
753         return EGL_FALSE;
754     }
755 
756     thread->setSuccess();
757     return EGL_TRUE;
758 }
759 
EGL_StreamConsumerReleaseKHR(EGLDisplay dpy,EGLStreamKHR stream)760 EGLBoolean EGLAPIENTRY EGL_StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream)
761 {
762     ANGLE_SCOPED_GLOBAL_LOCK();
763     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR = 0x%016" PRIxPTR, (uintptr_t)dpy,
764                (uintptr_t)stream);
765     Thread *thread = egl::GetCurrentThread();
766 
767     egl::Display *display = static_cast<egl::Display *>(dpy);
768     Stream *streamObject  = static_cast<Stream *>(stream);
769     gl::Context *context  = gl::GetValidGlobalContext();
770 
771     Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject);
772     if (error.isError())
773     {
774         thread->setError(error, GetDebug(), "eglSStreamConsumerReleaseKHR",
775                          GetStreamIfValid(display, streamObject));
776         return EGL_FALSE;
777     }
778 
779     error = streamObject->consumerRelease(context);
780     if (error.isError())
781     {
782         thread->setError(error, GetDebug(), "eglStreamConsumerReleaseKHR",
783                          GetStreamIfValid(display, streamObject));
784         return EGL_FALSE;
785     }
786 
787     thread->setSuccess();
788     return EGL_TRUE;
789 }
790 
EGL_StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,EGLStreamKHR stream,const EGLAttrib * attrib_list)791 EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
792                                                                     EGLStreamKHR stream,
793                                                                     const EGLAttrib *attrib_list)
794 {
795     ANGLE_SCOPED_GLOBAL_LOCK();
796     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
797                ", EGLAttrib attrib_list = 0x%016" PRIxPTR "",
798                (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)attrib_list);
799     Thread *thread = egl::GetCurrentThread();
800 
801     egl::Display *display   = static_cast<egl::Display *>(dpy);
802     Stream *streamObject    = static_cast<Stream *>(stream);
803     gl::Context *context    = gl::GetValidGlobalContext();
804     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
805 
806     Error error = ValidateStreamConsumerGLTextureExternalAttribsNV(display, context, streamObject,
807                                                                    attributes);
808     if (error.isError())
809     {
810         thread->setError(error, GetDebug(), "eglStreamConsumerGLTextureExternalAttribsNV",
811                          GetStreamIfValid(display, streamObject));
812         return EGL_FALSE;
813     }
814 
815     error = streamObject->createConsumerGLTextureExternal(attributes, context);
816     if (error.isError())
817     {
818         thread->setError(error, GetDebug(), "eglStreamConsumerGLTextureExternalAttribsNV",
819                          GetStreamIfValid(display, streamObject));
820         return EGL_FALSE;
821     }
822 
823     thread->setSuccess();
824     return EGL_TRUE;
825 }
826 
EGL_CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,EGLStreamKHR stream,const EGLAttrib * attrib_list)827 EGLBoolean EGLAPIENTRY EGL_CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
828                                                                EGLStreamKHR stream,
829                                                                const EGLAttrib *attrib_list)
830 {
831     ANGLE_SCOPED_GLOBAL_LOCK();
832     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
833                ", EGLAttrib attrib_list = 0x%016" PRIxPTR "",
834                (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)attrib_list);
835     Thread *thread = egl::GetCurrentThread();
836 
837     egl::Display *display   = static_cast<egl::Display *>(dpy);
838     Stream *streamObject    = static_cast<Stream *>(stream);
839     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
840 
841     Error error = ValidateCreateStreamProducerD3DTextureANGLE(display, streamObject, attributes);
842     if (error.isError())
843     {
844         thread->setError(error, GetDebug(), "eglCreateStreamProducerD3DTextureANGLE",
845                          GetStreamIfValid(display, streamObject));
846         return EGL_FALSE;
847     }
848 
849     error = streamObject->createProducerD3D11Texture(attributes);
850     if (error.isError())
851     {
852         thread->setError(error, GetDebug(), "eglCreateStreamProducerD3DTextureANGLE",
853                          GetStreamIfValid(display, streamObject));
854         return EGL_FALSE;
855     }
856 
857     thread->setSuccess();
858     return EGL_TRUE;
859 }
860 
EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,EGLStreamKHR stream,void * texture,const EGLAttrib * attrib_list)861 EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,
862                                                      EGLStreamKHR stream,
863                                                      void *texture,
864                                                      const EGLAttrib *attrib_list)
865 {
866     ANGLE_SCOPED_GLOBAL_LOCK();
867     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLStreamKHR stream = 0x%016" PRIxPTR
868                ", void* texture = 0x%016" PRIxPTR
869                ", "
870                "EGLAttrib attrib_list = 0x%016" PRIxPTR "",
871                (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)texture, (uintptr_t)attrib_list);
872     Thread *thread = egl::GetCurrentThread();
873 
874     egl::Display *display   = static_cast<egl::Display *>(dpy);
875     Stream *streamObject    = static_cast<Stream *>(stream);
876     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
877 
878     Error error = ValidateStreamPostD3DTextureANGLE(display, streamObject, texture, attributes);
879     if (error.isError())
880     {
881         thread->setError(error, GetDebug(), "eglStreamPostD3DTextureANGLE",
882                          GetStreamIfValid(display, streamObject));
883         return EGL_FALSE;
884     }
885 
886     error = streamObject->postD3D11Texture(texture, attributes);
887     if (error.isError())
888     {
889         thread->setError(error, GetDebug(), "eglStreamPostD3DTextureANGLE",
890                          GetStreamIfValid(display, streamObject));
891         return EGL_FALSE;
892     }
893 
894     thread->setSuccess();
895     return EGL_TRUE;
896 }
897 
898 // EGL_KHR_fence_sync
EGL_CreateSyncKHR(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)899 ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
900                                                    EGLenum type,
901                                                    const EGLint *attrib_list)
902 {
903     ANGLE_SCOPED_GLOBAL_LOCK();
904     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR
905                ", EGLenum type = 0x%X, const EGLint* attrib_list = 0x%016" PRIxPTR,
906                (uintptr_t)dpy, type, (uintptr_t)attrib_list);
907 
908     Thread *thread          = egl::GetCurrentThread();
909     egl::Display *display   = static_cast<egl::Display *>(dpy);
910     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
911 
912     gl::Context *currentContext  = thread->getContext();
913     egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr;
914 
915     ANGLE_EGL_TRY_RETURN(
916         thread, ValidateCreateSyncKHR(display, type, attributes, currentDisplay, currentContext),
917         "eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
918 
919     egl::Sync *syncObject = nullptr;
920     ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
921                          "eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
922 
923     thread->setSuccess();
924     return static_cast<EGLSync>(syncObject);
925 }
926 
EGL_DestroySyncKHR(EGLDisplay dpy,EGLSync sync)927 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSync sync)
928 {
929     ANGLE_SCOPED_GLOBAL_LOCK();
930     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR, (uintptr_t)dpy,
931                (uintptr_t)sync);
932 
933     Thread *thread        = egl::GetCurrentThread();
934     egl::Display *display = static_cast<egl::Display *>(dpy);
935     egl::Sync *syncObject = static_cast<Sync *>(sync);
936 
937     ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
938                          GetDisplayIfValid(display), EGL_FALSE);
939 
940     display->destroySync(syncObject);
941 
942     thread->setSuccess();
943     return EGL_TRUE;
944 }
945 
EGL_ClientWaitSyncKHR(EGLDisplay dpy,EGLSync sync,EGLint flags,EGLTime timeout)946 ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
947                                                       EGLSync sync,
948                                                       EGLint flags,
949                                                       EGLTime timeout)
950 {
951     ANGLE_SCOPED_GLOBAL_LOCK();
952     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
953                ", EGLint flags = 0x%X, EGLTime timeout = "
954                "%llu",
955                (uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
956 
957     Thread *thread        = egl::GetCurrentThread();
958     egl::Display *display = static_cast<egl::Display *>(dpy);
959     egl::Sync *syncObject = static_cast<Sync *>(sync);
960 
961     ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
962                          "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
963 
964     gl::Context *currentContext = thread->getContext();
965     EGLint syncStatus           = EGL_FALSE;
966     ANGLE_EGL_TRY_RETURN(
967         thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
968         "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
969 
970     thread->setSuccess();
971     return syncStatus;
972 }
973 
EGL_GetSyncAttribKHR(EGLDisplay dpy,EGLSync sync,EGLint attribute,EGLint * value)974 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
975                                                          EGLSync sync,
976                                                          EGLint attribute,
977                                                          EGLint *value)
978 {
979     ANGLE_SCOPED_GLOBAL_LOCK();
980     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
981                ", EGLint attribute = 0x%X, EGLAttrib "
982                "*value = 0x%016" PRIxPTR,
983                (uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
984 
985     Thread *thread        = egl::GetCurrentThread();
986     egl::Display *display = static_cast<egl::Display *>(dpy);
987     egl::Sync *syncObject = static_cast<Sync *>(sync);
988 
989     ANGLE_EGL_TRY_RETURN(thread, ValidateGetSyncAttribKHR(display, syncObject, attribute, value),
990                          "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
991 
992     ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
993                          "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
994 
995     thread->setSuccess();
996     return EGL_TRUE;
997 }
998 
999 // EGL_KHR_wait_sync
EGL_WaitSyncKHR(EGLDisplay dpy,EGLSync sync,EGLint flags)1000 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
1001 {
1002     ANGLE_SCOPED_GLOBAL_LOCK();
1003     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR "p, EGLSync sync = 0x%016" PRIxPTR
1004                ", EGLint flags = 0x%X",
1005                (uintptr_t)dpy, (uintptr_t)sync, flags);
1006 
1007     Thread *thread        = egl::GetCurrentThread();
1008     egl::Display *display = static_cast<egl::Display *>(dpy);
1009     gl::Context *context  = thread->getContext();
1010     egl::Sync *syncObject = static_cast<Sync *>(sync);
1011 
1012     ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
1013                          "eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
1014 
1015     gl::Context *currentContext = thread->getContext();
1016     ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
1017                          "eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
1018 
1019     thread->setSuccess();
1020     return EGL_TRUE;
1021 }
1022 
EGL_GetMscRateANGLE(EGLDisplay dpy,EGLSurface surface,EGLint * numerator,EGLint * denominator)1023 EGLBoolean EGLAPIENTRY EGL_GetMscRateANGLE(EGLDisplay dpy,
1024                                            EGLSurface surface,
1025                                            EGLint *numerator,
1026                                            EGLint *denominator)
1027 {
1028     ANGLE_SCOPED_GLOBAL_LOCK();
1029     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1030                ", EGLint* numerator = 0x%016" PRIxPTR
1031                ", "
1032                "EGLint* denomintor = 0x%016" PRIxPTR "",
1033                (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)numerator, (uintptr_t)denominator);
1034     Thread *thread = egl::GetCurrentThread();
1035 
1036     egl::Display *display = static_cast<egl::Display *>(dpy);
1037     Surface *eglSurface   = static_cast<Surface *>(surface);
1038 
1039     Error error = ValidateGetMscRateANGLE(display, eglSurface, numerator, denominator);
1040     if (error.isError())
1041     {
1042         thread->setError(error, GetDebug(), "eglGetMscRateANGLE",
1043                          GetSurfaceIfValid(display, eglSurface));
1044         return EGL_FALSE;
1045     }
1046 
1047     error = eglSurface->getMscRate(numerator, denominator);
1048     if (error.isError())
1049     {
1050         thread->setError(error, GetDebug(), "eglGetMscRateANGLE",
1051                          GetSurfaceIfValid(display, eglSurface));
1052         return EGL_FALSE;
1053     }
1054 
1055     thread->setSuccess();
1056     return EGL_TRUE;
1057 }
1058 
EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)1059 EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
1060                                                  EGLSurface surface,
1061                                                  EGLuint64KHR *ust,
1062                                                  EGLuint64KHR *msc,
1063                                                  EGLuint64KHR *sbc)
1064 {
1065     ANGLE_SCOPED_GLOBAL_LOCK();
1066     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1067                ", EGLuint64KHR* ust = 0x%016" PRIxPTR
1068                ", "
1069                "EGLuint64KHR* msc = 0x%016" PRIxPTR ", EGLuint64KHR* sbc = 0x%016" PRIxPTR "",
1070                (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)ust, (uintptr_t)msc, (uintptr_t)sbc);
1071     Thread *thread = egl::GetCurrentThread();
1072 
1073     egl::Display *display = static_cast<egl::Display *>(dpy);
1074     Surface *eglSurface   = static_cast<Surface *>(surface);
1075 
1076     Error error = ValidateGetSyncValuesCHROMIUM(display, eglSurface, ust, msc, sbc);
1077     if (error.isError())
1078     {
1079         thread->setError(error, GetDebug(), "eglGetSyncValuesCHROMIUM",
1080                          GetSurfaceIfValid(display, eglSurface));
1081         return EGL_FALSE;
1082     }
1083 
1084     error = eglSurface->getSyncValues(ust, msc, sbc);
1085     if (error.isError())
1086     {
1087         thread->setError(error, GetDebug(), "eglGetSyncValuesCHROMIUM",
1088                          GetSurfaceIfValid(display, eglSurface));
1089         return EGL_FALSE;
1090     }
1091 
1092     thread->setSuccess();
1093     return EGL_TRUE;
1094 }
1095 
EGL_SwapBuffersWithDamageKHR(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)1096 EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithDamageKHR(EGLDisplay dpy,
1097                                                     EGLSurface surface,
1098                                                     EGLint *rects,
1099                                                     EGLint n_rects)
1100 {
1101     ANGLE_SCOPED_GLOBAL_LOCK();
1102     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1103                ", EGLint *rects = 0x%016" PRIxPTR
1104                ", EGLint "
1105                "n_rects = %d",
1106                (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)rects, n_rects);
1107     Thread *thread = egl::GetCurrentThread();
1108 
1109     egl::Display *display = static_cast<egl::Display *>(dpy);
1110     Surface *eglSurface   = static_cast<Surface *>(surface);
1111 
1112     Error error = ValidateSwapBuffersWithDamageKHR(display, eglSurface, rects, n_rects);
1113     if (error.isError())
1114     {
1115         thread->setError(error, GetDebug(), "eglSwapBuffersWithDamageEXT",
1116                          GetSurfaceIfValid(display, eglSurface));
1117         return EGL_FALSE;
1118     }
1119 
1120     error = eglSurface->swapWithDamage(thread->getContext(), rects, n_rects);
1121     if (error.isError())
1122     {
1123         thread->setError(error, GetDebug(), "eglSwapBuffersWithDamageEXT",
1124                          GetSurfaceIfValid(display, eglSurface));
1125         return EGL_FALSE;
1126     }
1127 
1128     thread->setSuccess();
1129     return EGL_TRUE;
1130 }
1131 
EGL_PresentationTimeANDROID(EGLDisplay dpy,EGLSurface surface,EGLnsecsANDROID time)1132 EGLBoolean EGLAPIENTRY EGL_PresentationTimeANDROID(EGLDisplay dpy,
1133                                                    EGLSurface surface,
1134                                                    EGLnsecsANDROID time)
1135 {
1136     ANGLE_SCOPED_GLOBAL_LOCK();
1137     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1138                ", EGLnsecsANDROID time = %llu",
1139                (uintptr_t)dpy, (uintptr_t)surface, static_cast<unsigned long long>(time));
1140     Thread *thread = egl::GetCurrentThread();
1141 
1142     egl::Display *display = static_cast<egl::Display *>(dpy);
1143     Surface *eglSurface   = static_cast<Surface *>(surface);
1144 
1145     ANGLE_EGL_TRY_RETURN(thread, ValidatePresentationTimeANDROID(display, eglSurface, time),
1146                          "eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
1147                          EGL_FALSE);
1148     ANGLE_EGL_TRY_RETURN(thread, eglSurface->setPresentationTime(time),
1149                          "eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
1150                          EGL_FALSE);
1151 
1152     return EGL_TRUE;
1153 }
1154 
EGL_SetBlobCacheFuncsANDROID(EGLDisplay dpy,EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get)1155 ANGLE_EXPORT void EGLAPIENTRY EGL_SetBlobCacheFuncsANDROID(EGLDisplay dpy,
1156                                                            EGLSetBlobFuncANDROID set,
1157                                                            EGLGetBlobFuncANDROID get)
1158 {
1159     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSetBlobFuncANDROID set = 0x%016" PRIxPTR
1160                ", EGLGetBlobFuncANDROID get "
1161                "= 0x%016" PRIxPTR,
1162                (uintptr_t)dpy, (uintptr_t)set, (uintptr_t)get);
1163     Thread *thread = egl::GetCurrentThread();
1164 
1165     egl::Display *display = static_cast<egl::Display *>(dpy);
1166 
1167     ANGLE_EGL_TRY(thread, ValidateSetBlobCacheANDROID(display, set, get),
1168                   "eglSetBlobCacheFuncsANDROID", GetDisplayIfValid(display));
1169 
1170     thread->setSuccess();
1171     display->setBlobCacheFuncs(set, get);
1172 }
1173 
EGL_ProgramCacheGetAttribANGLE(EGLDisplay dpy,EGLenum attrib)1174 EGLint EGLAPIENTRY EGL_ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib)
1175 {
1176     ANGLE_SCOPED_GLOBAL_LOCK();
1177     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLenum attrib = 0x%X", (uintptr_t)dpy, attrib);
1178 
1179     egl::Display *display = static_cast<egl::Display *>(dpy);
1180     Thread *thread        = egl::GetCurrentThread();
1181 
1182     ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheGetAttribANGLE(display, attrib),
1183                          "eglProgramCacheGetAttribANGLE", GetDisplayIfValid(display), 0);
1184 
1185     thread->setSuccess();
1186     return display->programCacheGetAttrib(attrib);
1187 }
1188 
EGL_ProgramCacheQueryANGLE(EGLDisplay dpy,EGLint index,void * key,EGLint * keysize,void * binary,EGLint * binarysize)1189 void EGLAPIENTRY EGL_ProgramCacheQueryANGLE(EGLDisplay dpy,
1190                                             EGLint index,
1191                                             void *key,
1192                                             EGLint *keysize,
1193                                             void *binary,
1194                                             EGLint *binarysize)
1195 {
1196     ANGLE_SCOPED_GLOBAL_LOCK();
1197     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint index = %d, void *key = 0x%016" PRIxPTR
1198                ", EGLint *keysize = "
1199                "0x%016" PRIxPTR ", void *binary = 0x%016" PRIxPTR ", EGLint *size = 0x%016" PRIxPTR,
1200                (uintptr_t)dpy, index, (uintptr_t)key, (uintptr_t)keysize, (uintptr_t)binary,
1201                (uintptr_t)binarysize);
1202 
1203     egl::Display *display = static_cast<egl::Display *>(dpy);
1204     Thread *thread        = egl::GetCurrentThread();
1205 
1206     ANGLE_EGL_TRY(thread,
1207                   ValidateProgramCacheQueryANGLE(display, index, key, keysize, binary, binarysize),
1208                   "eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
1209 
1210     ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize),
1211                   "eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
1212 
1213     thread->setSuccess();
1214 }
1215 
EGL_ProgramCachePopulateANGLE(EGLDisplay dpy,const void * key,EGLint keysize,const void * binary,EGLint binarysize)1216 void EGLAPIENTRY EGL_ProgramCachePopulateANGLE(EGLDisplay dpy,
1217                                                const void *key,
1218                                                EGLint keysize,
1219                                                const void *binary,
1220                                                EGLint binarysize)
1221 {
1222     ANGLE_SCOPED_GLOBAL_LOCK();
1223     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", void *key = 0x%016" PRIxPTR
1224                ", EGLint keysize = %d, void *binary = "
1225                "0x%016" PRIxPTR ", EGLint size = %d",
1226                (uintptr_t)dpy, (uintptr_t)key, keysize, (uintptr_t)binary, binarysize);
1227 
1228     egl::Display *display = static_cast<egl::Display *>(dpy);
1229     Thread *thread        = egl::GetCurrentThread();
1230 
1231     ANGLE_EGL_TRY(thread,
1232                   ValidateProgramCachePopulateANGLE(display, key, keysize, binary, binarysize),
1233                   "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
1234 
1235     ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize),
1236                   "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
1237 
1238     thread->setSuccess();
1239 }
1240 
EGL_ProgramCacheResizeANGLE(EGLDisplay dpy,EGLint limit,EGLenum mode)1241 EGLint EGLAPIENTRY EGL_ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode)
1242 {
1243     ANGLE_SCOPED_GLOBAL_LOCK();
1244     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint limit = %d, EGLenum mode = 0x%X",
1245                (uintptr_t)dpy, limit, mode);
1246 
1247     egl::Display *display = static_cast<egl::Display *>(dpy);
1248     Thread *thread        = egl::GetCurrentThread();
1249 
1250     ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheResizeANGLE(display, limit, mode),
1251                          "eglProgramCacheResizeANGLE", GetDisplayIfValid(display), 0);
1252 
1253     thread->setSuccess();
1254     return display->programCacheResize(limit, mode);
1255 }
1256 
EGL_DebugMessageControlKHR(EGLDEBUGPROCKHR callback,const EGLAttrib * attrib_list)1257 EGLint EGLAPIENTRY EGL_DebugMessageControlKHR(EGLDEBUGPROCKHR callback,
1258                                               const EGLAttrib *attrib_list)
1259 {
1260     ANGLE_SCOPED_GLOBAL_LOCK();
1261     FUNC_EVENT("EGLDEBUGPROCKHR callback = 0x%016" PRIxPTR
1262                ", EGLAttrib attrib_list = 0x%016" PRIxPTR,
1263                (uintptr_t)callback, (uintptr_t)attrib_list);
1264 
1265     Thread *thread = egl::GetCurrentThread();
1266 
1267     AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
1268 
1269     Error error = ValidateDebugMessageControlKHR(callback, attributes);
1270     if (error.isError())
1271     {
1272         thread->setError(error, GetDebug(), "eglDebugMessageControlKHR", nullptr);
1273         return error.getCode();
1274     }
1275 
1276     Debug *debug = GetDebug();
1277     debug->setCallback(callback, attributes);
1278 
1279     thread->setSuccess();
1280     return EGL_SUCCESS;
1281 }
1282 
EGL_QueryDebugKHR(EGLint attribute,EGLAttrib * value)1283 EGLBoolean EGLAPIENTRY EGL_QueryDebugKHR(EGLint attribute, EGLAttrib *value)
1284 {
1285     ANGLE_SCOPED_GLOBAL_LOCK();
1286     FUNC_EVENT("EGLint attribute = 0x%X, EGLAttrib* value = 0x%016" PRIxPTR, attribute,
1287                (uintptr_t)value);
1288 
1289     Thread *thread = egl::GetCurrentThread();
1290 
1291     Error error = ValidateQueryDebugKHR(attribute, value);
1292     if (error.isError())
1293     {
1294         thread->setError(error, GetDebug(), "eglQueryDebugKHR", nullptr);
1295         return EGL_FALSE;
1296     }
1297 
1298     Debug *debug = GetDebug();
1299     switch (attribute)
1300     {
1301         case EGL_DEBUG_MSG_CRITICAL_KHR:
1302         case EGL_DEBUG_MSG_ERROR_KHR:
1303         case EGL_DEBUG_MSG_WARN_KHR:
1304         case EGL_DEBUG_MSG_INFO_KHR:
1305             *value = debug->isMessageTypeEnabled(FromEGLenum<MessageType>(attribute)) ? EGL_TRUE
1306                                                                                       : EGL_FALSE;
1307             break;
1308         case EGL_DEBUG_CALLBACK_KHR:
1309             *value = reinterpret_cast<EGLAttrib>(debug->getCallback());
1310             break;
1311 
1312         default:
1313             UNREACHABLE();
1314     }
1315 
1316     thread->setSuccess();
1317     return EGL_TRUE;
1318 }
1319 
EGL_LabelObjectKHR(EGLDisplay dpy,EGLenum objectType,EGLObjectKHR object,EGLLabelKHR label)1320 EGLint EGLAPIENTRY EGL_LabelObjectKHR(EGLDisplay dpy,
1321                                       EGLenum objectType,
1322                                       EGLObjectKHR object,
1323                                       EGLLabelKHR label)
1324 {
1325     ANGLE_SCOPED_GLOBAL_LOCK();
1326     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR
1327                ", EGLenum objectType = 0x%X, EGLObjectKHR object = 0x%016" PRIxPTR
1328                ", "
1329                "EGLLabelKHR label = 0x%016" PRIxPTR,
1330                (uintptr_t)dpy, objectType, (uintptr_t)object, (uintptr_t)label);
1331 
1332     egl::Display *display = static_cast<egl::Display *>(dpy);
1333     Thread *thread        = egl::GetCurrentThread();
1334 
1335     ObjectType objectTypePacked = FromEGLenum<ObjectType>(objectType);
1336     Error error = ValidateLabelObjectKHR(thread, display, objectTypePacked, object, label);
1337     if (error.isError())
1338     {
1339         thread->setError(error, GetDebug(), "eglLabelObjectKHR",
1340                          GetLabeledObjectIfValid(thread, display, objectTypePacked, object));
1341         return error.getCode();
1342     }
1343 
1344     LabeledObject *labeledObject =
1345         GetLabeledObjectIfValid(thread, display, objectTypePacked, object);
1346     ASSERT(labeledObject != nullptr);
1347     labeledObject->setLabel(label);
1348 
1349     thread->setSuccess();
1350     return EGL_SUCCESS;
1351 }
1352 
EGL_GetCompositorTimingSupportedANDROID(EGLDisplay dpy,EGLSurface surface,EGLint name)1353 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingSupportedANDROID(EGLDisplay dpy,
1354                                                                             EGLSurface surface,
1355                                                                             EGLint name)
1356 {
1357     ANGLE_SCOPED_GLOBAL_LOCK();
1358     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1359                ", EGLint name = 0x%X",
1360                (uintptr_t)dpy, (uintptr_t)surface, name);
1361 
1362     egl::Display *display = static_cast<egl::Display *>(dpy);
1363     Surface *eglSurface   = static_cast<Surface *>(surface);
1364     Thread *thread        = egl::GetCurrentThread();
1365 
1366     CompositorTiming nameInternal = FromEGLenum<CompositorTiming>(name);
1367 
1368     ANGLE_EGL_TRY_RETURN(
1369         thread, ValidateGetCompositorTimingSupportedANDROID(display, eglSurface, nameInternal),
1370         "eglQueryTimestampSupportedANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
1371 
1372     thread->setSuccess();
1373     return eglSurface->getSupportedCompositorTimings().test(nameInternal);
1374 }
1375 
EGL_GetCompositorTimingANDROID(EGLDisplay dpy,EGLSurface surface,EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values)1376 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingANDROID(EGLDisplay dpy,
1377                                                                    EGLSurface surface,
1378                                                                    EGLint numTimestamps,
1379                                                                    const EGLint *names,
1380                                                                    EGLnsecsANDROID *values)
1381 {
1382     ANGLE_SCOPED_GLOBAL_LOCK();
1383     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1384                ", EGLint numTimestamps = %d, const EGLint *names = 0x%016" PRIxPTR
1385                ", EGLnsecsANDROID *values = 0x%016" PRIxPTR,
1386                (uintptr_t)dpy, (uintptr_t)surface, numTimestamps, (uintptr_t)names,
1387                (uintptr_t)values);
1388 
1389     egl::Display *display = static_cast<egl::Display *>(dpy);
1390     Surface *eglSurface   = static_cast<Surface *>(surface);
1391     Thread *thread        = egl::GetCurrentThread();
1392 
1393     ANGLE_EGL_TRY_RETURN(
1394         thread,
1395         ValidateGetCompositorTimingANDROID(display, eglSurface, numTimestamps, names, values),
1396         "eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
1397     ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
1398                          "eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface),
1399                          EGL_FALSE);
1400 
1401     thread->setSuccess();
1402     return EGL_TRUE;
1403 }
1404 
EGL_GetNextFrameIdANDROID(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR * frameId)1405 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetNextFrameIdANDROID(EGLDisplay dpy,
1406                                                               EGLSurface surface,
1407                                                               EGLuint64KHR *frameId)
1408 {
1409     ANGLE_SCOPED_GLOBAL_LOCK();
1410     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1411                ", EGLuint64KHR *frameId = 0x%016" PRIxPTR,
1412                (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)frameId);
1413 
1414     egl::Display *display = static_cast<egl::Display *>(dpy);
1415     Surface *eglSurface   = static_cast<Surface *>(surface);
1416     Thread *thread        = egl::GetCurrentThread();
1417 
1418     ANGLE_EGL_TRY_RETURN(thread, ValidateGetNextFrameIdANDROID(display, eglSurface, frameId),
1419                          "eglGetNextFrameIdANDROID", GetSurfaceIfValid(display, eglSurface),
1420                          EGL_FALSE);
1421     ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
1422                          GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
1423 
1424     thread->setSuccess();
1425     return EGL_TRUE;
1426 }
1427 
EGL_GetFrameTimestampSupportedANDROID(EGLDisplay dpy,EGLSurface surface,EGLint timestamp)1428 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampSupportedANDROID(EGLDisplay dpy,
1429                                                                           EGLSurface surface,
1430                                                                           EGLint timestamp)
1431 {
1432     ANGLE_SCOPED_GLOBAL_LOCK();
1433     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1434                ", EGLint timestamp = 0x%X",
1435                (uintptr_t)dpy, (uintptr_t)surface, timestamp);
1436 
1437     egl::Display *display = static_cast<egl::Display *>(dpy);
1438     Surface *eglSurface   = static_cast<Surface *>(surface);
1439     Thread *thread        = egl::GetCurrentThread();
1440 
1441     Timestamp timestampInternal = FromEGLenum<Timestamp>(timestamp);
1442 
1443     ANGLE_EGL_TRY_RETURN(
1444         thread, ValidateGetFrameTimestampSupportedANDROID(display, eglSurface, timestampInternal),
1445         "eglQueryTimestampSupportedANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
1446 
1447     thread->setSuccess();
1448     return eglSurface->getSupportedTimestamps().test(timestampInternal);
1449 }
1450 
EGL_GetFrameTimestampsANDROID(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)1451 ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampsANDROID(EGLDisplay dpy,
1452                                                                   EGLSurface surface,
1453                                                                   EGLuint64KHR frameId,
1454                                                                   EGLint numTimestamps,
1455                                                                   const EGLint *timestamps,
1456                                                                   EGLnsecsANDROID *values)
1457 {
1458     ANGLE_SCOPED_GLOBAL_LOCK();
1459     FUNC_EVENT(
1460         "EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1461         ", EGLuint64KHR frameId = %llu, EGLint numTimestamps = %d, const EGLint *timestamps = "
1462         "0x%016" PRIxPTR ", EGLnsecsANDROID *values = 0x%016" PRIxPTR,
1463         (uintptr_t)dpy, (uintptr_t)surface, (unsigned long long)frameId, numTimestamps,
1464         (uintptr_t)timestamps, (uintptr_t)values);
1465 
1466     egl::Display *display = static_cast<egl::Display *>(dpy);
1467     Surface *eglSurface   = static_cast<Surface *>(surface);
1468     Thread *thread        = egl::GetCurrentThread();
1469 
1470     ANGLE_EGL_TRY_RETURN(thread,
1471                          ValidateGetFrameTimestampsANDROID(display, eglSurface, frameId,
1472                                                            numTimestamps, timestamps, values),
1473                          "eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface),
1474                          EGL_FALSE);
1475     ANGLE_EGL_TRY_RETURN(
1476         thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
1477         "eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
1478 
1479     thread->setSuccess();
1480     return EGL_TRUE;
1481 }
1482 
1483 // EGL_ANGLE_feature_control
EGL_QueryStringiANGLE(EGLDisplay dpy,EGLint name,EGLint index)1484 ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy,
1485                                                            EGLint name,
1486                                                            EGLint index)
1487 {
1488     ANGLE_SCOPED_GLOBAL_LOCK();
1489     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint name = %d, EGLint index = %d",
1490                (uintptr_t)dpy, name, index);
1491 
1492     egl::Display *display = static_cast<egl::Display *>(dpy);
1493     Thread *thread        = egl::GetCurrentThread();
1494 
1495     ANGLE_EGL_TRY_RETURN(thread, ValidateQueryStringiANGLE(display, name, index),
1496                          "eglQueryStringiANGLE", GetDisplayIfValid(display), nullptr);
1497 
1498     thread->setSuccess();
1499     return display->queryStringi(name, index);
1500 }
1501 
EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer * buffer)1502 EGLClientBuffer EGLAPIENTRY EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer)
1503 {
1504     ANGLE_SCOPED_GLOBAL_LOCK();
1505     FUNC_EVENT("const struct AHardwareBuffer *buffer = 0x%016" PRIxPTR, (uintptr_t)buffer);
1506 
1507     Thread *thread = egl::GetCurrentThread();
1508 
1509     ANGLE_EGL_TRY_RETURN(thread, ValidateGetNativeClientBufferANDROID(buffer),
1510                          "eglGetNativeClientBufferANDROID", nullptr, nullptr);
1511 
1512     thread->setSuccess();
1513     return egl::Display::GetNativeClientBuffer(buffer);
1514 }
1515 
EGL_DupNativeFenceFDANDROID(EGLDisplay dpy,EGLSyncKHR sync)1516 EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
1517 {
1518     ANGLE_SCOPED_GLOBAL_LOCK();
1519     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSyncKHR sync = 0x%016" PRIxPTR,
1520                (uintptr_t)dpy, (uintptr_t)sync);
1521 
1522     egl::Display *display = static_cast<egl::Display *>(dpy);
1523     Sync *syncObject      = static_cast<Sync *>(sync);
1524     Thread *thread        = egl::GetCurrentThread();
1525 
1526     ANGLE_EGL_TRY_RETURN(thread, ValidateDupNativeFenceFDANDROID(display, syncObject),
1527                          "eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
1528                          EGL_NO_NATIVE_FENCE_FD_ANDROID);
1529 
1530     EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
1531     ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
1532                          "eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
1533                          EGL_NO_NATIVE_FENCE_FD_ANDROID);
1534 
1535     thread->setSuccess();
1536     return result;
1537 }
1538 
EGL_SwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,EGLSurface surface,EGLFrameTokenANGLE frametoken)1539 EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
1540                                                           EGLSurface surface,
1541                                                           EGLFrameTokenANGLE frametoken)
1542 {
1543     ANGLE_SCOPED_GLOBAL_LOCK();
1544     FUNC_EVENT("EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
1545                ", EGLFrameTokenANGLE frametoken = 0x%llX",
1546                (uintptr_t)dpy, (uintptr_t)surface, (unsigned long long)frametoken);
1547 
1548     egl::Display *display    = static_cast<egl::Display *>(dpy);
1549     egl::Surface *eglSurface = static_cast<egl::Surface *>(surface);
1550     Thread *thread           = egl::GetCurrentThread();
1551 
1552     ANGLE_EGL_TRY_RETURN(
1553         thread, ValidateSwapBuffersWithFrameTokenANGLE(display, eglSurface, frametoken),
1554         "eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display), EGL_FALSE);
1555 
1556     ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithFrameToken(thread->getContext(), frametoken),
1557                          "eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display),
1558                          EGL_FALSE);
1559 
1560     thread->setSuccess();
1561     return EGL_TRUE;
1562 }
1563 }  // extern "C"
1564