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