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