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