1 //
2 // Copyright 2020 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 // egl_ext_stubs.cpp: Stubs for EXT extension entry points.
7 //
8
9 #include "libGLESv2/egl_ext_stubs_autogen.h"
10
11 #include "libANGLE/Device.h"
12 #include "libANGLE/Display.h"
13 #include "libANGLE/EGLSync.h"
14 #include "libANGLE/Surface.h"
15 #include "libANGLE/Thread.h"
16 #include "libANGLE/entry_points_utils.h"
17 #include "libANGLE/queryutils.h"
18 #include "libANGLE/renderer/DisplayImpl.h"
19 #include "libANGLE/validationEGL.h"
20 #include "libANGLE/validationEGL_autogen.h"
21 #include "libGLESv2/global_state.h"
22
23 namespace egl
24 {
ClientWaitSyncKHR(Thread * thread,Display * display,Sync * syncObject,EGLint flags,EGLTimeKHR timeout)25 EGLint ClientWaitSyncKHR(Thread *thread,
26 Display *display,
27 Sync *syncObject,
28 EGLint flags,
29 EGLTimeKHR timeout)
30 {
31 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
32 GetDisplayIfValid(display), EGL_FALSE);
33 gl::Context *currentContext = thread->getContext();
34 EGLint syncStatus = EGL_FALSE;
35 ANGLE_EGL_TRY_RETURN(
36 thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
37 "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
38
39 thread->setSuccess();
40 return syncStatus;
41 }
42
CreateImageKHR(Thread * thread,Display * display,gl::Context * context,EGLenum target,EGLClientBuffer buffer,const AttributeMap & attributes)43 EGLImageKHR CreateImageKHR(Thread *thread,
44 Display *display,
45 gl::Context *context,
46 EGLenum target,
47 EGLClientBuffer buffer,
48 const AttributeMap &attributes)
49 {
50 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImageKHR",
51 GetDisplayIfValid(display), EGL_NO_IMAGE);
52 Image *image = nullptr;
53 ANGLE_EGL_TRY_RETURN(thread, display->createImage(context, target, buffer, attributes, &image),
54 "", GetDisplayIfValid(display), EGL_NO_IMAGE);
55
56 thread->setSuccess();
57 return static_cast<EGLImage>(image);
58 }
59
CreateNativeClientBufferANDROID(Thread * thread,const AttributeMap & attribMap)60 EGLClientBuffer CreateNativeClientBufferANDROID(Thread *thread, const AttributeMap &attribMap)
61 {
62 EGLClientBuffer eglClientBuffer = nullptr;
63 ANGLE_EGL_TRY_RETURN(thread,
64 egl::Display::CreateNativeClientBuffer(attribMap, &eglClientBuffer),
65 "eglCreateNativeClientBufferANDROID", nullptr, nullptr);
66
67 thread->setSuccess();
68 return eglClientBuffer;
69 }
70
CreatePlatformPixmapSurfaceEXT(Thread * thread,Display * display,Config * configPacked,void * native_pixmap,const AttributeMap & attributes)71 EGLSurface CreatePlatformPixmapSurfaceEXT(Thread *thread,
72 Display *display,
73 Config *configPacked,
74 void *native_pixmap,
75 const AttributeMap &attributes)
76 {
77 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurfaceEXT",
78 GetDisplayIfValid(display), EGL_NO_SURFACE);
79 thread->setError(EGL_BAD_DISPLAY, "eglCreatePlatformPixmapSurfaceEXT",
80 GetDisplayIfValid(display), "CreatePlatformPixmapSurfaceEXT unimplemented.");
81 return EGL_NO_SURFACE;
82 }
83
CreatePlatformWindowSurfaceEXT(Thread * thread,Display * display,Config * configPacked,void * native_window,const AttributeMap & attributes)84 EGLSurface CreatePlatformWindowSurfaceEXT(Thread *thread,
85 Display *display,
86 Config *configPacked,
87 void *native_window,
88 const AttributeMap &attributes)
89 {
90 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformWindowSurfaceEXT",
91 GetDisplayIfValid(display), EGL_NO_SURFACE);
92 Surface *surface = nullptr;
93
94 // In X11, eglCreatePlatformWindowSurfaceEXT expects the native_window argument to be a pointer
95 // to a Window while the EGLNativeWindowType for X11 is its actual value.
96 // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_platform_x11.txt
97 void *actualNativeWindow = display->getImplementation()->isX11()
98 ? *reinterpret_cast<void **>(native_window)
99 : native_window;
100 EGLNativeWindowType nativeWindow = reinterpret_cast<EGLNativeWindowType>(actualNativeWindow);
101
102 ANGLE_EGL_TRY_RETURN(
103 thread, display->createWindowSurface(configPacked, nativeWindow, attributes, &surface),
104 "eglPlatformCreateWindowSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
105
106 return static_cast<EGLSurface>(surface);
107 }
108
CreateStreamKHR(Thread * thread,Display * display,const AttributeMap & attributes)109 EGLStreamKHR CreateStreamKHR(Thread *thread, Display *display, const AttributeMap &attributes)
110 {
111 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateStreamKHR",
112 GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
113 Stream *stream;
114 ANGLE_EGL_TRY_RETURN(thread, display->createStream(attributes, &stream), "eglCreateStreamKHR",
115 GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
116
117 thread->setSuccess();
118 return static_cast<EGLStreamKHR>(stream);
119 }
120
CreateSyncKHR(Thread * thread,Display * display,EGLenum type,const AttributeMap & attributes)121 EGLSyncKHR CreateSyncKHR(Thread *thread,
122 Display *display,
123 EGLenum type,
124 const AttributeMap &attributes)
125 {
126 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSyncKHR",
127 GetDisplayIfValid(display), EGL_NO_SYNC);
128 egl::Sync *syncObject = nullptr;
129 ANGLE_EGL_TRY_RETURN(thread,
130 display->createSync(thread->getContext(), type, attributes, &syncObject),
131 "eglCreateSyncKHR", GetDisplayIfValid(display), EGL_NO_SYNC);
132
133 thread->setSuccess();
134 return static_cast<EGLSync>(syncObject);
135 }
136
DebugMessageControlKHR(Thread * thread,EGLDEBUGPROCKHR callback,const AttributeMap & attributes)137 EGLint DebugMessageControlKHR(Thread *thread,
138 EGLDEBUGPROCKHR callback,
139 const AttributeMap &attributes)
140 {
141 Debug *debug = GetDebug();
142 debug->setCallback(callback, attributes);
143
144 thread->setSuccess();
145 return EGL_SUCCESS;
146 }
147
DestroyImageKHR(Thread * thread,Display * display,Image * img)148 EGLBoolean DestroyImageKHR(Thread *thread, Display *display, Image *img)
149 {
150 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImageKHR",
151 GetDisplayIfValid(display), EGL_FALSE);
152 display->destroyImage(img);
153
154 thread->setSuccess();
155 return EGL_TRUE;
156 }
157
DestroyStreamKHR(Thread * thread,Display * display,Stream * streamObject)158 EGLBoolean DestroyStreamKHR(Thread *thread, Display *display, Stream *streamObject)
159 {
160 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyStreamKHR",
161 GetDisplayIfValid(display), EGL_FALSE);
162 display->destroyStream(streamObject);
163
164 thread->setSuccess();
165 return EGL_TRUE;
166 }
167
DestroySyncKHR(Thread * thread,Display * display,Sync * syncObject)168 EGLBoolean DestroySyncKHR(Thread *thread, Display *display, Sync *syncObject)
169 {
170 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
171 GetDisplayIfValid(display), EGL_FALSE);
172 display->destroySync(syncObject);
173
174 thread->setSuccess();
175 return EGL_TRUE;
176 }
177
DupNativeFenceFDANDROID(Thread * thread,Display * display,Sync * syncObject)178 EGLint DupNativeFenceFDANDROID(Thread *thread, Display *display, Sync *syncObject)
179 {
180 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDupNativeFenceFDANDROID",
181 GetDisplayIfValid(display), EGL_NO_NATIVE_FENCE_FD_ANDROID);
182 EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
183 ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
184 "eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
185 EGL_NO_NATIVE_FENCE_FD_ANDROID);
186
187 thread->setSuccess();
188 return result;
189 }
190
GetNativeClientBufferANDROID(Thread * thread,const struct AHardwareBuffer * buffer)191 EGLClientBuffer GetNativeClientBufferANDROID(Thread *thread, const struct AHardwareBuffer *buffer)
192 {
193 thread->setSuccess();
194 return egl::Display::GetNativeClientBuffer(buffer);
195 }
196
GetPlatformDisplayEXT(Thread * thread,EGLenum platform,void * native_display,const AttributeMap & attribMap)197 EGLDisplay GetPlatformDisplayEXT(Thread *thread,
198 EGLenum platform,
199 void *native_display,
200 const AttributeMap &attribMap)
201 {
202 if (platform == EGL_PLATFORM_ANGLE_ANGLE)
203 {
204 return egl::Display::GetDisplayFromNativeDisplay(
205 gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
206 }
207 else if (platform == EGL_PLATFORM_DEVICE_EXT)
208 {
209 Device *eglDevice = static_cast<Device *>(native_display);
210 return egl::Display::GetDisplayFromDevice(eglDevice, attribMap);
211 }
212 else
213 {
214 UNREACHABLE();
215 return EGL_NO_DISPLAY;
216 }
217 }
218
GetSyncAttribKHR(Thread * thread,Display * display,Sync * syncObject,EGLint attribute,EGLint * value)219 EGLBoolean GetSyncAttribKHR(Thread *thread,
220 Display *display,
221 Sync *syncObject,
222 EGLint attribute,
223 EGLint *value)
224 {
225 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncAttrib",
226 GetDisplayIfValid(display), EGL_FALSE);
227 ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
228 "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
229
230 thread->setSuccess();
231 return EGL_TRUE;
232 }
233
LabelObjectKHR(Thread * thread,Display * display,ObjectType objectTypePacked,EGLObjectKHR object,EGLLabelKHR label)234 EGLint LabelObjectKHR(Thread *thread,
235 Display *display,
236 ObjectType objectTypePacked,
237 EGLObjectKHR object,
238 EGLLabelKHR label)
239 {
240 LabeledObject *labeledObject =
241 GetLabeledObjectIfValid(thread, display, objectTypePacked, object);
242 ASSERT(labeledObject != nullptr);
243 labeledObject->setLabel(label);
244
245 thread->setSuccess();
246 return EGL_SUCCESS;
247 }
248
PostSubBufferNV(Thread * thread,Display * display,Surface * eglSurface,EGLint x,EGLint y,EGLint width,EGLint height)249 EGLBoolean PostSubBufferNV(Thread *thread,
250 Display *display,
251 Surface *eglSurface,
252 EGLint x,
253 EGLint y,
254 EGLint width,
255 EGLint height)
256 {
257 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPostSubBufferNV",
258 GetDisplayIfValid(display), EGL_FALSE);
259 Error error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
260 if (error.isError())
261 {
262 thread->setError(error, "eglPostSubBufferNV", GetSurfaceIfValid(display, eglSurface));
263 return EGL_FALSE;
264 }
265
266 thread->setSuccess();
267 return EGL_TRUE;
268 }
269
PresentationTimeANDROID(Thread * thread,Display * display,Surface * eglSurface,EGLnsecsANDROID time)270 EGLBoolean PresentationTimeANDROID(Thread *thread,
271 Display *display,
272 Surface *eglSurface,
273 EGLnsecsANDROID time)
274 {
275 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPresentationTimeANDROID",
276 GetDisplayIfValid(display), EGL_FALSE);
277 ANGLE_EGL_TRY_RETURN(thread, eglSurface->setPresentationTime(time),
278 "eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
279 EGL_FALSE);
280
281 return EGL_TRUE;
282 }
283
GetCompositorTimingSupportedANDROID(Thread * thread,Display * display,Surface * eglSurface,CompositorTiming nameInternal)284 EGLBoolean GetCompositorTimingSupportedANDROID(Thread *thread,
285 Display *display,
286 Surface *eglSurface,
287 CompositorTiming nameInternal)
288 {
289 thread->setSuccess();
290 return eglSurface->getSupportedCompositorTimings().test(nameInternal);
291 }
292
GetCompositorTimingANDROID(Thread * thread,Display * display,Surface * eglSurface,EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values)293 EGLBoolean GetCompositorTimingANDROID(Thread *thread,
294 Display *display,
295 Surface *eglSurface,
296 EGLint numTimestamps,
297 const EGLint *names,
298 EGLnsecsANDROID *values)
299 {
300 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetCompositorTimingANDROIDD",
301 GetDisplayIfValid(display), EGL_FALSE);
302 ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
303 "eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface),
304 EGL_FALSE);
305
306 thread->setSuccess();
307 return EGL_TRUE;
308 }
309
GetNextFrameIdANDROID(Thread * thread,Display * display,Surface * eglSurface,EGLuint64KHR * frameId)310 EGLBoolean GetNextFrameIdANDROID(Thread *thread,
311 Display *display,
312 Surface *eglSurface,
313 EGLuint64KHR *frameId)
314 {
315 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetNextFrameIdANDROID",
316 GetDisplayIfValid(display), EGL_FALSE);
317 ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
318 GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
319
320 thread->setSuccess();
321 return EGL_TRUE;
322 }
323
GetFrameTimestampSupportedANDROID(Thread * thread,Display * display,Surface * eglSurface,Timestamp timestampInternal)324 EGLBoolean GetFrameTimestampSupportedANDROID(Thread *thread,
325 Display *display,
326 Surface *eglSurface,
327 Timestamp timestampInternal)
328 {
329 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryTimestampSupportedANDROID",
330 GetDisplayIfValid(display), EGL_FALSE);
331 thread->setSuccess();
332 return eglSurface->getSupportedTimestamps().test(timestampInternal);
333 }
334
GetFrameTimestampsANDROID(Thread * thread,Display * display,Surface * eglSurface,EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values)335 EGLBoolean GetFrameTimestampsANDROID(Thread *thread,
336 Display *display,
337 Surface *eglSurface,
338 EGLuint64KHR frameId,
339 EGLint numTimestamps,
340 const EGLint *timestamps,
341 EGLnsecsANDROID *values)
342 {
343 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetFrameTimestampsANDROID",
344 GetDisplayIfValid(display), EGL_FALSE);
345 ANGLE_EGL_TRY_RETURN(
346 thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
347 "eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
348
349 thread->setSuccess();
350 return EGL_TRUE;
351 }
352
QueryDebugKHR(Thread * thread,EGLint attribute,EGLAttrib * value)353 EGLBoolean QueryDebugKHR(Thread *thread, EGLint attribute, EGLAttrib *value)
354 {
355 Debug *debug = GetDebug();
356 switch (attribute)
357 {
358 case EGL_DEBUG_MSG_CRITICAL_KHR:
359 case EGL_DEBUG_MSG_ERROR_KHR:
360 case EGL_DEBUG_MSG_WARN_KHR:
361 case EGL_DEBUG_MSG_INFO_KHR:
362 *value = debug->isMessageTypeEnabled(FromEGLenum<MessageType>(attribute)) ? EGL_TRUE
363 : EGL_FALSE;
364 break;
365 case EGL_DEBUG_CALLBACK_KHR:
366 *value = reinterpret_cast<EGLAttrib>(debug->getCallback());
367 break;
368
369 default:
370 UNREACHABLE();
371 }
372
373 thread->setSuccess();
374 return EGL_TRUE;
375 }
376
QueryDeviceAttribEXT(Thread * thread,Device * dev,EGLint attribute,EGLAttrib * value)377 EGLBoolean QueryDeviceAttribEXT(Thread *thread, Device *dev, EGLint attribute, EGLAttrib *value)
378 {
379 ANGLE_EGL_TRY_RETURN(thread, dev->getAttribute(attribute, value), "eglQueryDeviceAttribEXT",
380 GetDeviceIfValid(dev), EGL_FALSE);
381
382 thread->setSuccess();
383 return EGL_TRUE;
384 }
385
QueryDeviceStringEXT(Thread * thread,Device * dev,EGLint name)386 const char *QueryDeviceStringEXT(Thread *thread, Device *dev, EGLint name)
387 {
388 egl::Display *owningDisplay = dev->getOwningDisplay();
389 ANGLE_EGL_TRY_RETURN(thread, owningDisplay->prepareForCall(), "eglQueryDeviceStringEXT",
390 GetDisplayIfValid(owningDisplay), EGL_FALSE);
391 const char *result;
392 switch (name)
393 {
394 case EGL_EXTENSIONS:
395 result = dev->getExtensionString().c_str();
396 break;
397 default:
398 thread->setError(EglBadDevice(), "eglQueryDeviceStringEXT", GetDeviceIfValid(dev));
399 return nullptr;
400 }
401
402 thread->setSuccess();
403 return result;
404 }
405
QueryDisplayAttribEXT(Thread * thread,Display * display,EGLint attribute,EGLAttrib * value)406 EGLBoolean QueryDisplayAttribEXT(Thread *thread,
407 Display *display,
408 EGLint attribute,
409 EGLAttrib *value)
410 {
411 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribEXT",
412 GetDisplayIfValid(display), EGL_FALSE);
413 *value = display->queryAttrib(attribute);
414 thread->setSuccess();
415 return EGL_TRUE;
416 }
417
QueryStreamKHR(Thread * thread,Display * display,Stream * streamObject,EGLenum attribute,EGLint * value)418 EGLBoolean QueryStreamKHR(Thread *thread,
419 Display *display,
420 Stream *streamObject,
421 EGLenum attribute,
422 EGLint *value)
423 {
424 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamKHR",
425 GetDisplayIfValid(display), EGL_FALSE);
426 switch (attribute)
427 {
428 case EGL_STREAM_STATE_KHR:
429 *value = streamObject->getState();
430 break;
431 case EGL_CONSUMER_LATENCY_USEC_KHR:
432 *value = streamObject->getConsumerLatency();
433 break;
434 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
435 *value = streamObject->getConsumerAcquireTimeout();
436 break;
437 default:
438 UNREACHABLE();
439 }
440
441 thread->setSuccess();
442 return EGL_TRUE;
443 }
444
QueryStreamu64KHR(Thread * thread,Display * display,Stream * streamObject,EGLenum attribute,EGLuint64KHR * value)445 EGLBoolean QueryStreamu64KHR(Thread *thread,
446 Display *display,
447 Stream *streamObject,
448 EGLenum attribute,
449 EGLuint64KHR *value)
450 {
451 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamu64KHR",
452 GetDisplayIfValid(display), EGL_FALSE);
453 switch (attribute)
454 {
455 case EGL_PRODUCER_FRAME_KHR:
456 *value = streamObject->getProducerFrame();
457 break;
458 case EGL_CONSUMER_FRAME_KHR:
459 *value = streamObject->getConsumerFrame();
460 break;
461 default:
462 UNREACHABLE();
463 }
464
465 thread->setSuccess();
466 return EGL_TRUE;
467 }
468
QuerySurfacePointerANGLE(Thread * thread,Display * display,Surface * eglSurface,EGLint attribute,void ** value)469 EGLBoolean QuerySurfacePointerANGLE(Thread *thread,
470 Display *display,
471 Surface *eglSurface,
472 EGLint attribute,
473 void **value)
474 {
475 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurfacePointerANGLE",
476 GetDisplayIfValid(display), EGL_FALSE);
477 Error error = eglSurface->querySurfacePointerANGLE(attribute, value);
478 if (error.isError())
479 {
480 thread->setError(error, "eglQuerySurfacePointerANGLE",
481 GetSurfaceIfValid(display, eglSurface));
482 return EGL_FALSE;
483 }
484
485 thread->setSuccess();
486 return EGL_TRUE;
487 }
488
SetBlobCacheFuncsANDROID(Thread * thread,Display * display,EGLSetBlobFuncANDROID set,EGLGetBlobFuncANDROID get)489 void SetBlobCacheFuncsANDROID(Thread *thread,
490 Display *display,
491 EGLSetBlobFuncANDROID set,
492 EGLGetBlobFuncANDROID get)
493 {
494 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglSetBlobCacheFuncsANDROID",
495 GetDisplayIfValid(display));
496 thread->setSuccess();
497 display->setBlobCacheFuncs(set, get);
498 }
499
SignalSyncKHR(Thread * thread,Display * display,Sync * syncObject,EGLenum mode)500 EGLBoolean SignalSyncKHR(Thread *thread, Display *display, Sync *syncObject, EGLenum mode)
501 {
502 gl::Context *currentContext = thread->getContext();
503 ANGLE_EGL_TRY_RETURN(thread, syncObject->signal(display, currentContext, mode),
504 "eglSignalSyncKHR", GetSyncIfValid(display, syncObject), EGL_FALSE);
505
506 thread->setSuccess();
507 return EGL_TRUE;
508 }
509
StreamAttribKHR(Thread * thread,Display * display,Stream * streamObject,EGLenum attribute,EGLint value)510 EGLBoolean StreamAttribKHR(Thread *thread,
511 Display *display,
512 Stream *streamObject,
513 EGLenum attribute,
514 EGLint value)
515 {
516 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamAttribKHR",
517 GetDisplayIfValid(display), EGL_FALSE);
518 switch (attribute)
519 {
520 case EGL_CONSUMER_LATENCY_USEC_KHR:
521 streamObject->setConsumerLatency(value);
522 break;
523 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
524 streamObject->setConsumerAcquireTimeout(value);
525 break;
526 default:
527 UNREACHABLE();
528 }
529
530 thread->setSuccess();
531 return EGL_TRUE;
532 }
533
StreamConsumerAcquireKHR(Thread * thread,Display * display,Stream * streamObject)534 EGLBoolean StreamConsumerAcquireKHR(Thread *thread, Display *display, Stream *streamObject)
535 {
536 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerAcquireKHR",
537 GetDisplayIfValid(display), EGL_FALSE);
538 ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerAcquire(thread->getContext()),
539 "eglStreamConsumerAcquireKHR", GetStreamIfValid(display, streamObject),
540 EGL_FALSE);
541 thread->setSuccess();
542 return EGL_TRUE;
543 }
544
StreamConsumerGLTextureExternalKHR(Thread * thread,Display * display,Stream * streamObject)545 EGLBoolean StreamConsumerGLTextureExternalKHR(Thread *thread,
546 Display *display,
547 Stream *streamObject)
548 {
549 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerGLTextureExternalKHR",
550 GetDisplayIfValid(display), EGL_FALSE);
551 ANGLE_EGL_TRY_RETURN(
552 thread, streamObject->createConsumerGLTextureExternal(AttributeMap(), thread->getContext()),
553 "eglStreamConsumerGLTextureExternalKHR", GetStreamIfValid(display, streamObject),
554 EGL_FALSE);
555 thread->setSuccess();
556 return EGL_TRUE;
557 }
558
StreamConsumerGLTextureExternalAttribsNV(Thread * thread,Display * display,Stream * streamObject,const AttributeMap & attributes)559 EGLBoolean StreamConsumerGLTextureExternalAttribsNV(Thread *thread,
560 Display *display,
561 Stream *streamObject,
562 const AttributeMap &attributes)
563 {
564 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
565 "eglStreamConsumerGLTextureExternalAttribsNV", GetDisplayIfValid(display),
566 EGL_FALSE);
567
568 gl::Context *context = gl::GetValidGlobalContext();
569 ANGLE_EGL_TRY_RETURN(thread, streamObject->createConsumerGLTextureExternal(attributes, context),
570 "eglStreamConsumerGLTextureExternalAttribsNV",
571 GetStreamIfValid(display, streamObject), EGL_FALSE);
572 thread->setSuccess();
573 return EGL_TRUE;
574 }
575
StreamConsumerReleaseKHR(Thread * thread,Display * display,Stream * streamObject)576 EGLBoolean StreamConsumerReleaseKHR(Thread *thread, Display *display, Stream *streamObject)
577 {
578 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerReleaseKHR",
579 GetDisplayIfValid(display), EGL_FALSE);
580
581 gl::Context *context = gl::GetValidGlobalContext();
582 ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerRelease(context),
583 "eglStreamConsumerReleaseKHR", GetStreamIfValid(display, streamObject),
584 EGL_FALSE);
585 thread->setSuccess();
586 return EGL_TRUE;
587 }
588
SwapBuffersWithDamageKHR(Thread * thread,Display * display,Surface * eglSurface,const EGLint * rects,EGLint n_rects)589 EGLBoolean SwapBuffersWithDamageKHR(Thread *thread,
590 Display *display,
591 Surface *eglSurface,
592 const EGLint *rects,
593 EGLint n_rects)
594 {
595 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithDamageEXT",
596 GetDisplayIfValid(display), EGL_FALSE);
597 ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithDamage(thread->getContext(), rects, n_rects),
598 "eglSwapBuffersWithDamageEXT", GetSurfaceIfValid(display, eglSurface),
599 EGL_FALSE);
600
601 thread->setSuccess();
602 return EGL_TRUE;
603 }
604
PrepareSwapBuffersANGLE(EGLDisplay dpy,EGLSurface surface)605 EGLBoolean PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface)
606
607 {
608 ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
609
610 egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
611 Surface *surfacePacked = PackParam<Surface *>(surface);
612 Thread *thread = egl::GetCurrentThread();
613 {
614 ANGLE_SCOPED_GLOBAL_LOCK();
615
616 EGL_EVENT(PrepareSwapBuffersANGLE, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "",
617 (uintptr_t)dpy, (uintptr_t)surface);
618
619 ANGLE_EGL_VALIDATE(thread, PrepareSwapBuffersANGLE, GetDisplayIfValid(dpyPacked),
620 EGLBoolean, dpyPacked, surfacePacked);
621
622 ANGLE_EGL_TRY_RETURN(thread, dpyPacked->prepareForCall(), "eglPrepareSwapBuffersANGLE",
623 GetDisplayIfValid(dpyPacked), EGL_FALSE);
624 }
625 ANGLE_EGL_TRY_RETURN(thread, surfacePacked->prepareSwap(thread->getContext()), "prepareSwap",
626 GetSurfaceIfValid(dpyPacked, surfacePacked), EGL_FALSE);
627
628 thread->setSuccess();
629 return EGL_TRUE;
630 }
631
WaitSyncKHR(Thread * thread,Display * display,Sync * syncObject,EGLint flags)632 EGLint WaitSyncKHR(Thread *thread, Display *display, Sync *syncObject, EGLint flags)
633 {
634 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitSync",
635 GetDisplayIfValid(display), EGL_FALSE);
636 gl::Context *currentContext = thread->getContext();
637 ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
638 "eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
639
640 thread->setSuccess();
641 return EGL_TRUE;
642 }
643
CreateDeviceANGLE(Thread * thread,EGLint device_type,void * native_device,const EGLAttrib * attrib_list)644 EGLDeviceEXT CreateDeviceANGLE(Thread *thread,
645 EGLint device_type,
646 void *native_device,
647 const EGLAttrib *attrib_list)
648 {
649 Device *device = nullptr;
650 ANGLE_EGL_TRY_RETURN(thread, Device::CreateDevice(device_type, native_device, &device),
651 "eglCreateDeviceANGLE", GetThreadIfValid(thread), EGL_NO_DEVICE_EXT);
652
653 thread->setSuccess();
654 return device;
655 }
656
ReleaseDeviceANGLE(Thread * thread,Device * dev)657 EGLBoolean ReleaseDeviceANGLE(Thread *thread, Device *dev)
658 {
659 SafeDelete(dev);
660
661 thread->setSuccess();
662 return EGL_TRUE;
663 }
664
CreateStreamProducerD3DTextureANGLE(Thread * thread,Display * display,Stream * streamObject,const AttributeMap & attributes)665 EGLBoolean CreateStreamProducerD3DTextureANGLE(Thread *thread,
666 Display *display,
667 Stream *streamObject,
668 const AttributeMap &attributes)
669 {
670 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
671 "eglCreateStreamProducerD3DTextureANGLE", GetDisplayIfValid(display),
672 EGL_FALSE);
673 ANGLE_EGL_TRY_RETURN(thread, streamObject->createProducerD3D11Texture(attributes),
674 "eglCreateStreamProducerD3DTextureANGLE",
675 GetStreamIfValid(display, streamObject), EGL_FALSE);
676 thread->setSuccess();
677 return EGL_TRUE;
678 }
679
StreamPostD3DTextureANGLE(Thread * thread,Display * display,Stream * streamObject,void * texture,const AttributeMap & attributes)680 EGLBoolean StreamPostD3DTextureANGLE(Thread *thread,
681 Display *display,
682 Stream *streamObject,
683 void *texture,
684 const AttributeMap &attributes)
685 {
686 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamPostD3DTextureANGLE",
687 GetDisplayIfValid(display), EGL_FALSE);
688 ANGLE_EGL_TRY_RETURN(thread, streamObject->postD3D11Texture(texture, attributes),
689 "eglStreamPostD3DTextureANGLE", GetStreamIfValid(display, streamObject),
690 EGL_FALSE);
691 thread->setSuccess();
692 return EGL_TRUE;
693 }
694
GetMscRateANGLE(Thread * thread,Display * display,Surface * eglSurface,EGLint * numerator,EGLint * denominator)695 EGLBoolean GetMscRateANGLE(Thread *thread,
696 Display *display,
697 Surface *eglSurface,
698 EGLint *numerator,
699 EGLint *denominator)
700 {
701 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetMscRateANGLE",
702 GetDisplayIfValid(display), EGL_FALSE);
703 ANGLE_EGL_TRY_RETURN(thread, eglSurface->getMscRate(numerator, denominator),
704 "eglGetMscRateANGLE", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
705
706 thread->setSuccess();
707 return EGL_TRUE;
708 }
709
GetSyncValuesCHROMIUM(Thread * thread,Display * display,Surface * eglSurface,EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)710 EGLBoolean GetSyncValuesCHROMIUM(Thread *thread,
711 Display *display,
712 Surface *eglSurface,
713 EGLuint64KHR *ust,
714 EGLuint64KHR *msc,
715 EGLuint64KHR *sbc)
716 {
717 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncValuesCHROMIUM",
718 GetDisplayIfValid(display), EGL_FALSE);
719 ANGLE_EGL_TRY_RETURN(thread, eglSurface->getSyncValues(ust, msc, sbc),
720 "eglGetSyncValuesCHROMIUM", GetSurfaceIfValid(display, eglSurface),
721 EGL_FALSE);
722
723 thread->setSuccess();
724 return EGL_TRUE;
725 }
726
ProgramCacheGetAttribANGLE(Thread * thread,Display * display,EGLenum attrib)727 EGLint ProgramCacheGetAttribANGLE(Thread *thread, Display *display, EGLenum attrib)
728 {
729 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheGetAttribANGLE",
730 GetDisplayIfValid(display), 0);
731 thread->setSuccess();
732 return display->programCacheGetAttrib(attrib);
733 }
734
ProgramCacheQueryANGLE(Thread * thread,Display * display,EGLint index,void * key,EGLint * keysize,void * binary,EGLint * binarysize)735 void ProgramCacheQueryANGLE(Thread *thread,
736 Display *display,
737 EGLint index,
738 void *key,
739 EGLint *keysize,
740 void *binary,
741 EGLint *binarysize)
742 {
743 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCacheQueryANGLE",
744 GetDisplayIfValid(display));
745 ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize),
746 "eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
747
748 thread->setSuccess();
749 }
750
ProgramCachePopulateANGLE(Thread * thread,Display * display,const void * key,EGLint keysize,const void * binary,EGLint binarysize)751 void ProgramCachePopulateANGLE(Thread *thread,
752 Display *display,
753 const void *key,
754 EGLint keysize,
755 const void *binary,
756 EGLint binarysize)
757 {
758 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCachePopulateANGLE",
759 GetDisplayIfValid(display));
760 ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize),
761 "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
762
763 thread->setSuccess();
764 }
765
ProgramCacheResizeANGLE(Thread * thread,Display * display,EGLint limit,EGLint mode)766 EGLint ProgramCacheResizeANGLE(Thread *thread, Display *display, EGLint limit, EGLint mode)
767 {
768 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheResizeANGLE",
769 GetDisplayIfValid(display), 0);
770 thread->setSuccess();
771 return display->programCacheResize(limit, mode);
772 }
773
QueryStringiANGLE(Thread * thread,Display * display,EGLint name,EGLint index)774 const char *QueryStringiANGLE(Thread *thread, Display *display, EGLint name, EGLint index)
775 {
776 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStringiANGLE",
777 GetDisplayIfValid(display), nullptr);
778 thread->setSuccess();
779 return display->queryStringi(name, index);
780 }
781
SwapBuffersWithFrameTokenANGLE(Thread * thread,Display * display,Surface * eglSurface,EGLFrameTokenANGLE frametoken)782 EGLBoolean SwapBuffersWithFrameTokenANGLE(Thread *thread,
783 Display *display,
784 Surface *eglSurface,
785 EGLFrameTokenANGLE frametoken)
786 {
787 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithFrameTokenANGLE",
788 GetDisplayIfValid(display), EGL_FALSE);
789 ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithFrameToken(thread->getContext(), frametoken),
790 "eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display),
791 EGL_FALSE);
792
793 thread->setSuccess();
794 return EGL_TRUE;
795 }
796
ReleaseHighPowerGPUANGLE(Thread * thread,Display * display,gl::Context * context)797 void ReleaseHighPowerGPUANGLE(Thread *thread, Display *display, gl::Context *context)
798 {
799 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReleaseHighPowerGPUANGLE",
800 GetDisplayIfValid(display));
801 ANGLE_EGL_TRY(thread, context->releaseHighPowerGPU(), "eglReleaseHighPowerGPUANGLE",
802 GetDisplayIfValid(display));
803
804 thread->setSuccess();
805 }
806
ReacquireHighPowerGPUANGLE(Thread * thread,Display * display,gl::Context * context)807 void ReacquireHighPowerGPUANGLE(Thread *thread, Display *display, gl::Context *context)
808 {
809 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReacquireHighPowerGPUANGLE",
810 GetDisplayIfValid(display));
811 ANGLE_EGL_TRY(thread, context->reacquireHighPowerGPU(), "eglReacquireHighPowerGPUANGLE",
812 GetDisplayIfValid(display));
813
814 thread->setSuccess();
815 }
816
HandleGPUSwitchANGLE(Thread * thread,Display * display)817 void HandleGPUSwitchANGLE(Thread *thread, Display *display)
818 {
819 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglHandleGPUSwitchANGLE",
820 GetDisplayIfValid(display));
821 ANGLE_EGL_TRY(thread, display->handleGPUSwitch(), "eglHandleGPUSwitchANGLE",
822 GetDisplayIfValid(display));
823
824 thread->setSuccess();
825 }
826
ForceGPUSwitchANGLE(Thread * thread,Display * display,EGLint gpuIDHigh,EGLint gpuIDLow)827 void ForceGPUSwitchANGLE(Thread *thread, Display *display, EGLint gpuIDHigh, EGLint gpuIDLow)
828 {
829 ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglForceGPUSwitchANGLE",
830 GetDisplayIfValid(display));
831 ANGLE_EGL_TRY(thread, display->forceGPUSwitch(gpuIDHigh, gpuIDLow), "eglForceGPUSwitchANGLE",
832 GetDisplayIfValid(display));
833
834 thread->setSuccess();
835 }
836
QueryDisplayAttribANGLE(Thread * thread,Display * display,EGLint attribute,EGLAttrib * value)837 EGLBoolean QueryDisplayAttribANGLE(Thread *thread,
838 Display *display,
839 EGLint attribute,
840 EGLAttrib *value)
841 {
842 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribEXT",
843 GetDisplayIfValid(display), EGL_FALSE);
844 *value = display->queryAttrib(attribute);
845 thread->setSuccess();
846 return EGL_TRUE;
847 }
848
LockSurfaceKHR(Thread * thread,egl::Display * display,Surface * surface,const AttributeMap & attributes)849 EGLBoolean LockSurfaceKHR(Thread *thread,
850 egl::Display *display,
851 Surface *surface,
852 const AttributeMap &attributes)
853 {
854 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglLockSurfaceKHR",
855 GetDisplayIfValid(display), EGL_FALSE);
856 ANGLE_EGL_TRY_RETURN(thread, surface->lockSurfaceKHR(display, attributes), "eglLockSurfaceKHR",
857 GetSurfaceIfValid(display, surface), EGL_FALSE);
858 thread->setSuccess();
859 return EGL_TRUE;
860 }
861
UnlockSurfaceKHR(Thread * thread,egl::Display * display,Surface * surface)862 EGLBoolean UnlockSurfaceKHR(Thread *thread, egl::Display *display, Surface *surface)
863 {
864 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglUnlockSurfaceKHR",
865 GetDisplayIfValid(display), EGL_FALSE);
866 ANGLE_EGL_TRY_RETURN(thread, surface->unlockSurfaceKHR(display), "eglQuerySurface64KHR",
867 GetSurfaceIfValid(display, surface), EGL_FALSE);
868 thread->setSuccess();
869 return EGL_TRUE;
870 }
871
QuerySurface64KHR(Thread * thread,egl::Display * display,Surface * surface,EGLint attribute,EGLAttribKHR * value)872 EGLBoolean QuerySurface64KHR(Thread *thread,
873 egl::Display *display,
874 Surface *surface,
875 EGLint attribute,
876 EGLAttribKHR *value)
877 {
878 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface64KHR",
879 GetDisplayIfValid(display), EGL_FALSE);
880 ANGLE_EGL_TRY_RETURN(
881 thread, QuerySurfaceAttrib64KHR(display, thread->getContext(), surface, attribute, value),
882 "eglQuerySurface64KHR", GetSurfaceIfValid(display, surface), EGL_FALSE);
883 thread->setSuccess();
884 return EGL_TRUE;
885 }
886
ExportVkImageANGLE(Thread * thread,egl::Display * display,Image * image,void * vk_image,void * vk_image_create_info)887 EGLBoolean ExportVkImageANGLE(Thread *thread,
888 egl::Display *display,
889 Image *image,
890 void *vk_image,
891 void *vk_image_create_info)
892 {
893 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglExportVkImageANGLE",
894 GetDisplayIfValid(display), EGL_FALSE);
895 ANGLE_EGL_TRY_RETURN(thread, image->exportVkImage(vk_image, vk_image_create_info),
896 "eglExportVkImageANGLE", GetImageIfValid(display, image), EGL_FALSE);
897
898 thread->setSuccess();
899 return EGL_TRUE;
900 }
901
SetDamageRegionKHR(Thread * thread,egl::Display * display,egl::Surface * surface,EGLint * rects,EGLint n_rects)902 EGLBoolean SetDamageRegionKHR(Thread *thread,
903 egl::Display *display,
904 egl::Surface *surface,
905 EGLint *rects,
906 EGLint n_rects)
907 {
908 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSetDamageRegionKHR",
909 GetDisplayIfValid(display), EGL_FALSE);
910 surface->setDamageRegion(rects, n_rects);
911
912 thread->setSuccess();
913 return EGL_TRUE;
914 }
915
QueryDmaBufFormatsEXT(Thread * thread,egl::Display * display,EGLint max_formats,EGLint * formats,EGLint * num_formats)916 EGLBoolean QueryDmaBufFormatsEXT(Thread *thread,
917 egl::Display *display,
918 EGLint max_formats,
919 EGLint *formats,
920 EGLint *num_formats)
921 {
922 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDmaBufFormatsEXT",
923 GetDisplayIfValid(display), EGL_FALSE);
924 ANGLE_EGL_TRY_RETURN(thread, display->queryDmaBufFormats(max_formats, formats, num_formats),
925 "eglQueryDmaBufFormatsEXT", GetDisplayIfValid(display), EGL_FALSE);
926 thread->setSuccess();
927 return EGL_TRUE;
928 }
929
QueryDmaBufModifiersEXT(Thread * thread,egl::Display * display,EGLint format,EGLint max_modifiers,EGLuint64KHR * modifiers,EGLBoolean * external_only,EGLint * num_modifiers)930 EGLBoolean QueryDmaBufModifiersEXT(Thread *thread,
931 egl::Display *display,
932 EGLint format,
933 EGLint max_modifiers,
934 EGLuint64KHR *modifiers,
935 EGLBoolean *external_only,
936 EGLint *num_modifiers)
937 {
938 ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDmaBufModifiersEXT",
939 GetDisplayIfValid(display), EGL_FALSE);
940 ANGLE_EGL_TRY_RETURN(thread,
941 display->queryDmaBufModifiers(format, max_modifiers, modifiers,
942 external_only, num_modifiers),
943 "eglQueryDmaBufModifiersEXT", GetDisplayIfValid(display), EGL_FALSE);
944 thread->setSuccess();
945 return EGL_TRUE;
946 }
947
948 } // namespace egl
949