1 //
2 // Copyright (c) 2002-2010 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 // libEGL.cpp: Implements the exported EGL functions.
8 
9 #include <exception>
10 
11 #include "common/debug.h"
12 #include "libGLESv2/Context.h"
13 
14 #include "libEGL/main.h"
15 #include "libEGL/Display.h"
16 
17 
validate(egl::Display * display)18 bool validate(egl::Display *display)
19 {
20     if (display == EGL_NO_DISPLAY)
21     {
22         return error(EGL_BAD_DISPLAY, false);
23     }
24 
25     if (!display->isInitialized())
26     {
27         return error(EGL_NOT_INITIALIZED, false);
28     }
29 
30     return true;
31 }
32 
validate(egl::Display * display,EGLConfig config)33 bool validate(egl::Display *display, EGLConfig config)
34 {
35     if (!validate(display))
36     {
37         return false;
38     }
39 
40     if (!display->isValidConfig(config))
41     {
42         return error(EGL_BAD_CONFIG, false);
43     }
44 
45     return true;
46 }
47 
validate(egl::Display * display,gl::Context * context)48 bool validate(egl::Display *display, gl::Context *context)
49 {
50     if (!validate(display))
51     {
52         return false;
53     }
54 
55     if (!display->isValidContext(context))
56     {
57         return error(EGL_BAD_CONTEXT, false);
58     }
59 
60     return true;
61 }
62 
validate(egl::Display * display,egl::Surface * surface)63 bool validate(egl::Display *display, egl::Surface *surface)
64 {
65     if (!validate(display))
66     {
67         return false;
68     }
69 
70     if (!display->isValidSurface(surface))
71     {
72         return error(EGL_BAD_SURFACE, false);
73     }
74 
75     return true;
76 }
77 
78 extern "C"
79 {
eglGetError(void)80 EGLint __stdcall eglGetError(void)
81 {
82     TRACE("()");
83 
84     EGLint error = egl::getCurrentError();
85 
86     if (error != EGL_SUCCESS)
87     {
88         egl::setCurrentError(EGL_SUCCESS);
89     }
90 
91     return error;
92 }
93 
eglGetDisplay(EGLNativeDisplayType display_id)94 EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
95 {
96     TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
97 
98     try
99     {
100         // FIXME: Return the same EGLDisplay handle when display_id already created a display
101 
102         if (display_id == EGL_DEFAULT_DISPLAY)
103         {
104             return new egl::Display((HDC)NULL);
105         }
106         else
107         {
108             // FIXME: Check if display_id is a valid display device context
109 
110             return new egl::Display((HDC)display_id);
111         }
112     }
113     catch(std::bad_alloc&)
114     {
115         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
116     }
117 
118     return EGL_NO_DISPLAY;
119 }
120 
eglInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)121 EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
122 {
123     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
124           dpy, major, minor);
125 
126     try
127     {
128         if (dpy == EGL_NO_DISPLAY)
129         {
130             return error(EGL_BAD_DISPLAY, EGL_FALSE);
131         }
132 
133         egl::Display *display = static_cast<egl::Display*>(dpy);
134 
135         if (!display->initialize())
136         {
137             return error(EGL_NOT_INITIALIZED, EGL_FALSE);
138         }
139 
140         if (major) *major = 1;
141         if (minor) *minor = 4;
142 
143         return success(EGL_TRUE);
144     }
145     catch(std::bad_alloc&)
146     {
147         return error(EGL_BAD_ALLOC, EGL_FALSE);
148     }
149 
150     return EGL_FALSE;
151 }
152 
eglTerminate(EGLDisplay dpy)153 EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
154 {
155     TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy);
156 
157     try
158     {
159         if (dpy == EGL_NO_DISPLAY)
160         {
161             return error(EGL_BAD_DISPLAY, EGL_FALSE);
162         }
163 
164         egl::Display *display = static_cast<egl::Display*>(dpy);
165 
166         display->terminate();
167 
168         return success(EGL_TRUE);
169     }
170     catch(std::bad_alloc&)
171     {
172         return error(EGL_BAD_ALLOC, EGL_FALSE);
173     }
174 
175     return EGL_FALSE;
176 }
177 
eglQueryString(EGLDisplay dpy,EGLint name)178 const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
179 {
180     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
181 
182     try
183     {
184         egl::Display *display = static_cast<egl::Display*>(dpy);
185 
186         if (!validate(display))
187         {
188             return NULL;
189         }
190 
191         switch (name)
192         {
193           case EGL_CLIENT_APIS:
194             return success("OpenGL_ES");
195           case EGL_EXTENSIONS:
196             return success("");
197           case EGL_VENDOR:
198             return success("TransGaming Inc.");
199           case EGL_VERSION:
200             return success("1.4 (git-devel " __DATE__ " "  __TIME__ ")");
201         }
202 
203         return error(EGL_BAD_PARAMETER, (const char*)NULL);
204     }
205     catch(std::bad_alloc&)
206     {
207         return error(EGL_BAD_ALLOC, (const char*)NULL);
208     }
209 
210     return NULL;
211 }
212 
eglGetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)213 EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
214 {
215     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
216           "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
217           dpy, configs, config_size, num_config);
218 
219     try
220     {
221         egl::Display *display = static_cast<egl::Display*>(dpy);
222 
223         if (!validate(display))
224         {
225             return EGL_FALSE;
226         }
227 
228         if (!num_config)
229         {
230             return error(EGL_BAD_PARAMETER, EGL_FALSE);
231         }
232 
233         const EGLint attribList[] =    {EGL_NONE};
234 
235         if (!display->getConfigs(configs, attribList, config_size, num_config))
236         {
237             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
238         }
239 
240         return success(EGL_TRUE);
241     }
242     catch(std::bad_alloc&)
243     {
244         return error(EGL_BAD_ALLOC, EGL_FALSE);
245     }
246 
247     return EGL_FALSE;
248 }
249 
eglChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)250 EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
251 {
252     TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
253           "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
254           dpy, attrib_list, configs, config_size, num_config);
255 
256     try
257     {
258         egl::Display *display = static_cast<egl::Display*>(dpy);
259 
260         if (!validate(display))
261         {
262             return EGL_FALSE;
263         }
264 
265         if (!num_config)
266         {
267             return error(EGL_BAD_PARAMETER, EGL_FALSE);
268         }
269 
270         const EGLint attribList[] =    {EGL_NONE};
271 
272         if (!attrib_list)
273         {
274             attrib_list = attribList;
275         }
276 
277         display->getConfigs(configs, attrib_list, config_size, num_config);
278 
279         return success(EGL_TRUE);
280     }
281     catch(std::bad_alloc&)
282     {
283         return error(EGL_BAD_ALLOC, EGL_FALSE);
284     }
285 
286     return EGL_FALSE;
287 }
288 
eglGetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)289 EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
290 {
291     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
292           dpy, config, attribute, value);
293 
294     try
295     {
296         egl::Display *display = static_cast<egl::Display*>(dpy);
297 
298         if (!validate(display, config))
299         {
300             return EGL_FALSE;
301         }
302 
303         if (!display->getConfigAttrib(config, attribute, value))
304         {
305             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
306         }
307 
308         return success(EGL_TRUE);
309     }
310     catch(std::bad_alloc&)
311     {
312         return error(EGL_BAD_ALLOC, EGL_FALSE);
313     }
314 
315     return EGL_FALSE;
316 }
317 
eglCreateWindowSurface(EGLDisplay dpy,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)318 EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
319 {
320     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
321           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
322 
323     try
324     {
325         egl::Display *display = static_cast<egl::Display*>(dpy);
326 
327         if (!validate(display, config))
328         {
329             return EGL_NO_SURFACE;
330         }
331 
332         HWND window = (HWND)win;
333 
334         if (!IsWindow(window))
335         {
336             return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
337         }
338 
339         if (attrib_list)
340         {
341             while (*attrib_list != EGL_NONE)
342             {
343                 switch (attrib_list[0])
344                 {
345                   case EGL_RENDER_BUFFER:
346                     switch (attrib_list[1])
347                     {
348                       case EGL_BACK_BUFFER:
349                         break;
350                       case EGL_SINGLE_BUFFER:
351                         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
352                       default:
353                         return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
354                     }
355                     break;
356                   case EGL_VG_COLORSPACE:
357                     return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
358                   case EGL_VG_ALPHA_FORMAT:
359                     return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
360                   default:
361                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
362                 }
363 
364                 attrib_list += 2;
365             }
366         }
367 
368         if (display->hasExistingWindowSurface(window))
369         {
370             return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
371         }
372 
373         EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config);
374 
375         return success(surface);
376     }
377     catch(std::bad_alloc&)
378     {
379         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
380     }
381 
382     return EGL_NO_SURFACE;
383 }
384 
eglCreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)385 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
386 {
387     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
388           dpy, config, attrib_list);
389 
390     try
391     {
392         egl::Display *display = static_cast<egl::Display*>(dpy);
393 
394         if (!validate(display, config))
395         {
396             return EGL_NO_SURFACE;
397         }
398 
399         UNIMPLEMENTED();   // FIXME
400 
401         return success(EGL_NO_DISPLAY);
402     }
403     catch(std::bad_alloc&)
404     {
405         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
406     }
407 
408     return EGL_NO_SURFACE;
409 }
410 
eglCreatePixmapSurface(EGLDisplay dpy,EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attrib_list)411 EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
412 {
413     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
414           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
415 
416     try
417     {
418         egl::Display *display = static_cast<egl::Display*>(dpy);
419 
420         if (!validate(display, config))
421         {
422             return EGL_NO_SURFACE;
423         }
424 
425         UNIMPLEMENTED();   // FIXME
426 
427         return success(EGL_NO_DISPLAY);
428     }
429     catch(std::bad_alloc&)
430     {
431         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
432     }
433 
434     return EGL_NO_SURFACE;
435 }
436 
eglDestroySurface(EGLDisplay dpy,EGLSurface surface)437 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
438 {
439     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
440 
441     try
442     {
443         egl::Display *display = static_cast<egl::Display*>(dpy);
444 
445         if (!validate(display))
446         {
447             return EGL_FALSE;
448         }
449 
450         if (surface == EGL_NO_SURFACE)
451         {
452             return error(EGL_BAD_SURFACE, EGL_FALSE);
453         }
454 
455         display->destroySurface((egl::Surface*)surface);
456 
457         return success(EGL_TRUE);
458     }
459     catch(std::bad_alloc&)
460     {
461         return error(EGL_BAD_ALLOC, EGL_FALSE);
462     }
463 
464     return EGL_FALSE;
465 }
466 
eglQuerySurface(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)467 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
468 {
469     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
470           dpy, surface, attribute, value);
471 
472     try
473     {
474         egl::Display *display = static_cast<egl::Display*>(dpy);
475 
476         if (!validate(display))
477         {
478             return EGL_FALSE;
479         }
480 
481         if (surface == EGL_NO_SURFACE)
482         {
483             return error(EGL_BAD_SURFACE, EGL_FALSE);
484         }
485 
486         egl::Surface *eglSurface = (egl::Surface*)surface;
487 
488         switch (attribute)
489         {
490           case EGL_VG_ALPHA_FORMAT:
491             UNIMPLEMENTED();   // FIXME
492             break;
493           case EGL_VG_COLORSPACE:
494             UNIMPLEMENTED();   // FIXME
495             break;
496           case EGL_CONFIG_ID:
497             UNIMPLEMENTED();   // FIXME
498             break;
499           case EGL_HEIGHT:
500             *value = eglSurface->getHeight();
501             break;
502           case EGL_HORIZONTAL_RESOLUTION:
503             UNIMPLEMENTED();   // FIXME
504             break;
505           case EGL_LARGEST_PBUFFER:
506             UNIMPLEMENTED();   // FIXME
507             break;
508           case EGL_MIPMAP_TEXTURE:
509             UNIMPLEMENTED();   // FIXME
510             break;
511           case EGL_MIPMAP_LEVEL:
512             UNIMPLEMENTED();   // FIXME
513             break;
514           case EGL_MULTISAMPLE_RESOLVE:
515             UNIMPLEMENTED();   // FIXME
516             break;
517           case EGL_PIXEL_ASPECT_RATIO:
518             UNIMPLEMENTED();   // FIXME
519             break;
520           case EGL_RENDER_BUFFER:
521             UNIMPLEMENTED();   // FIXME
522             break;
523           case EGL_SWAP_BEHAVIOR:
524             UNIMPLEMENTED();   // FIXME
525             break;
526           case EGL_TEXTURE_FORMAT:
527             UNIMPLEMENTED();   // FIXME
528             break;
529           case EGL_TEXTURE_TARGET:
530             UNIMPLEMENTED();   // FIXME
531             break;
532           case EGL_VERTICAL_RESOLUTION:
533             UNIMPLEMENTED();   // FIXME
534             break;
535           case EGL_WIDTH:
536             *value = eglSurface->getWidth();
537             break;
538           default:
539             return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
540         }
541 
542         return success(EGL_TRUE);
543     }
544     catch(std::bad_alloc&)
545     {
546         return error(EGL_BAD_ALLOC, EGL_FALSE);
547     }
548 
549     return EGL_FALSE;
550 }
551 
eglBindAPI(EGLenum api)552 EGLBoolean __stdcall eglBindAPI(EGLenum api)
553 {
554     TRACE("(EGLenum api = 0x%X)", api);
555 
556     try
557     {
558         switch (api)
559         {
560           case EGL_OPENGL_API:
561           case EGL_OPENVG_API:
562             return error(EGL_BAD_PARAMETER, EGL_FALSE);   // Not supported by this implementation
563           case EGL_OPENGL_ES_API:
564             break;
565           default:
566             return error(EGL_BAD_PARAMETER, EGL_FALSE);
567         }
568 
569         egl::setCurrentAPI(api);
570 
571         return success(EGL_TRUE);
572     }
573     catch(std::bad_alloc&)
574     {
575         return error(EGL_BAD_ALLOC, EGL_FALSE);
576     }
577 
578     return EGL_FALSE;
579 }
580 
eglQueryAPI(void)581 EGLenum __stdcall eglQueryAPI(void)
582 {
583     TRACE("()");
584 
585     try
586     {
587         EGLenum API = egl::getCurrentAPI();
588 
589         return success(API);
590     }
591     catch(std::bad_alloc&)
592     {
593         return error(EGL_BAD_ALLOC, EGL_FALSE);
594     }
595 
596     return EGL_FALSE;
597 }
598 
eglWaitClient(void)599 EGLBoolean __stdcall eglWaitClient(void)
600 {
601     TRACE("()");
602 
603     try
604     {
605         UNIMPLEMENTED();   // FIXME
606 
607         return success(0);
608     }
609     catch(std::bad_alloc&)
610     {
611         return error(EGL_BAD_ALLOC, EGL_FALSE);
612     }
613 
614     return EGL_FALSE;
615 }
616 
eglReleaseThread(void)617 EGLBoolean __stdcall eglReleaseThread(void)
618 {
619     TRACE("()");
620 
621     try
622     {
623         eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
624 
625         return success(EGL_TRUE);
626     }
627     catch(std::bad_alloc&)
628     {
629         return error(EGL_BAD_ALLOC, EGL_FALSE);
630     }
631 
632     return EGL_FALSE;
633 }
634 
eglCreatePbufferFromClientBuffer(EGLDisplay dpy,EGLenum buftype,EGLClientBuffer buffer,EGLConfig config,const EGLint * attrib_list)635 EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
636 {
637     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
638           "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
639           dpy, buftype, buffer, config, attrib_list);
640 
641     try
642     {
643         egl::Display *display = static_cast<egl::Display*>(dpy);
644 
645         if (!validate(display, config))
646         {
647             return EGL_NO_SURFACE;
648         }
649 
650         UNIMPLEMENTED();   // FIXME
651 
652         return success(EGL_NO_SURFACE);
653     }
654     catch(std::bad_alloc&)
655     {
656         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
657     }
658 
659     return EGL_NO_SURFACE;
660 }
661 
eglSurfaceAttrib(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint value)662 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
663 {
664     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
665           dpy, surface, attribute, value);
666 
667     try
668     {
669         egl::Display *display = static_cast<egl::Display*>(dpy);
670 
671         if (!validate(display))
672         {
673             return EGL_FALSE;
674         }
675 
676         UNIMPLEMENTED();   // FIXME
677 
678         return success(EGL_TRUE);
679     }
680     catch(std::bad_alloc&)
681     {
682         return error(EGL_BAD_ALLOC, EGL_FALSE);
683     }
684 
685     return EGL_FALSE;
686 }
687 
eglBindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)688 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
689 {
690     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
691 
692     try
693     {
694         egl::Display *display = static_cast<egl::Display*>(dpy);
695 
696         if (!validate(display))
697         {
698             return EGL_FALSE;
699         }
700 
701         UNIMPLEMENTED();   // FIXME
702 
703         return success(EGL_TRUE);
704     }
705     catch(std::bad_alloc&)
706     {
707         return error(EGL_BAD_ALLOC, EGL_FALSE);
708     }
709 
710     return EGL_FALSE;
711 }
712 
eglReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)713 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
714 {
715     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
716 
717     try
718     {
719         egl::Display *display = static_cast<egl::Display*>(dpy);
720 
721         if (!validate(display))
722         {
723             return EGL_FALSE;
724         }
725 
726         UNIMPLEMENTED();   // FIXME
727 
728         return success(EGL_TRUE);
729     }
730     catch(std::bad_alloc&)
731     {
732         return error(EGL_BAD_ALLOC, EGL_FALSE);
733     }
734 
735     return EGL_FALSE;
736 }
737 
eglSwapInterval(EGLDisplay dpy,EGLint interval)738 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
739 {
740     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
741 
742     try
743     {
744         egl::Display *display = static_cast<egl::Display*>(dpy);
745 
746         if (!validate(display))
747         {
748             return EGL_FALSE;
749         }
750 
751         egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
752 
753         if (draw_surface == NULL)
754         {
755             return error(EGL_BAD_SURFACE, EGL_FALSE);
756         }
757 
758         draw_surface->setSwapInterval(interval);
759 
760         return success(EGL_TRUE);
761     }
762     catch(std::bad_alloc&)
763     {
764         return error(EGL_BAD_ALLOC, EGL_FALSE);
765     }
766 
767     return EGL_FALSE;
768 }
769 
eglCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)770 EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
771 {
772     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
773           "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
774 
775     try
776     {
777         // Get the requested client version (default is 1) and check it is two.
778         EGLint client_version = 1;
779         if (attrib_list)
780         {
781             for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
782             {
783                 if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
784                 {
785                     client_version = attribute[1];
786                 }
787                 else
788                 {
789                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
790                 }
791             }
792         }
793 
794         if (client_version != 2)
795         {
796             return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
797         }
798 
799         egl::Display *display = static_cast<egl::Display*>(dpy);
800 
801         if (!validate(display, config))
802         {
803             return EGL_NO_CONTEXT;
804         }
805 
806         EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
807 
808         return success(context);
809     }
810     catch(std::bad_alloc&)
811     {
812         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
813     }
814 
815     return EGL_NO_CONTEXT;
816 }
817 
eglDestroyContext(EGLDisplay dpy,EGLContext ctx)818 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
819 {
820     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
821 
822     try
823     {
824         egl::Display *display = static_cast<egl::Display*>(dpy);
825 
826         if (!validate(display))
827         {
828             return EGL_FALSE;
829         }
830 
831         if (ctx == EGL_NO_CONTEXT)
832         {
833             return error(EGL_BAD_CONTEXT, EGL_FALSE);
834         }
835 
836         display->destroyContext((gl::Context*)ctx);
837 
838         return success(EGL_TRUE);
839     }
840     catch(std::bad_alloc&)
841     {
842         return error(EGL_BAD_ALLOC, EGL_FALSE);
843     }
844 
845     return EGL_FALSE;
846 }
847 
eglMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)848 EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
849 {
850     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
851           dpy, draw, read, ctx);
852 
853     try
854     {
855         egl::Display *display = static_cast<egl::Display*>(dpy);
856         gl::Context *context = static_cast<gl::Context*>(ctx);
857         IDirect3DDevice9 *device = display->getDevice();
858 
859         if (!device || FAILED(device->TestCooperativeLevel()))
860         {
861             return error(EGL_CONTEXT_LOST, EGL_FALSE);
862         }
863 
864         if (ctx != EGL_NO_CONTEXT && !validate(display, context))
865         {
866             return EGL_FALSE;
867         }
868 
869         if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) ||
870             (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read))))
871         {
872             return EGL_FALSE;
873         }
874 
875         if (draw != read)
876         {
877             UNIMPLEMENTED();   // FIXME
878         }
879 
880         egl::setCurrentDisplay(dpy);
881         egl::setCurrentDrawSurface(draw);
882         egl::setCurrentReadSurface(read);
883 
884         glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
885 
886         return success(EGL_TRUE);
887     }
888     catch(std::bad_alloc&)
889     {
890         return error(EGL_BAD_ALLOC, EGL_FALSE);
891     }
892 
893     return EGL_FALSE;
894 }
895 
eglGetCurrentContext(void)896 EGLContext __stdcall eglGetCurrentContext(void)
897 {
898     TRACE("()");
899 
900     try
901     {
902         EGLContext context = glGetCurrentContext();
903 
904         return success(context);
905     }
906     catch(std::bad_alloc&)
907     {
908         return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
909     }
910 
911     return EGL_NO_CONTEXT;
912 }
913 
eglGetCurrentSurface(EGLint readdraw)914 EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
915 {
916     TRACE("(EGLint readdraw = %d)", readdraw);
917 
918     try
919     {
920         if (readdraw == EGL_READ)
921         {
922             EGLSurface read = egl::getCurrentReadSurface();
923             return success(read);
924         }
925         else if (readdraw == EGL_DRAW)
926         {
927             EGLSurface draw = egl::getCurrentDrawSurface();
928             return success(draw);
929         }
930         else
931         {
932             return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
933         }
934     }
935     catch(std::bad_alloc&)
936     {
937         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
938     }
939 
940     return EGL_NO_SURFACE;
941 }
942 
eglGetCurrentDisplay(void)943 EGLDisplay __stdcall eglGetCurrentDisplay(void)
944 {
945     TRACE("()");
946 
947     try
948     {
949         EGLDisplay dpy = egl::getCurrentDisplay();
950 
951         return success(dpy);
952     }
953     catch(std::bad_alloc&)
954     {
955         return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
956     }
957 
958     return EGL_NO_DISPLAY;
959 }
960 
eglQueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)961 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
962 {
963     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
964           dpy, ctx, attribute, value);
965 
966     try
967     {
968         egl::Display *display = static_cast<egl::Display*>(dpy);
969 
970         if (!validate(display))
971         {
972             return EGL_FALSE;
973         }
974 
975         UNIMPLEMENTED();   // FIXME
976 
977         return success(0);
978     }
979     catch(std::bad_alloc&)
980     {
981         return error(EGL_BAD_ALLOC, EGL_FALSE);
982     }
983 
984     return EGL_FALSE;
985 }
986 
eglWaitGL(void)987 EGLBoolean __stdcall eglWaitGL(void)
988 {
989     TRACE("()");
990 
991     try
992     {
993         UNIMPLEMENTED();   // FIXME
994 
995         return success(0);
996     }
997     catch(std::bad_alloc&)
998     {
999         return error(EGL_BAD_ALLOC, EGL_FALSE);
1000     }
1001 
1002     return EGL_FALSE;
1003 }
1004 
eglWaitNative(EGLint engine)1005 EGLBoolean __stdcall eglWaitNative(EGLint engine)
1006 {
1007     TRACE("(EGLint engine = %d)", engine);
1008 
1009     try
1010     {
1011         UNIMPLEMENTED();   // FIXME
1012 
1013         return success(0);
1014     }
1015     catch(std::bad_alloc&)
1016     {
1017         return error(EGL_BAD_ALLOC, EGL_FALSE);
1018     }
1019 
1020     return EGL_FALSE;
1021 }
1022 
eglSwapBuffers(EGLDisplay dpy,EGLSurface surface)1023 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1024 {
1025     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
1026 
1027     try
1028     {
1029         egl::Display *display = static_cast<egl::Display*>(dpy);
1030 
1031         if (!validate(display))
1032         {
1033             return EGL_FALSE;
1034         }
1035 
1036         if (surface == EGL_NO_SURFACE)
1037         {
1038             return error(EGL_BAD_SURFACE, EGL_FALSE);
1039         }
1040 
1041         egl::Surface *eglSurface = (egl::Surface*)surface;
1042 
1043         if (eglSurface->swap())
1044         {
1045             return success(EGL_TRUE);
1046         }
1047     }
1048     catch(std::bad_alloc&)
1049     {
1050         return error(EGL_BAD_ALLOC, EGL_FALSE);
1051     }
1052 
1053     return EGL_FALSE;
1054 }
1055 
eglCopyBuffers(EGLDisplay dpy,EGLSurface surface,EGLNativePixmapType target)1056 EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1057 {
1058     TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
1059 
1060     try
1061     {
1062         egl::Display *display = static_cast<egl::Display*>(dpy);
1063 
1064         if (!validate(display))
1065         {
1066             return EGL_FALSE;
1067         }
1068 
1069         UNIMPLEMENTED();   // FIXME
1070 
1071         return success(0);
1072     }
1073     catch(std::bad_alloc&)
1074     {
1075         return error(EGL_BAD_ALLOC, EGL_FALSE);
1076     }
1077 
1078     return EGL_FALSE;
1079 }
1080 
eglGetProcAddress(const char * procname)1081 __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
1082 {
1083     TRACE("(const char *procname = \"%s\")", procname);
1084 
1085     try
1086     {
1087         struct Extension
1088         {
1089             const char *name;
1090             __eglMustCastToProperFunctionPointerType address;
1091         };
1092 
1093         static const Extension eglExtensions[] =
1094         {
1095             {"", NULL},
1096         };
1097 
1098         for (int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
1099         {
1100             if (strcmp(procname, eglExtensions[ext].name) == 0)
1101             {
1102                 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
1103             }
1104         }
1105 
1106         return glGetProcAddress(procname);
1107     }
1108     catch(std::bad_alloc&)
1109     {
1110         return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
1111     }
1112 
1113     return NULL;
1114 }
1115 }
1116