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