1 //
2 // Copyright(c) 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_egl.cpp : Implements the EGL entry points.
8 
9 #include "libGLESv2/entry_points_egl.h"
10 #include "libGLESv2/entry_points_egl_ext.h"
11 #include "libGLESv2/entry_points_gles_2_0.h"
12 #include "libGLESv2/entry_points_gles_2_0_ext.h"
13 #include "libGLESv2/entry_points_gles_3_0.h"
14 #include "libGLESv2/entry_points_gles_3_1.h"
15 #include "libGLESv2/global_state.h"
16 
17 #include "libANGLE/Context.h"
18 #include "libANGLE/Display.h"
19 #include "libANGLE/Texture.h"
20 #include "libANGLE/Thread.h"
21 #include "libANGLE/Surface.h"
22 #include "libANGLE/validationEGL.h"
23 
24 #include "common/debug.h"
25 #include "common/version.h"
26 
27 #include "platform/Platform.h"
28 
29 #include <EGL/eglext.h>
30 
31 namespace egl
32 {
33 
34 // EGL 1.0
GetError(void)35 EGLint EGLAPIENTRY GetError(void)
36 {
37     EVENT("()");
38     Thread *thread = GetCurrentThread();
39 
40     EGLint error = thread->getError();
41     thread->setError(Error(EGL_SUCCESS));
42     return error;
43 }
44 
GetDisplay(EGLNativeDisplayType display_id)45 EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id)
46 {
47     EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
48 
49     return Display::GetDisplayFromAttribs(reinterpret_cast<void *>(display_id), AttributeMap());
50 }
51 
Initialize(EGLDisplay dpy,EGLint * major,EGLint * minor)52 EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
53 {
54     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy,
55           major, minor);
56     Thread *thread = GetCurrentThread();
57 
58     Display *display = static_cast<Display *>(dpy);
59     if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
60     {
61         thread->setError(Error(EGL_BAD_DISPLAY));
62         return EGL_FALSE;
63     }
64 
65     Error error = display->initialize();
66     if (error.isError())
67     {
68         thread->setError(error);
69         return EGL_FALSE;
70     }
71 
72     if (major) *major = 1;
73     if (minor) *minor = 4;
74 
75     thread->setError(Error(EGL_SUCCESS));
76     return EGL_TRUE;
77 }
78 
Terminate(EGLDisplay dpy)79 EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy)
80 {
81     EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
82     Thread *thread = GetCurrentThread();
83 
84     Display *display = static_cast<Display *>(dpy);
85     if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
86     {
87         thread->setError(Error(EGL_BAD_DISPLAY));
88         return EGL_FALSE;
89     }
90 
91     if (display->isValidContext(thread->getContext()))
92     {
93         thread->setCurrent(nullptr, nullptr, nullptr, nullptr);
94     }
95 
96     display->terminate();
97 
98     thread->setError(Error(EGL_SUCCESS));
99     return EGL_TRUE;
100 }
101 
QueryString(EGLDisplay dpy,EGLint name)102 const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
103 {
104     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
105     Thread *thread = GetCurrentThread();
106 
107     Display *display = static_cast<Display*>(dpy);
108     if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS))
109     {
110         Error error = ValidateDisplay(display);
111         if (error.isError())
112         {
113             thread->setError(error);
114             return NULL;
115         }
116     }
117 
118     const char *result;
119     switch (name)
120     {
121       case EGL_CLIENT_APIS:
122         result = "OpenGL_ES";
123         break;
124       case EGL_EXTENSIONS:
125         if (display == EGL_NO_DISPLAY)
126         {
127             result = Display::getClientExtensionString().c_str();
128         }
129         else
130         {
131             result = display->getExtensionString().c_str();
132         }
133         break;
134       case EGL_VENDOR:
135         result = display->getVendorString().c_str();
136         break;
137       case EGL_VERSION:
138         result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
139         break;
140       default:
141           thread->setError(Error(EGL_BAD_PARAMETER));
142           return NULL;
143     }
144 
145     thread->setError(Error(EGL_SUCCESS));
146     return result;
147 }
148 
GetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)149 EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
150 {
151     EVENT(
152         "(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
153         "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
154         dpy, configs, config_size, num_config);
155     Thread *thread = GetCurrentThread();
156 
157     Display *display = static_cast<Display*>(dpy);
158 
159     Error error = ValidateDisplay(display);
160     if (error.isError())
161     {
162         thread->setError(error);
163         return EGL_FALSE;
164     }
165 
166     if (!num_config)
167     {
168         thread->setError(Error(EGL_BAD_PARAMETER));
169         return EGL_FALSE;
170     }
171 
172     std::vector<const Config*> filteredConfigs = display->getConfigs(AttributeMap());
173     if (configs)
174     {
175         filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
176         for (size_t i = 0; i < filteredConfigs.size(); i++)
177         {
178             configs[i] = const_cast<Config*>(filteredConfigs[i]);
179         }
180     }
181     *num_config = static_cast<EGLint>(filteredConfigs.size());
182 
183     thread->setError(Error(EGL_SUCCESS));
184     return EGL_TRUE;
185 }
186 
ChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)187 EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
188 {
189     EVENT(
190         "(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
191         "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
192         dpy, attrib_list, configs, config_size, num_config);
193     Thread *thread = GetCurrentThread();
194 
195     Display *display = static_cast<Display*>(dpy);
196 
197     Error error = ValidateDisplay(display);
198     if (error.isError())
199     {
200         thread->setError(error);
201         return EGL_FALSE;
202     }
203 
204     if (!num_config)
205     {
206         thread->setError(Error(EGL_BAD_PARAMETER));
207         return EGL_FALSE;
208     }
209 
210     std::vector<const Config *> filteredConfigs =
211         display->getConfigs(AttributeMap::CreateFromIntArray(attrib_list));
212     if (configs)
213     {
214         filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
215         for (size_t i = 0; i < filteredConfigs.size(); i++)
216         {
217             configs[i] = const_cast<Config*>(filteredConfigs[i]);
218         }
219     }
220     *num_config = static_cast<EGLint>(filteredConfigs.size());
221 
222     thread->setError(Error(EGL_SUCCESS));
223     return EGL_TRUE;
224 }
225 
GetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)226 EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
227 {
228     EVENT(
229         "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint "
230         "*value = 0x%0.8p)",
231         dpy, config, attribute, value);
232     Thread *thread = GetCurrentThread();
233 
234     Display *display = static_cast<Display*>(dpy);
235     Config *configuration = static_cast<Config*>(config);
236 
237     Error error = ValidateConfig(display, configuration);
238     if (error.isError())
239     {
240         thread->setError(error);
241         return EGL_FALSE;
242     }
243 
244     if (!display->getConfigAttrib(configuration, attribute, value))
245     {
246         thread->setError(Error(EGL_BAD_ATTRIBUTE));
247         return EGL_FALSE;
248     }
249 
250     thread->setError(Error(EGL_SUCCESS));
251     return EGL_TRUE;
252 }
253 
CreateWindowSurface(EGLDisplay dpy,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)254 EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
255 {
256     EVENT(
257         "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
258         "const EGLint *attrib_list = 0x%0.8p)",
259         dpy, config, win, attrib_list);
260     Thread *thread = GetCurrentThread();
261 
262     Display *display = static_cast<Display*>(dpy);
263     Config *configuration = static_cast<Config*>(config);
264     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
265 
266     Error error = ValidateCreateWindowSurface(display, configuration, win, attributes);
267     if (error.isError())
268     {
269         thread->setError(error);
270         return EGL_NO_SURFACE;
271     }
272 
273     egl::Surface *surface = nullptr;
274     error = display->createWindowSurface(configuration, win, attributes, &surface);
275     if (error.isError())
276     {
277         thread->setError(error);
278         return EGL_NO_SURFACE;
279     }
280 
281     return static_cast<EGLSurface>(surface);
282 }
283 
CreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)284 EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
285 {
286     EVENT(
287         "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = "
288         "0x%0.8p)",
289         dpy, config, attrib_list);
290     Thread *thread = GetCurrentThread();
291 
292     Display *display = static_cast<Display*>(dpy);
293     Config *configuration = static_cast<Config*>(config);
294     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
295 
296     Error error = ValidateCreatePbufferSurface(display, configuration, attributes);
297     if (error.isError())
298     {
299         thread->setError(error);
300         return EGL_NO_SURFACE;
301     }
302 
303     egl::Surface *surface = nullptr;
304     error = display->createPbufferSurface(configuration, attributes, &surface);
305     if (error.isError())
306     {
307         thread->setError(error);
308         return EGL_NO_SURFACE;
309     }
310 
311     return static_cast<EGLSurface>(surface);
312 }
313 
CreatePixmapSurface(EGLDisplay dpy,EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attrib_list)314 EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
315 {
316     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
317           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
318     Thread *thread = GetCurrentThread();
319 
320     Display *display = static_cast<Display*>(dpy);
321     Config *configuration = static_cast<Config*>(config);
322 
323     Error error = ValidateConfig(display, configuration);
324     if (error.isError())
325     {
326         thread->setError(error);
327         return EGL_NO_SURFACE;
328     }
329 
330     UNIMPLEMENTED();   // FIXME
331 
332     thread->setError(Error(EGL_SUCCESS));
333     return EGL_NO_SURFACE;
334 }
335 
DestroySurface(EGLDisplay dpy,EGLSurface surface)336 EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
337 {
338     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
339     Thread *thread = GetCurrentThread();
340 
341     Display *display = static_cast<Display*>(dpy);
342     Surface *eglSurface = static_cast<Surface*>(surface);
343 
344     Error error = ValidateSurface(display, eglSurface);
345     if (error.isError())
346     {
347         thread->setError(error);
348         return EGL_FALSE;
349     }
350 
351     if (surface == EGL_NO_SURFACE)
352     {
353         thread->setError(Error(EGL_BAD_SURFACE));
354         return EGL_FALSE;
355     }
356 
357     display->destroySurface((Surface*)surface);
358 
359     thread->setError(Error(EGL_SUCCESS));
360     return EGL_TRUE;
361 }
362 
QuerySurface(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)363 EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
364 {
365     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
366           dpy, surface, attribute, value);
367     Thread *thread = GetCurrentThread();
368 
369     Display *display = static_cast<Display*>(dpy);
370     Surface *eglSurface = (Surface*)surface;
371 
372     Error error = ValidateSurface(display, eglSurface);
373     if (error.isError())
374     {
375         thread->setError(error);
376         return EGL_FALSE;
377     }
378 
379     if (surface == EGL_NO_SURFACE)
380     {
381         thread->setError(Error(EGL_BAD_SURFACE));
382         return EGL_FALSE;
383     }
384 
385     switch (attribute)
386     {
387       case EGL_VG_ALPHA_FORMAT:
388         UNIMPLEMENTED();   // FIXME
389         break;
390       case EGL_VG_COLORSPACE:
391         UNIMPLEMENTED();   // FIXME
392         break;
393       case EGL_CONFIG_ID:
394         *value = eglSurface->getConfig()->configID;
395         break;
396       case EGL_HEIGHT:
397         *value = eglSurface->getHeight();
398         break;
399       case EGL_HORIZONTAL_RESOLUTION:
400         UNIMPLEMENTED();   // FIXME
401         break;
402       case EGL_LARGEST_PBUFFER:
403         UNIMPLEMENTED();   // FIXME
404         break;
405       case EGL_MIPMAP_TEXTURE:
406         UNIMPLEMENTED();   // FIXME
407         break;
408       case EGL_MIPMAP_LEVEL:
409         UNIMPLEMENTED();   // FIXME
410         break;
411       case EGL_MULTISAMPLE_RESOLVE:
412         UNIMPLEMENTED();   // FIXME
413         break;
414       case EGL_PIXEL_ASPECT_RATIO:
415         *value = eglSurface->getPixelAspectRatio();
416         break;
417       case EGL_RENDER_BUFFER:
418         *value = eglSurface->getRenderBuffer();
419         break;
420       case EGL_SWAP_BEHAVIOR:
421         *value = eglSurface->getSwapBehavior();
422         break;
423       case EGL_TEXTURE_FORMAT:
424         *value = eglSurface->getTextureFormat();
425         break;
426       case EGL_TEXTURE_TARGET:
427         *value = eglSurface->getTextureTarget();
428         break;
429       case EGL_VERTICAL_RESOLUTION:
430         UNIMPLEMENTED();   // FIXME
431         break;
432       case EGL_WIDTH:
433         *value = eglSurface->getWidth();
434         break;
435       case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
436         if (!display->getExtensions().postSubBuffer)
437         {
438             thread->setError(Error(EGL_BAD_ATTRIBUTE));
439             return EGL_FALSE;
440         }
441         *value = eglSurface->isPostSubBufferSupported();
442         break;
443       case EGL_FIXED_SIZE_ANGLE:
444         if (!display->getExtensions().windowFixedSize)
445         {
446             thread->setError(Error(EGL_BAD_ATTRIBUTE));
447             return EGL_FALSE;
448         }
449         *value = eglSurface->isFixedSize();
450         break;
451       case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
452           if (!display->getExtensions().flexibleSurfaceCompatibility)
453           {
454               thread->setError(
455                   Error(EGL_BAD_ATTRIBUTE,
456                         "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without "
457                         "EGL_ANGLE_flexible_surface_compatibility support."));
458               return EGL_FALSE;
459           }
460           *value = eglSurface->flexibleSurfaceCompatibilityRequested();
461           break;
462       case EGL_SURFACE_ORIENTATION_ANGLE:
463           if (!display->getExtensions().surfaceOrientation)
464           {
465               thread->setError(Error(EGL_BAD_ATTRIBUTE,
466                                      "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without "
467                                      "EGL_ANGLE_surface_orientation support."));
468               return EGL_FALSE;
469           }
470           *value = eglSurface->getOrientation();
471           break;
472       case EGL_DIRECT_COMPOSITION_ANGLE:
473           if (!display->getExtensions().directComposition)
474           {
475               thread->setError(Error(EGL_BAD_ATTRIBUTE,
476                                      "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without "
477                                      "EGL_ANGLE_direct_composition support."));
478               return EGL_FALSE;
479           }
480           *value = eglSurface->directComposition();
481           break;
482       default:
483           thread->setError(Error(EGL_BAD_ATTRIBUTE));
484           return EGL_FALSE;
485     }
486 
487     thread->setError(Error(EGL_SUCCESS));
488     return EGL_TRUE;
489 }
490 
CreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)491 EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
492 {
493     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
494           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
495     Thread *thread = GetCurrentThread();
496 
497     Display *display = static_cast<Display*>(dpy);
498     Config *configuration = static_cast<Config*>(config);
499     gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
500     AttributeMap attributes      = AttributeMap::CreateFromIntArray(attrib_list);
501 
502     Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes);
503     if (error.isError())
504     {
505         thread->setError(error);
506         return EGL_NO_CONTEXT;
507     }
508 
509     gl::Context *context = nullptr;
510     error = display->createContext(configuration, sharedGLContext, attributes, &context);
511     if (error.isError())
512     {
513         thread->setError(error);
514         return EGL_NO_CONTEXT;
515     }
516 
517     thread->setError(Error(EGL_SUCCESS));
518     return static_cast<EGLContext>(context);
519 }
520 
DestroyContext(EGLDisplay dpy,EGLContext ctx)521 EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
522 {
523     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
524     Thread *thread = GetCurrentThread();
525 
526     Display *display = static_cast<Display*>(dpy);
527     gl::Context *context = static_cast<gl::Context*>(ctx);
528 
529     Error error = ValidateContext(display, context);
530     if (error.isError())
531     {
532         thread->setError(error);
533         return EGL_FALSE;
534     }
535 
536     if (ctx == EGL_NO_CONTEXT)
537     {
538         thread->setError(Error(EGL_BAD_CONTEXT));
539         return EGL_FALSE;
540     }
541 
542     if (context == thread->getContext())
543     {
544         thread->setCurrent(nullptr, thread->getDrawSurface(), thread->getReadSurface(), nullptr);
545     }
546 
547     display->destroyContext(context);
548 
549     thread->setError(Error(EGL_SUCCESS));
550     return EGL_TRUE;
551 }
552 
MakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)553 EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
554 {
555     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
556           dpy, draw, read, ctx);
557     Thread *thread = GetCurrentThread();
558 
559     Display *display = static_cast<Display*>(dpy);
560     gl::Context *context = static_cast<gl::Context*>(ctx);
561 
562     // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH
563     // error is generated.
564     if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
565     {
566         thread->setError(Error(EGL_BAD_MATCH));
567         return EGL_FALSE;
568     }
569 
570     if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE)
571     {
572         thread->setError(Error(EGL_BAD_MATCH));
573         return EGL_FALSE;
574     }
575 
576     // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an
577     // EGL_BAD_MATCH error is generated.
578     if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE))
579     {
580         thread->setError(Error(
581             EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"));
582         return EGL_FALSE;
583     }
584 
585     if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
586     {
587         thread->setError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle"));
588         return EGL_FALSE;
589     }
590 
591     // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
592     if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
593     {
594         thread->setError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized"));
595         return EGL_FALSE;
596     }
597 
598     if (ctx != EGL_NO_CONTEXT)
599     {
600         Error error = ValidateContext(display, context);
601         if (error.isError())
602         {
603             thread->setError(error);
604             return EGL_FALSE;
605         }
606     }
607 
608     if (display->isInitialized() && display->testDeviceLost())
609     {
610         thread->setError(Error(EGL_CONTEXT_LOST));
611         return EGL_FALSE;
612     }
613 
614     Surface *drawSurface = static_cast<Surface*>(draw);
615     if (draw != EGL_NO_SURFACE)
616     {
617         Error error = ValidateSurface(display, drawSurface);
618         if (error.isError())
619         {
620             thread->setError(error);
621             return EGL_FALSE;
622         }
623     }
624 
625     Surface *readSurface = static_cast<Surface*>(read);
626     if (read != EGL_NO_SURFACE)
627     {
628         Error error = ValidateSurface(display, readSurface);
629         if (error.isError())
630         {
631             thread->setError(error);
632             return EGL_FALSE;
633         }
634     }
635 
636     if (readSurface)
637     {
638         Error readCompatError =
639             ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface,
640                                       context->getConfig(), readSurface->getType());
641         if (readCompatError.isError())
642         {
643             thread->setError(readCompatError);
644             return EGL_FALSE;
645         }
646     }
647 
648     if (draw != read)
649     {
650         UNIMPLEMENTED();   // FIXME
651 
652         if (drawSurface)
653         {
654             Error drawCompatError =
655                 ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface,
656                                           context->getConfig(), drawSurface->getType());
657             if (drawCompatError.isError())
658             {
659                 thread->setError(drawCompatError);
660                 return EGL_FALSE;
661             }
662         }
663     }
664 
665     Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context);
666     if (makeCurrentError.isError())
667     {
668         thread->setError(makeCurrentError);
669         return EGL_FALSE;
670     }
671 
672     gl::Context *previousContext = thread->getContext();
673     thread->setCurrent(display, drawSurface, readSurface, context);
674 
675     // Release the surface from the previously-current context, to allow
676     // destroyed surfaces to delete themselves.
677     if (previousContext != nullptr && context != previousContext)
678     {
679         previousContext->releaseSurface();
680     }
681 
682     thread->setError(Error(EGL_SUCCESS));
683     return EGL_TRUE;
684 }
685 
GetCurrentSurface(EGLint readdraw)686 EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
687 {
688     EVENT("(EGLint readdraw = %d)", readdraw);
689     Thread *thread = GetCurrentThread();
690 
691     if (readdraw == EGL_READ)
692     {
693         thread->setError(Error(EGL_SUCCESS));
694         return thread->getReadSurface();
695     }
696     else if (readdraw == EGL_DRAW)
697     {
698         thread->setError(Error(EGL_SUCCESS));
699         return thread->getDrawSurface();
700     }
701     else
702     {
703         thread->setError(Error(EGL_BAD_PARAMETER));
704         return EGL_NO_SURFACE;
705     }
706 }
707 
GetCurrentDisplay(void)708 EGLDisplay EGLAPIENTRY GetCurrentDisplay(void)
709 {
710     EVENT("()");
711     Thread *thread = GetCurrentThread();
712 
713     EGLDisplay dpy = thread->getDisplay();
714 
715     thread->setError(Error(EGL_SUCCESS));
716     return dpy;
717 }
718 
QueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)719 EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
720 {
721     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
722           dpy, ctx, attribute, value);
723     Thread *thread = GetCurrentThread();
724 
725     Display *display = static_cast<Display*>(dpy);
726     gl::Context *context = static_cast<gl::Context*>(ctx);
727 
728     Error error = ValidateContext(display, context);
729     if (error.isError())
730     {
731         thread->setError(error);
732         return EGL_FALSE;
733     }
734 
735     switch (attribute)
736     {
737       case EGL_CONFIG_ID:
738         *value = context->getConfig()->configID;
739         break;
740       case EGL_CONTEXT_CLIENT_TYPE:
741         *value = context->getClientType();
742         break;
743       case EGL_CONTEXT_CLIENT_VERSION:
744           *value = context->getClientMajorVersion();
745           break;
746       case EGL_RENDER_BUFFER:
747         *value = context->getRenderBuffer();
748         break;
749       default:
750           thread->setError(Error(EGL_BAD_ATTRIBUTE));
751           return EGL_FALSE;
752     }
753 
754     thread->setError(Error(EGL_SUCCESS));
755     return EGL_TRUE;
756 }
757 
WaitGL(void)758 EGLBoolean EGLAPIENTRY WaitGL(void)
759 {
760     EVENT("()");
761     Thread *thread = GetCurrentThread();
762 
763     Display *display = thread->getDisplay();
764 
765     Error error = ValidateDisplay(display);
766     if (error.isError())
767     {
768         thread->setError(error);
769         return EGL_FALSE;
770     }
771 
772     // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement
773     // OpenGL ES we can do the call directly.
774     error = display->waitClient();
775     if (error.isError())
776     {
777         thread->setError(error);
778         return EGL_FALSE;
779     }
780 
781     thread->setError(Error(EGL_SUCCESS));
782     return EGL_TRUE;
783 }
784 
WaitNative(EGLint engine)785 EGLBoolean EGLAPIENTRY WaitNative(EGLint engine)
786 {
787     EVENT("(EGLint engine = %d)", engine);
788     Thread *thread = GetCurrentThread();
789 
790     Display *display = thread->getDisplay();
791 
792     Error error = ValidateDisplay(display);
793     if (error.isError())
794     {
795         thread->setError(error);
796         return EGL_FALSE;
797     }
798 
799     if (engine != EGL_CORE_NATIVE_ENGINE)
800     {
801         thread->setError(
802             Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value"));
803     }
804 
805     error = display->waitNative(engine, thread->getDrawSurface(), thread->getReadSurface());
806     if (error.isError())
807     {
808         thread->setError(error);
809         return EGL_FALSE;
810     }
811 
812     thread->setError(Error(EGL_SUCCESS));
813     return EGL_TRUE;
814 }
815 
SwapBuffers(EGLDisplay dpy,EGLSurface surface)816 EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
817 {
818     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
819     Thread *thread = GetCurrentThread();
820 
821     Display *display = static_cast<Display*>(dpy);
822     Surface *eglSurface = (Surface*)surface;
823 
824     Error error = ValidateSurface(display, eglSurface);
825     if (error.isError())
826     {
827         thread->setError(error);
828         return EGL_FALSE;
829     }
830 
831     if (display->testDeviceLost())
832     {
833         thread->setError(Error(EGL_CONTEXT_LOST));
834         return EGL_FALSE;
835     }
836 
837     if (surface == EGL_NO_SURFACE)
838     {
839         thread->setError(Error(EGL_BAD_SURFACE));
840         return EGL_FALSE;
841     }
842 
843     error = eglSurface->swap();
844     if (error.isError())
845     {
846         thread->setError(error);
847         return EGL_FALSE;
848     }
849 
850     thread->setError(Error(EGL_SUCCESS));
851     return EGL_TRUE;
852 }
853 
CopyBuffers(EGLDisplay dpy,EGLSurface surface,EGLNativePixmapType target)854 EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
855 {
856     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
857     Thread *thread = GetCurrentThread();
858 
859     Display *display = static_cast<Display*>(dpy);
860     Surface *eglSurface = static_cast<Surface*>(surface);
861 
862     Error error = ValidateSurface(display, eglSurface);
863     if (error.isError())
864     {
865         thread->setError(error);
866         return EGL_FALSE;
867     }
868 
869     if (display->testDeviceLost())
870     {
871         thread->setError(Error(EGL_CONTEXT_LOST));
872         return EGL_FALSE;
873     }
874 
875     UNIMPLEMENTED();   // FIXME
876 
877     thread->setError(Error(EGL_SUCCESS));
878     return 0;
879 }
880 
881 // EGL 1.1
BindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)882 EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
883 {
884     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
885     Thread *thread = GetCurrentThread();
886 
887     Display *display = static_cast<Display*>(dpy);
888     Surface *eglSurface = static_cast<Surface*>(surface);
889 
890     Error error = ValidateSurface(display, eglSurface);
891     if (error.isError())
892     {
893         thread->setError(error);
894         return EGL_FALSE;
895     }
896 
897     if (buffer != EGL_BACK_BUFFER)
898     {
899         thread->setError(Error(EGL_BAD_PARAMETER));
900         return EGL_FALSE;
901     }
902 
903     if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
904     {
905         thread->setError(Error(EGL_BAD_SURFACE));
906         return EGL_FALSE;
907     }
908 
909     if (eglSurface->getBoundTexture())
910     {
911         thread->setError(Error(EGL_BAD_ACCESS));
912         return EGL_FALSE;
913     }
914 
915     if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
916     {
917         thread->setError(Error(EGL_BAD_MATCH));
918         return EGL_FALSE;
919     }
920 
921     gl::Context *context = thread->getContext();
922     if (context)
923     {
924         gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
925         ASSERT(textureObject != NULL);
926 
927         if (textureObject->getImmutableFormat())
928         {
929             thread->setError(Error(EGL_BAD_MATCH));
930             return EGL_FALSE;
931         }
932 
933         error = eglSurface->bindTexImage(textureObject, buffer);
934         if (error.isError())
935         {
936             thread->setError(error);
937             return EGL_FALSE;
938         }
939     }
940 
941     thread->setError(Error(EGL_SUCCESS));
942     return EGL_TRUE;
943 }
944 
SurfaceAttrib(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)945 EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
946 {
947     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
948         dpy, surface, attribute, value);
949     Thread *thread = GetCurrentThread();
950 
951     Display *display = static_cast<Display*>(dpy);
952     Surface *eglSurface = static_cast<Surface*>(surface);
953 
954     Error error = ValidateSurface(display, eglSurface);
955     if (error.isError())
956     {
957         thread->setError(error);
958         return EGL_FALSE;
959     }
960 
961     UNIMPLEMENTED();   // FIXME
962 
963     thread->setError(Error(EGL_SUCCESS));
964     return EGL_TRUE;
965 }
966 
ReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)967 EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
968 {
969     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
970     Thread *thread = GetCurrentThread();
971 
972     Display *display = static_cast<Display*>(dpy);
973     Surface *eglSurface = static_cast<Surface*>(surface);
974 
975     Error error = ValidateSurface(display, eglSurface);
976     if (error.isError())
977     {
978         thread->setError(error);
979         return EGL_FALSE;
980     }
981 
982     if (buffer != EGL_BACK_BUFFER)
983     {
984         thread->setError(Error(EGL_BAD_PARAMETER));
985         return EGL_FALSE;
986     }
987 
988     if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
989     {
990         thread->setError(Error(EGL_BAD_SURFACE));
991         return EGL_FALSE;
992     }
993 
994     if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
995     {
996         thread->setError(Error(EGL_BAD_MATCH));
997         return EGL_FALSE;
998     }
999 
1000     gl::Texture *texture = eglSurface->getBoundTexture();
1001 
1002     if (texture)
1003     {
1004         error = eglSurface->releaseTexImage(buffer);
1005         if (error.isError())
1006         {
1007             thread->setError(error);
1008             return EGL_FALSE;
1009         }
1010     }
1011 
1012     thread->setError(Error(EGL_SUCCESS));
1013     return EGL_TRUE;
1014 }
1015 
SwapInterval(EGLDisplay dpy,EGLint interval)1016 EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
1017 {
1018     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
1019     Thread *thread = GetCurrentThread();
1020 
1021     Display *display = static_cast<Display*>(dpy);
1022 
1023     Error error = ValidateDisplay(display);
1024     if (error.isError())
1025     {
1026         thread->setError(error);
1027         return EGL_FALSE;
1028     }
1029 
1030     Surface *draw_surface = static_cast<Surface *>(thread->getDrawSurface());
1031 
1032     if (draw_surface == NULL)
1033     {
1034         thread->setError(Error(EGL_BAD_SURFACE));
1035         return EGL_FALSE;
1036     }
1037 
1038     const egl::Config *surfaceConfig = draw_surface->getConfig();
1039     EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval);
1040 
1041     draw_surface->setSwapInterval(clampedInterval);
1042 
1043     thread->setError(Error(EGL_SUCCESS));
1044     return EGL_TRUE;
1045 }
1046 
1047 
1048 // EGL 1.2
BindAPI(EGLenum api)1049 EGLBoolean EGLAPIENTRY BindAPI(EGLenum api)
1050 {
1051     EVENT("(EGLenum api = 0x%X)", api);
1052     Thread *thread = GetCurrentThread();
1053 
1054     switch (api)
1055     {
1056       case EGL_OPENGL_API:
1057       case EGL_OPENVG_API:
1058           thread->setError(Error(EGL_BAD_PARAMETER));
1059           return EGL_FALSE;  // Not supported by this implementation
1060       case EGL_OPENGL_ES_API:
1061         break;
1062       default:
1063           thread->setError(Error(EGL_BAD_PARAMETER));
1064           return EGL_FALSE;
1065     }
1066 
1067     thread->setAPI(api);
1068 
1069     thread->setError(Error(EGL_SUCCESS));
1070     return EGL_TRUE;
1071 }
1072 
QueryAPI(void)1073 EGLenum EGLAPIENTRY QueryAPI(void)
1074 {
1075     EVENT("()");
1076     Thread *thread = GetCurrentThread();
1077 
1078     EGLenum API = thread->getAPI();
1079 
1080     thread->setError(Error(EGL_SUCCESS));
1081     return API;
1082 }
1083 
CreatePbufferFromClientBuffer(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)1084 EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
1085 {
1086     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
1087           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
1088           dpy, buftype, buffer, config, attrib_list);
1089     Thread *thread = GetCurrentThread();
1090 
1091     Display *display = static_cast<Display*>(dpy);
1092     Config *configuration = static_cast<Config*>(config);
1093     AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
1094 
1095     Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes);
1096     if (error.isError())
1097     {
1098         thread->setError(error);
1099         return EGL_NO_SURFACE;
1100     }
1101 
1102     egl::Surface *surface = nullptr;
1103     error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes,
1104                                                    &surface);
1105     if (error.isError())
1106     {
1107         thread->setError(error);
1108         return EGL_NO_SURFACE;
1109     }
1110 
1111     return static_cast<EGLSurface>(surface);
1112 }
1113 
ReleaseThread(void)1114 EGLBoolean EGLAPIENTRY ReleaseThread(void)
1115 {
1116     EVENT("()");
1117     Thread *thread = GetCurrentThread();
1118 
1119     MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
1120 
1121     thread->setError(Error(EGL_SUCCESS));
1122     return EGL_TRUE;
1123 }
1124 
WaitClient(void)1125 EGLBoolean EGLAPIENTRY WaitClient(void)
1126 {
1127     EVENT("()");
1128     Thread *thread = GetCurrentThread();
1129 
1130     Display *display = thread->getDisplay();
1131 
1132     Error error = ValidateDisplay(display);
1133     if (error.isError())
1134     {
1135         thread->setError(error);
1136         return EGL_FALSE;
1137     }
1138 
1139     error = display->waitClient();
1140     if (error.isError())
1141     {
1142         thread->setError(error);
1143         return EGL_FALSE;
1144     }
1145 
1146     thread->setError(Error(EGL_SUCCESS));
1147     return EGL_TRUE;
1148 }
1149 
1150 // EGL 1.4
GetCurrentContext(void)1151 EGLContext EGLAPIENTRY GetCurrentContext(void)
1152 {
1153     EVENT("()");
1154     Thread *thread = GetCurrentThread();
1155 
1156     gl::Context *context = thread->getContext();
1157 
1158     thread->setError(Error(EGL_SUCCESS));
1159     return static_cast<EGLContext>(context);
1160 }
1161 
1162 // EGL 1.5
CreateSync(EGLDisplay dpy,EGLenum type,const EGLAttrib * attrib_list)1163 EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
1164 {
1165     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list);
1166     Thread *thread = GetCurrentThread();
1167 
1168     UNIMPLEMENTED();
1169     thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateSync unimplemented."));
1170     return EGL_NO_SYNC;
1171 }
1172 
DestroySync(EGLDisplay dpy,EGLSync sync)1173 EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync)
1174 {
1175     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync);
1176     Thread *thread = GetCurrentThread();
1177 
1178     UNIMPLEMENTED();
1179     thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroySync unimplemented."));
1180     return EGL_FALSE;
1181 }
1182 
ClientWaitSync(EGLDisplay dpy,EGLSync sync,EGLint flags,EGLTime timeout)1183 EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
1184 {
1185     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout);
1186     Thread *thread = GetCurrentThread();
1187 
1188     UNIMPLEMENTED();
1189     thread->setError(Error(EGL_BAD_DISPLAY, "eglClientWaitSync unimplemented."));
1190     return 0;
1191 }
1192 
GetSyncAttrib(EGLDisplay dpy,EGLSync sync,EGLint attribute,EGLAttrib * value)1193 EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
1194 {
1195     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value);
1196     Thread *thread = GetCurrentThread();
1197 
1198     UNIMPLEMENTED();
1199     thread->setError(Error(EGL_BAD_DISPLAY, "eglSyncAttrib unimplemented."));
1200     return EGL_FALSE;
1201 }
1202 
CreateImage(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLAttrib * attrib_list)1203 EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
1204 {
1205     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
1206           "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
1207           dpy, ctx, target, buffer, attrib_list);
1208     Thread *thread = GetCurrentThread();
1209 
1210     UNIMPLEMENTED();
1211     thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateImage unimplemented."));
1212     return EGL_NO_IMAGE;
1213 }
1214 
DestroyImage(EGLDisplay dpy,EGLImage image)1215 EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image)
1216 {
1217     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
1218     Thread *thread = GetCurrentThread();
1219 
1220     UNIMPLEMENTED();
1221     thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroyImage unimplemented."));
1222     return EGL_FALSE;
1223 }
1224 
GetPlatformDisplay(EGLenum platform,void * native_display,const EGLAttrib * attrib_list)1225 EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
1226 {
1227     EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
1228           platform, native_display, attrib_list);
1229     Thread *thread = GetCurrentThread();
1230 
1231     UNIMPLEMENTED();
1232     thread->setError(Error(EGL_BAD_DISPLAY, "eglGetPlatformDisplay unimplemented."));
1233     return EGL_NO_DISPLAY;
1234 }
1235 
CreatePlatformWindowSurface(EGLDisplay dpy,EGLConfig config,void * native_window,const EGLAttrib * attrib_list)1236 EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
1237 {
1238     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
1239           dpy, config, native_window, attrib_list);
1240     Thread *thread = GetCurrentThread();
1241 
1242     UNIMPLEMENTED();
1243     thread->setError(Error(EGL_BAD_DISPLAY, "eglCreatePlatformWindowSurface unimplemented."));
1244     return EGL_NO_SURFACE;
1245 }
1246 
CreatePlatformPixmapSurface(EGLDisplay dpy,EGLConfig config,void * native_pixmap,const EGLAttrib * attrib_list)1247 EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
1248 {
1249     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
1250           dpy, config, native_pixmap, attrib_list);
1251     Thread *thread = GetCurrentThread();
1252 
1253     UNIMPLEMENTED();
1254     thread->setError(Error(EGL_BAD_DISPLAY, "eglCraetePlatformPixmaSurface unimplemented."));
1255     return EGL_NO_SURFACE;
1256 }
1257 
WaitSync(EGLDisplay dpy,EGLSync sync,EGLint flags)1258 EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
1259 {
1260     EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags);
1261     Thread *thread = GetCurrentThread();
1262 
1263     UNIMPLEMENTED();
1264     thread->setError(Error(EGL_BAD_DISPLAY, "eglWaitSync unimplemented."));
1265     return EGL_FALSE;
1266 }
1267 
GetProcAddress(const char * procname)1268 __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
1269 {
1270     EVENT("(const char *procname = \"%s\")", procname);
1271     Thread *thread = GetCurrentThread();
1272 
1273     typedef std::map<std::string, __eglMustCastToProperFunctionPointerType> ProcAddressMap;
1274     auto generateProcAddressMap = []()
1275     {
1276         ProcAddressMap map;
1277 #define INSERT_PROC_ADDRESS(ns, proc) \
1278     map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc)
1279 
1280 #define INSERT_PROC_ADDRESS_NO_NS(name, proc) \
1281     map[name] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(proc)
1282 
1283         // GLES2 core
1284         INSERT_PROC_ADDRESS(gl, ActiveTexture);
1285         INSERT_PROC_ADDRESS(gl, AttachShader);
1286         INSERT_PROC_ADDRESS(gl, BindAttribLocation);
1287         INSERT_PROC_ADDRESS(gl, BindBuffer);
1288         INSERT_PROC_ADDRESS(gl, BindFramebuffer);
1289         INSERT_PROC_ADDRESS(gl, BindRenderbuffer);
1290         INSERT_PROC_ADDRESS(gl, BindTexture);
1291         INSERT_PROC_ADDRESS(gl, BlendColor);
1292         INSERT_PROC_ADDRESS(gl, BlendEquation);
1293         INSERT_PROC_ADDRESS(gl, BlendEquationSeparate);
1294         INSERT_PROC_ADDRESS(gl, BlendFunc);
1295         INSERT_PROC_ADDRESS(gl, BlendFuncSeparate);
1296         INSERT_PROC_ADDRESS(gl, BufferData);
1297         INSERT_PROC_ADDRESS(gl, BufferSubData);
1298         INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus);
1299         INSERT_PROC_ADDRESS(gl, Clear);
1300         INSERT_PROC_ADDRESS(gl, ClearColor);
1301         INSERT_PROC_ADDRESS(gl, ClearDepthf);
1302         INSERT_PROC_ADDRESS(gl, ClearStencil);
1303         INSERT_PROC_ADDRESS(gl, ColorMask);
1304         INSERT_PROC_ADDRESS(gl, CompileShader);
1305         INSERT_PROC_ADDRESS(gl, CompressedTexImage2D);
1306         INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D);
1307         INSERT_PROC_ADDRESS(gl, CopyTexImage2D);
1308         INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D);
1309         INSERT_PROC_ADDRESS(gl, CreateProgram);
1310         INSERT_PROC_ADDRESS(gl, CreateShader);
1311         INSERT_PROC_ADDRESS(gl, CullFace);
1312         INSERT_PROC_ADDRESS(gl, DeleteBuffers);
1313         INSERT_PROC_ADDRESS(gl, DeleteFramebuffers);
1314         INSERT_PROC_ADDRESS(gl, DeleteProgram);
1315         INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers);
1316         INSERT_PROC_ADDRESS(gl, DeleteShader);
1317         INSERT_PROC_ADDRESS(gl, DeleteTextures);
1318         INSERT_PROC_ADDRESS(gl, DepthFunc);
1319         INSERT_PROC_ADDRESS(gl, DepthMask);
1320         INSERT_PROC_ADDRESS(gl, DepthRangef);
1321         INSERT_PROC_ADDRESS(gl, DetachShader);
1322         INSERT_PROC_ADDRESS(gl, Disable);
1323         INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray);
1324         INSERT_PROC_ADDRESS(gl, DrawArrays);
1325         INSERT_PROC_ADDRESS(gl, DrawElements);
1326         INSERT_PROC_ADDRESS(gl, Enable);
1327         INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray);
1328         INSERT_PROC_ADDRESS(gl, Finish);
1329         INSERT_PROC_ADDRESS(gl, Flush);
1330         INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer);
1331         INSERT_PROC_ADDRESS(gl, FramebufferTexture2D);
1332         INSERT_PROC_ADDRESS(gl, FrontFace);
1333         INSERT_PROC_ADDRESS(gl, GenBuffers);
1334         INSERT_PROC_ADDRESS(gl, GenerateMipmap);
1335         INSERT_PROC_ADDRESS(gl, GenFramebuffers);
1336         INSERT_PROC_ADDRESS(gl, GenRenderbuffers);
1337         INSERT_PROC_ADDRESS(gl, GenTextures);
1338         INSERT_PROC_ADDRESS(gl, GetActiveAttrib);
1339         INSERT_PROC_ADDRESS(gl, GetActiveUniform);
1340         INSERT_PROC_ADDRESS(gl, GetAttachedShaders);
1341         INSERT_PROC_ADDRESS(gl, GetAttribLocation);
1342         INSERT_PROC_ADDRESS(gl, GetBooleanv);
1343         INSERT_PROC_ADDRESS(gl, GetBufferParameteriv);
1344         INSERT_PROC_ADDRESS(gl, GetError);
1345         INSERT_PROC_ADDRESS(gl, GetFloatv);
1346         INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv);
1347         INSERT_PROC_ADDRESS(gl, GetIntegerv);
1348         INSERT_PROC_ADDRESS(gl, GetProgramiv);
1349         INSERT_PROC_ADDRESS(gl, GetProgramInfoLog);
1350         INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv);
1351         INSERT_PROC_ADDRESS(gl, GetShaderiv);
1352         INSERT_PROC_ADDRESS(gl, GetShaderInfoLog);
1353         INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat);
1354         INSERT_PROC_ADDRESS(gl, GetShaderSource);
1355         INSERT_PROC_ADDRESS(gl, GetString);
1356         INSERT_PROC_ADDRESS(gl, GetTexParameterfv);
1357         INSERT_PROC_ADDRESS(gl, GetTexParameteriv);
1358         INSERT_PROC_ADDRESS(gl, GetUniformfv);
1359         INSERT_PROC_ADDRESS(gl, GetUniformiv);
1360         INSERT_PROC_ADDRESS(gl, GetUniformLocation);
1361         INSERT_PROC_ADDRESS(gl, GetVertexAttribfv);
1362         INSERT_PROC_ADDRESS(gl, GetVertexAttribiv);
1363         INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv);
1364         INSERT_PROC_ADDRESS(gl, Hint);
1365         INSERT_PROC_ADDRESS(gl, IsBuffer);
1366         INSERT_PROC_ADDRESS(gl, IsEnabled);
1367         INSERT_PROC_ADDRESS(gl, IsFramebuffer);
1368         INSERT_PROC_ADDRESS(gl, IsProgram);
1369         INSERT_PROC_ADDRESS(gl, IsRenderbuffer);
1370         INSERT_PROC_ADDRESS(gl, IsShader);
1371         INSERT_PROC_ADDRESS(gl, IsTexture);
1372         INSERT_PROC_ADDRESS(gl, LineWidth);
1373         INSERT_PROC_ADDRESS(gl, LinkProgram);
1374         INSERT_PROC_ADDRESS(gl, PixelStorei);
1375         INSERT_PROC_ADDRESS(gl, PolygonOffset);
1376         INSERT_PROC_ADDRESS(gl, ReadPixels);
1377         INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler);
1378         INSERT_PROC_ADDRESS(gl, RenderbufferStorage);
1379         INSERT_PROC_ADDRESS(gl, SampleCoverage);
1380         INSERT_PROC_ADDRESS(gl, Scissor);
1381         INSERT_PROC_ADDRESS(gl, ShaderBinary);
1382         INSERT_PROC_ADDRESS(gl, ShaderSource);
1383         INSERT_PROC_ADDRESS(gl, StencilFunc);
1384         INSERT_PROC_ADDRESS(gl, StencilFuncSeparate);
1385         INSERT_PROC_ADDRESS(gl, StencilMask);
1386         INSERT_PROC_ADDRESS(gl, StencilMaskSeparate);
1387         INSERT_PROC_ADDRESS(gl, StencilOp);
1388         INSERT_PROC_ADDRESS(gl, StencilOpSeparate);
1389         INSERT_PROC_ADDRESS(gl, TexImage2D);
1390         INSERT_PROC_ADDRESS(gl, TexParameterf);
1391         INSERT_PROC_ADDRESS(gl, TexParameterfv);
1392         INSERT_PROC_ADDRESS(gl, TexParameteri);
1393         INSERT_PROC_ADDRESS(gl, TexParameteriv);
1394         INSERT_PROC_ADDRESS(gl, TexSubImage2D);
1395         INSERT_PROC_ADDRESS(gl, Uniform1f);
1396         INSERT_PROC_ADDRESS(gl, Uniform1fv);
1397         INSERT_PROC_ADDRESS(gl, Uniform1i);
1398         INSERT_PROC_ADDRESS(gl, Uniform1iv);
1399         INSERT_PROC_ADDRESS(gl, Uniform2f);
1400         INSERT_PROC_ADDRESS(gl, Uniform2fv);
1401         INSERT_PROC_ADDRESS(gl, Uniform2i);
1402         INSERT_PROC_ADDRESS(gl, Uniform2iv);
1403         INSERT_PROC_ADDRESS(gl, Uniform3f);
1404         INSERT_PROC_ADDRESS(gl, Uniform3fv);
1405         INSERT_PROC_ADDRESS(gl, Uniform3i);
1406         INSERT_PROC_ADDRESS(gl, Uniform3iv);
1407         INSERT_PROC_ADDRESS(gl, Uniform4f);
1408         INSERT_PROC_ADDRESS(gl, Uniform4fv);
1409         INSERT_PROC_ADDRESS(gl, Uniform4i);
1410         INSERT_PROC_ADDRESS(gl, Uniform4iv);
1411         INSERT_PROC_ADDRESS(gl, UniformMatrix2fv);
1412         INSERT_PROC_ADDRESS(gl, UniformMatrix3fv);
1413         INSERT_PROC_ADDRESS(gl, UniformMatrix4fv);
1414         INSERT_PROC_ADDRESS(gl, UseProgram);
1415         INSERT_PROC_ADDRESS(gl, ValidateProgram);
1416         INSERT_PROC_ADDRESS(gl, VertexAttrib1f);
1417         INSERT_PROC_ADDRESS(gl, VertexAttrib1fv);
1418         INSERT_PROC_ADDRESS(gl, VertexAttrib2f);
1419         INSERT_PROC_ADDRESS(gl, VertexAttrib2fv);
1420         INSERT_PROC_ADDRESS(gl, VertexAttrib3f);
1421         INSERT_PROC_ADDRESS(gl, VertexAttrib3fv);
1422         INSERT_PROC_ADDRESS(gl, VertexAttrib4f);
1423         INSERT_PROC_ADDRESS(gl, VertexAttrib4fv);
1424         INSERT_PROC_ADDRESS(gl, VertexAttribPointer);
1425         INSERT_PROC_ADDRESS(gl, Viewport);
1426 
1427         // GL_ANGLE_framebuffer_blit
1428         INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE);
1429 
1430         // GL_ANGLE_framebuffer_multisample
1431         INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE);
1432 
1433         // GL_EXT_discard_framebuffer
1434         INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT);
1435 
1436         // GL_NV_fence
1437         INSERT_PROC_ADDRESS(gl, DeleteFencesNV);
1438         INSERT_PROC_ADDRESS(gl, GenFencesNV);
1439         INSERT_PROC_ADDRESS(gl, IsFenceNV);
1440         INSERT_PROC_ADDRESS(gl, TestFenceNV);
1441         INSERT_PROC_ADDRESS(gl, GetFenceivNV);
1442         INSERT_PROC_ADDRESS(gl, FinishFenceNV);
1443         INSERT_PROC_ADDRESS(gl, SetFenceNV);
1444 
1445         // GL_ANGLE_translated_shader_source
1446         INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE);
1447 
1448         // GL_EXT_texture_storage
1449         INSERT_PROC_ADDRESS(gl, TexStorage2DEXT);
1450 
1451         // GL_EXT_robustness
1452         INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT);
1453         INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT);
1454         INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT);
1455         INSERT_PROC_ADDRESS(gl, GetnUniformivEXT);
1456 
1457         // GL_EXT_occlusion_query_boolean
1458         INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
1459         INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
1460         INSERT_PROC_ADDRESS(gl, IsQueryEXT);
1461         INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
1462         INSERT_PROC_ADDRESS(gl, EndQueryEXT);
1463         INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
1464         INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
1465 
1466         // GL_EXT_disjoint_timer_query
1467         INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
1468         INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
1469         INSERT_PROC_ADDRESS(gl, IsQueryEXT);
1470         INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
1471         INSERT_PROC_ADDRESS(gl, EndQueryEXT);
1472         INSERT_PROC_ADDRESS(gl, QueryCounterEXT);
1473         INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
1474         INSERT_PROC_ADDRESS(gl, GetQueryObjectivEXT);
1475         INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
1476         INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vEXT);
1477         INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vEXT);
1478 
1479         // GL_EXT_draw_buffers
1480         INSERT_PROC_ADDRESS(gl, DrawBuffersEXT);
1481 
1482         // GL_ANGLE_instanced_arrays
1483         INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE);
1484         INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE);
1485         INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE);
1486 
1487         // GL_OES_get_program_binary
1488         INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES);
1489         INSERT_PROC_ADDRESS(gl, ProgramBinaryOES);
1490 
1491         // GL_OES_mapbuffer
1492         INSERT_PROC_ADDRESS(gl, MapBufferOES);
1493         INSERT_PROC_ADDRESS(gl, UnmapBufferOES);
1494         INSERT_PROC_ADDRESS(gl, GetBufferPointervOES);
1495 
1496         // GL_EXT_map_buffer_range
1497         INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT);
1498         INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT);
1499 
1500         // GL_EXT_debug_marker
1501         INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT);
1502         INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT);
1503         INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT);
1504 
1505         // GL_OES_EGL_image
1506         INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES);
1507         INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES);
1508 
1509         // GL_OES_vertex_array_object
1510         INSERT_PROC_ADDRESS(gl, BindVertexArrayOES);
1511         INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES);
1512         INSERT_PROC_ADDRESS(gl, GenVertexArraysOES);
1513         INSERT_PROC_ADDRESS(gl, IsVertexArrayOES);
1514 
1515         // GL_KHR_debug
1516         INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR);
1517         INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR);
1518         INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR);
1519         INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR);
1520         INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR);
1521         INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR);
1522         INSERT_PROC_ADDRESS(gl, ObjectLabelKHR);
1523         INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR);
1524         INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR);
1525         INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR);
1526         INSERT_PROC_ADDRESS(gl, GetPointervKHR);
1527 
1528         // GL_CHROMIUM_bind_uniform_location
1529         INSERT_PROC_ADDRESS(gl, BindUniformLocationCHROMIUM);
1530 
1531         // GL_CHROMIUM_copy_texture
1532         INSERT_PROC_ADDRESS(gl, CopyTextureCHROMIUM);
1533         INSERT_PROC_ADDRESS(gl, CopySubTextureCHROMIUM);
1534 
1535         // GL_CHROMIUM_copy_compressed_texture
1536         INSERT_PROC_ADDRESS(gl, CompressedCopyTextureCHROMIUM);
1537 
1538         // GL_ANGLE_webgl_compatibility
1539         INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE);
1540 
1541         // GL_ANGLE_robust_client_memory
1542         INSERT_PROC_ADDRESS(gl, GetBooleanvRobustANGLE);
1543         INSERT_PROC_ADDRESS(gl, GetBufferParameterivRobustANGLE);
1544         INSERT_PROC_ADDRESS(gl, GetFloatvRobustANGLE);
1545         INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameterivRobustANGLE);
1546         INSERT_PROC_ADDRESS(gl, GetIntegervRobustANGLE);
1547         INSERT_PROC_ADDRESS(gl, GetProgramivRobustANGLE);
1548         INSERT_PROC_ADDRESS(gl, GetRenderbufferParameterivRobustANGLE);
1549         INSERT_PROC_ADDRESS(gl, GetShaderivRobustANGLE);
1550         INSERT_PROC_ADDRESS(gl, GetTexParameterfvRobustANGLE);
1551         INSERT_PROC_ADDRESS(gl, GetTexParameterivRobustANGLE);
1552         INSERT_PROC_ADDRESS(gl, GetUniformfvRobustANGLE);
1553         INSERT_PROC_ADDRESS(gl, GetUniformivRobustANGLE);
1554         INSERT_PROC_ADDRESS(gl, GetVertexAttribfvRobustANGLE);
1555         INSERT_PROC_ADDRESS(gl, GetVertexAttribivRobustANGLE);
1556         INSERT_PROC_ADDRESS(gl, GetVertexAttribPointervRobustANGLE);
1557         INSERT_PROC_ADDRESS(gl, ReadPixelsRobustANGLE);
1558         INSERT_PROC_ADDRESS(gl, TexImage2DRobustANGLE);
1559         INSERT_PROC_ADDRESS(gl, TexParameterfvRobustANGLE);
1560         INSERT_PROC_ADDRESS(gl, TexParameterivRobustANGLE);
1561         INSERT_PROC_ADDRESS(gl, TexSubImage2DRobustANGLE);
1562         INSERT_PROC_ADDRESS(gl, TexImage3DRobustANGLE);
1563         INSERT_PROC_ADDRESS(gl, TexSubImage3DRobustANGLE);
1564         INSERT_PROC_ADDRESS(gl, GetQueryivRobustANGLE);
1565         INSERT_PROC_ADDRESS(gl, GetQueryObjectuivRobustANGLE);
1566         INSERT_PROC_ADDRESS(gl, GetBufferPointervRobustANGLE);
1567         INSERT_PROC_ADDRESS(gl, GetIntegeri_vRobustANGLE);
1568         INSERT_PROC_ADDRESS(gl, GetInternalformativRobustANGLE);
1569         INSERT_PROC_ADDRESS(gl, GetVertexAttribIivRobustANGLE);
1570         INSERT_PROC_ADDRESS(gl, GetVertexAttribIuivRobustANGLE);
1571         INSERT_PROC_ADDRESS(gl, GetUniformuivRobustANGLE);
1572         INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockivRobustANGLE);
1573         INSERT_PROC_ADDRESS(gl, GetInteger64vRobustANGLE);
1574         INSERT_PROC_ADDRESS(gl, GetInteger64i_vRobustANGLE);
1575         INSERT_PROC_ADDRESS(gl, GetBufferParameteri64vRobustANGLE);
1576         INSERT_PROC_ADDRESS(gl, SamplerParameterivRobustANGLE);
1577         INSERT_PROC_ADDRESS(gl, SamplerParameterfvRobustANGLE);
1578         INSERT_PROC_ADDRESS(gl, GetSamplerParameterivRobustANGLE);
1579         INSERT_PROC_ADDRESS(gl, GetSamplerParameterfvRobustANGLE);
1580         INSERT_PROC_ADDRESS(gl, GetFramebufferParameterivRobustANGLE);
1581         INSERT_PROC_ADDRESS(gl, GetProgramInterfaceivRobustANGLE);
1582         INSERT_PROC_ADDRESS(gl, GetBooleani_vRobustANGLE);
1583         INSERT_PROC_ADDRESS(gl, GetMultisamplefvRobustANGLE);
1584         INSERT_PROC_ADDRESS(gl, GetTexLevelParameterivRobustANGLE);
1585         INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfvRobustANGLE);
1586         INSERT_PROC_ADDRESS(gl, GetPointervRobustANGLERobustANGLE);
1587         INSERT_PROC_ADDRESS(gl, ReadnPixelsRobustANGLE);
1588         INSERT_PROC_ADDRESS(gl, GetnUniformfvRobustANGLE);
1589         INSERT_PROC_ADDRESS(gl, GetnUniformivRobustANGLE);
1590         INSERT_PROC_ADDRESS(gl, GetnUniformuivRobustANGLE);
1591         INSERT_PROC_ADDRESS(gl, TexParameterIivRobustANGLE);
1592         INSERT_PROC_ADDRESS(gl, TexParameterIuivRobustANGLE);
1593         INSERT_PROC_ADDRESS(gl, GetTexParameterIivRobustANGLE);
1594         INSERT_PROC_ADDRESS(gl, GetTexParameterIuivRobustANGLE);
1595         INSERT_PROC_ADDRESS(gl, SamplerParameterIivRobustANGLE);
1596         INSERT_PROC_ADDRESS(gl, SamplerParameterIuivRobustANGLE);
1597         INSERT_PROC_ADDRESS(gl, GetSamplerParameterIivRobustANGLE);
1598         INSERT_PROC_ADDRESS(gl, GetSamplerParameterIuivRobustANGLE);
1599         INSERT_PROC_ADDRESS(gl, GetQueryObjectivRobustANGLE);
1600         INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vRobustANGLE);
1601         INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vRobustANGLE);
1602 
1603         // GLES3 core
1604         INSERT_PROC_ADDRESS(gl, ReadBuffer);
1605         INSERT_PROC_ADDRESS(gl, DrawRangeElements);
1606         INSERT_PROC_ADDRESS(gl, TexImage3D);
1607         INSERT_PROC_ADDRESS(gl, TexSubImage3D);
1608         INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D);
1609         INSERT_PROC_ADDRESS(gl, CompressedTexImage3D);
1610         INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D);
1611         INSERT_PROC_ADDRESS(gl, GenQueries);
1612         INSERT_PROC_ADDRESS(gl, DeleteQueries);
1613         INSERT_PROC_ADDRESS(gl, IsQuery);
1614         INSERT_PROC_ADDRESS(gl, BeginQuery);
1615         INSERT_PROC_ADDRESS(gl, EndQuery);
1616         INSERT_PROC_ADDRESS(gl, GetQueryiv);
1617         INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv);
1618         INSERT_PROC_ADDRESS(gl, UnmapBuffer);
1619         INSERT_PROC_ADDRESS(gl, GetBufferPointerv);
1620         INSERT_PROC_ADDRESS(gl, DrawBuffers);
1621         INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv);
1622         INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv);
1623         INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv);
1624         INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv);
1625         INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv);
1626         INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv);
1627         INSERT_PROC_ADDRESS(gl, BlitFramebuffer);
1628         INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample);
1629         INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer);
1630         INSERT_PROC_ADDRESS(gl, MapBufferRange);
1631         INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange);
1632         INSERT_PROC_ADDRESS(gl, BindVertexArray);
1633         INSERT_PROC_ADDRESS(gl, DeleteVertexArrays);
1634         INSERT_PROC_ADDRESS(gl, GenVertexArrays);
1635         INSERT_PROC_ADDRESS(gl, IsVertexArray);
1636         INSERT_PROC_ADDRESS(gl, GetIntegeri_v);
1637         INSERT_PROC_ADDRESS(gl, BeginTransformFeedback);
1638         INSERT_PROC_ADDRESS(gl, EndTransformFeedback);
1639         INSERT_PROC_ADDRESS(gl, BindBufferRange);
1640         INSERT_PROC_ADDRESS(gl, BindBufferBase);
1641         INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings);
1642         INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying);
1643         INSERT_PROC_ADDRESS(gl, VertexAttribIPointer);
1644         INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv);
1645         INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv);
1646         INSERT_PROC_ADDRESS(gl, VertexAttribI4i);
1647         INSERT_PROC_ADDRESS(gl, VertexAttribI4ui);
1648         INSERT_PROC_ADDRESS(gl, VertexAttribI4iv);
1649         INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv);
1650         INSERT_PROC_ADDRESS(gl, GetUniformuiv);
1651         INSERT_PROC_ADDRESS(gl, GetFragDataLocation);
1652         INSERT_PROC_ADDRESS(gl, Uniform1ui);
1653         INSERT_PROC_ADDRESS(gl, Uniform2ui);
1654         INSERT_PROC_ADDRESS(gl, Uniform3ui);
1655         INSERT_PROC_ADDRESS(gl, Uniform4ui);
1656         INSERT_PROC_ADDRESS(gl, Uniform1uiv);
1657         INSERT_PROC_ADDRESS(gl, Uniform2uiv);
1658         INSERT_PROC_ADDRESS(gl, Uniform3uiv);
1659         INSERT_PROC_ADDRESS(gl, Uniform4uiv);
1660         INSERT_PROC_ADDRESS(gl, ClearBufferiv);
1661         INSERT_PROC_ADDRESS(gl, ClearBufferuiv);
1662         INSERT_PROC_ADDRESS(gl, ClearBufferfv);
1663         INSERT_PROC_ADDRESS(gl, ClearBufferfi);
1664         INSERT_PROC_ADDRESS(gl, GetStringi);
1665         INSERT_PROC_ADDRESS(gl, CopyBufferSubData);
1666         INSERT_PROC_ADDRESS(gl, GetUniformIndices);
1667         INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv);
1668         INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex);
1669         INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv);
1670         INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName);
1671         INSERT_PROC_ADDRESS(gl, UniformBlockBinding);
1672         INSERT_PROC_ADDRESS(gl, DrawArraysInstanced);
1673         INSERT_PROC_ADDRESS(gl, DrawElementsInstanced);
1674         // FenceSync is the name of a class, the function has an added _ to prevent a name conflict.
1675         INSERT_PROC_ADDRESS_NO_NS("glFenceSync", gl::FenceSync_);
1676         INSERT_PROC_ADDRESS(gl, IsSync);
1677         INSERT_PROC_ADDRESS(gl, DeleteSync);
1678         INSERT_PROC_ADDRESS(gl, ClientWaitSync);
1679         INSERT_PROC_ADDRESS(gl, WaitSync);
1680         INSERT_PROC_ADDRESS(gl, GetInteger64v);
1681         INSERT_PROC_ADDRESS(gl, GetSynciv);
1682         INSERT_PROC_ADDRESS(gl, GetInteger64i_v);
1683         INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v);
1684         INSERT_PROC_ADDRESS(gl, GenSamplers);
1685         INSERT_PROC_ADDRESS(gl, DeleteSamplers);
1686         INSERT_PROC_ADDRESS(gl, IsSampler);
1687         INSERT_PROC_ADDRESS(gl, BindSampler);
1688         INSERT_PROC_ADDRESS(gl, SamplerParameteri);
1689         INSERT_PROC_ADDRESS(gl, SamplerParameteriv);
1690         INSERT_PROC_ADDRESS(gl, SamplerParameterf);
1691         INSERT_PROC_ADDRESS(gl, SamplerParameterfv);
1692         INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv);
1693         INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv);
1694         INSERT_PROC_ADDRESS(gl, VertexAttribDivisor);
1695         INSERT_PROC_ADDRESS(gl, BindTransformFeedback);
1696         INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks);
1697         INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks);
1698         INSERT_PROC_ADDRESS(gl, IsTransformFeedback);
1699         INSERT_PROC_ADDRESS(gl, PauseTransformFeedback);
1700         INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback);
1701         INSERT_PROC_ADDRESS(gl, GetProgramBinary);
1702         INSERT_PROC_ADDRESS(gl, ProgramBinary);
1703         INSERT_PROC_ADDRESS(gl, ProgramParameteri);
1704         INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer);
1705         INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer);
1706         INSERT_PROC_ADDRESS(gl, TexStorage2D);
1707         INSERT_PROC_ADDRESS(gl, TexStorage3D);
1708         INSERT_PROC_ADDRESS(gl, GetInternalformativ);
1709 
1710         // GLES31 core
1711         INSERT_PROC_ADDRESS(gl, DispatchCompute);
1712         INSERT_PROC_ADDRESS(gl, DispatchComputeIndirect);
1713         INSERT_PROC_ADDRESS(gl, DrawArraysIndirect);
1714         INSERT_PROC_ADDRESS(gl, DrawElementsIndirect);
1715         INSERT_PROC_ADDRESS(gl, FramebufferParameteri);
1716         INSERT_PROC_ADDRESS(gl, GetFramebufferParameteriv);
1717         INSERT_PROC_ADDRESS(gl, GetProgramInterfaceiv);
1718         INSERT_PROC_ADDRESS(gl, GetProgramResourceIndex);
1719         INSERT_PROC_ADDRESS(gl, GetProgramResourceName);
1720         INSERT_PROC_ADDRESS(gl, GetProgramResourceiv);
1721         INSERT_PROC_ADDRESS(gl, GetProgramResourceLocation);
1722         INSERT_PROC_ADDRESS(gl, UseProgramStages);
1723         INSERT_PROC_ADDRESS(gl, ActiveShaderProgram);
1724         INSERT_PROC_ADDRESS(gl, CreateShaderProgramv);
1725         INSERT_PROC_ADDRESS(gl, BindProgramPipeline);
1726         INSERT_PROC_ADDRESS(gl, DeleteProgramPipelines);
1727         INSERT_PROC_ADDRESS(gl, GenProgramPipelines);
1728         INSERT_PROC_ADDRESS(gl, IsProgramPipeline);
1729         INSERT_PROC_ADDRESS(gl, GetProgramPipelineiv);
1730         INSERT_PROC_ADDRESS(gl, ProgramUniform1i);
1731         INSERT_PROC_ADDRESS(gl, ProgramUniform2i);
1732         INSERT_PROC_ADDRESS(gl, ProgramUniform3i);
1733         INSERT_PROC_ADDRESS(gl, ProgramUniform4i);
1734         INSERT_PROC_ADDRESS(gl, ProgramUniform1ui);
1735         INSERT_PROC_ADDRESS(gl, ProgramUniform2ui);
1736         INSERT_PROC_ADDRESS(gl, ProgramUniform3ui);
1737         INSERT_PROC_ADDRESS(gl, ProgramUniform4ui);
1738         INSERT_PROC_ADDRESS(gl, ProgramUniform1f);
1739         INSERT_PROC_ADDRESS(gl, ProgramUniform2f);
1740         INSERT_PROC_ADDRESS(gl, ProgramUniform3f);
1741         INSERT_PROC_ADDRESS(gl, ProgramUniform4f);
1742         INSERT_PROC_ADDRESS(gl, ProgramUniform1iv);
1743         INSERT_PROC_ADDRESS(gl, ProgramUniform2iv);
1744         INSERT_PROC_ADDRESS(gl, ProgramUniform3iv);
1745         INSERT_PROC_ADDRESS(gl, ProgramUniform4iv);
1746         INSERT_PROC_ADDRESS(gl, ProgramUniform1uiv);
1747         INSERT_PROC_ADDRESS(gl, ProgramUniform2uiv);
1748         INSERT_PROC_ADDRESS(gl, ProgramUniform3uiv);
1749         INSERT_PROC_ADDRESS(gl, ProgramUniform4uiv);
1750         INSERT_PROC_ADDRESS(gl, ProgramUniform1fv);
1751         INSERT_PROC_ADDRESS(gl, ProgramUniform2fv);
1752         INSERT_PROC_ADDRESS(gl, ProgramUniform3fv);
1753         INSERT_PROC_ADDRESS(gl, ProgramUniform4fv);
1754         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2fv);
1755         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3fv);
1756         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4fv);
1757         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x3fv);
1758         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x2fv);
1759         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x4fv);
1760         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x2fv);
1761         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x4fv);
1762         INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x3fv);
1763         INSERT_PROC_ADDRESS(gl, ValidateProgramPipeline);
1764         INSERT_PROC_ADDRESS(gl, GetProgramPipelineInfoLog);
1765         INSERT_PROC_ADDRESS(gl, BindImageTexture);
1766         INSERT_PROC_ADDRESS(gl, GetBooleani_v);
1767         INSERT_PROC_ADDRESS(gl, MemoryBarrier);
1768         INSERT_PROC_ADDRESS(gl, MemoryBarrierByRegion);
1769         INSERT_PROC_ADDRESS(gl, TexStorage2DMultisample);
1770         INSERT_PROC_ADDRESS(gl, GetMultisamplefv);
1771         INSERT_PROC_ADDRESS(gl, SampleMaski);
1772         INSERT_PROC_ADDRESS(gl, GetTexLevelParameteriv);
1773         INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfv);
1774         INSERT_PROC_ADDRESS(gl, BindVertexBuffer);
1775         INSERT_PROC_ADDRESS(gl, VertexAttribFormat);
1776         INSERT_PROC_ADDRESS(gl, VertexAttribIFormat);
1777         INSERT_PROC_ADDRESS(gl, VertexAttribBinding);
1778         INSERT_PROC_ADDRESS(gl, VertexBindingDivisor);
1779 
1780         // EGL 1.0
1781         INSERT_PROC_ADDRESS(egl, ChooseConfig);
1782         INSERT_PROC_ADDRESS(egl, CopyBuffers);
1783         INSERT_PROC_ADDRESS(egl, CreateContext);
1784         INSERT_PROC_ADDRESS(egl, CreatePbufferSurface);
1785         INSERT_PROC_ADDRESS(egl, CreatePixmapSurface);
1786         INSERT_PROC_ADDRESS(egl, CreateWindowSurface);
1787         INSERT_PROC_ADDRESS(egl, DestroyContext);
1788         INSERT_PROC_ADDRESS(egl, DestroySurface);
1789         INSERT_PROC_ADDRESS(egl, GetConfigAttrib);
1790         INSERT_PROC_ADDRESS(egl, GetConfigs);
1791         INSERT_PROC_ADDRESS(egl, GetCurrentDisplay);
1792         INSERT_PROC_ADDRESS(egl, GetCurrentSurface);
1793         INSERT_PROC_ADDRESS(egl, GetDisplay);
1794         INSERT_PROC_ADDRESS(egl, GetError);
1795         INSERT_PROC_ADDRESS(egl, GetProcAddress);
1796         INSERT_PROC_ADDRESS(egl, Initialize);
1797         INSERT_PROC_ADDRESS(egl, MakeCurrent);
1798         INSERT_PROC_ADDRESS(egl, QueryContext);
1799         INSERT_PROC_ADDRESS(egl, QueryString);
1800         INSERT_PROC_ADDRESS(egl, QuerySurface);
1801         INSERT_PROC_ADDRESS(egl, SwapBuffers);
1802         INSERT_PROC_ADDRESS(egl, Terminate);
1803         INSERT_PROC_ADDRESS(egl, WaitGL);
1804         INSERT_PROC_ADDRESS(egl, WaitNative);
1805 
1806         // EGL 1.1
1807         INSERT_PROC_ADDRESS(egl, BindTexImage);
1808         INSERT_PROC_ADDRESS(egl, ReleaseTexImage);
1809         INSERT_PROC_ADDRESS(egl, SurfaceAttrib);
1810         INSERT_PROC_ADDRESS(egl, SwapInterval);
1811 
1812         // EGL 1.2
1813         INSERT_PROC_ADDRESS(egl, BindAPI);
1814         INSERT_PROC_ADDRESS(egl, QueryAPI);
1815         INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer);
1816         INSERT_PROC_ADDRESS(egl, ReleaseThread);
1817         INSERT_PROC_ADDRESS(egl, WaitClient);
1818 
1819         // EGL 1.4
1820         INSERT_PROC_ADDRESS(egl, GetCurrentContext);
1821 
1822         // EGL 1.5
1823         INSERT_PROC_ADDRESS(egl, CreateSync);
1824         INSERT_PROC_ADDRESS(egl, DestroySync);
1825         INSERT_PROC_ADDRESS(egl, ClientWaitSync);
1826         INSERT_PROC_ADDRESS(egl, GetSyncAttrib);
1827         INSERT_PROC_ADDRESS(egl, CreateImage);
1828         INSERT_PROC_ADDRESS(egl, DestroyImage);
1829         INSERT_PROC_ADDRESS(egl, GetPlatformDisplay);
1830         INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface);
1831         INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface);
1832         INSERT_PROC_ADDRESS(egl, WaitSync);
1833 
1834         // EGL_ANGLE_query_surface_pointer
1835         INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE);
1836 
1837         // EGL_NV_post_sub_buffer
1838         INSERT_PROC_ADDRESS(egl, PostSubBufferNV);
1839 
1840         // EGL_EXT_platform_base
1841         INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT);
1842 
1843         // EGL_EXT_device_query
1844         INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT);
1845         INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT);
1846         INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT);
1847 
1848         // EGL_KHR_image_base/EGL_KHR_image
1849         INSERT_PROC_ADDRESS(egl, CreateImageKHR);
1850         INSERT_PROC_ADDRESS(egl, DestroyImageKHR);
1851 
1852         // EGL_EXT_device_creation
1853         INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE);
1854         INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE);
1855 
1856         // EGL_KHR_stream
1857         INSERT_PROC_ADDRESS(egl, CreateStreamKHR);
1858         INSERT_PROC_ADDRESS(egl, DestroyStreamKHR);
1859         INSERT_PROC_ADDRESS(egl, StreamAttribKHR);
1860         INSERT_PROC_ADDRESS(egl, QueryStreamKHR);
1861         INSERT_PROC_ADDRESS(egl, QueryStreamu64KHR);
1862 
1863         // EGL_KHR_stream_consumer_gltexture
1864         INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalKHR);
1865         INSERT_PROC_ADDRESS(egl, StreamConsumerAcquireKHR);
1866         INSERT_PROC_ADDRESS(egl, StreamConsumerReleaseKHR);
1867 
1868         // EGL_NV_stream_consumer_gltexture_yuv
1869         INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalAttribsNV);
1870 
1871         // EGL_ANGLE_stream_producer_d3d_texture_nv12
1872         INSERT_PROC_ADDRESS(egl, CreateStreamProducerD3DTextureNV12ANGLE);
1873         INSERT_PROC_ADDRESS(egl, StreamPostD3DTextureNV12ANGLE);
1874 
1875         // EGL_EXT_swap_buffers_with_damage
1876         INSERT_PROC_ADDRESS(egl, SwapBuffersWithDamageEXT);
1877 
1878         // angle::Platform related entry points
1879         INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformInitialize", ANGLEPlatformInitialize);
1880         INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformShutdown", ANGLEPlatformShutdown);
1881 
1882 #undef INSERT_PROC_ADDRESS
1883 #undef INSERT_PROC_ADDRESS_NO_NS
1884 
1885         return map;
1886     };
1887 
1888     static const ProcAddressMap procAddressMap = generateProcAddressMap();
1889 
1890     thread->setError(Error(EGL_SUCCESS));
1891     auto iter = procAddressMap.find(procname);
1892     return iter != procAddressMap.end() ? iter->second : nullptr;
1893 }
1894 
1895 }
1896