Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 //
7 // libEGL.cpp: Implements the exported EGL functions.
9 #include <exception>
11 #include "common/debug.h"
12 #include "common/version.h"
13 #include "libGLESv2/Context.h"
14 #include "libGLESv2/Texture.h"
15 #include "libGLESv2/main.h"
16 #include "libGLESv2/renderer/SwapChain.h"
18 #include "libEGL/main.h"
19 #include "libEGL/Display.h"
20 #include "libEGL/Surface.h"
22 bool validateDisplay(egl::Display *display)
23 {
24 if (display == EGL_NO_DISPLAY)
25 {
26 return egl::error(EGL_BAD_DISPLAY, false);
27 }
29 if (!display->isInitialized())
30 {
31 return egl::error(EGL_NOT_INITIALIZED, false);
32 }
34 return true;
35 }
37 bool validateConfig(egl::Display *display, EGLConfig config)
38 {
39 if (!validateDisplay(display))
40 {
41 return false;
42 }
44 if (!display->isValidConfig(config))
45 {
46 return egl::error(EGL_BAD_CONFIG, false);
47 }
49 return true;
50 }
52 bool validateContext(egl::Display *display, gl::Context *context)
53 {
54 if (!validateDisplay(display))
55 {
56 return false;
57 }
59 if (!display->isValidContext(context))
60 {
61 return egl::error(EGL_BAD_CONTEXT, false);
62 }
64 return true;
65 }
67 bool validateSurface(egl::Display *display, egl::Surface *surface)
68 {
69 if (!validateDisplay(display))
70 {
71 return false;
72 }
74 if (!display->isValidSurface(surface))
75 {
76 return egl::error(EGL_BAD_SURFACE, false);
77 }
79 return true;
80 }
82 extern "C"
83 {
84 EGLint __stdcall eglGetError(void)
85 {
86 EVENT("()");
88 EGLint error = egl::getCurrentError();
90 if (error != EGL_SUCCESS)
91 {
92 egl::setCurrentError(EGL_SUCCESS);
93 }
95 return error;
96 }
98 EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
99 {
100 EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
102 try
103 {
104 return egl::Display::getDisplay(display_id);
105 }
106 catch(std::bad_alloc&)
107 {
108 return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
109 }
110 }
112 EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
113 {
114 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
115 dpy, major, minor);
117 try
118 {
119 if (dpy == EGL_NO_DISPLAY)
120 {
121 return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
122 }
124 egl::Display *display = static_cast<egl::Display*>(dpy);
126 if (!display->initialize())
127 {
128 return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
129 }
131 if (major) *major = 1;
132 if (minor) *minor = 4;
134 return egl::success(EGL_TRUE);
135 }
136 catch(std::bad_alloc&)
137 {
138 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
139 }
140 }
142 EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
143 {
144 EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
146 try
147 {
148 if (dpy == EGL_NO_DISPLAY)
149 {
150 return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
151 }
153 egl::Display *display = static_cast<egl::Display*>(dpy);
155 display->terminate();
157 return egl::success(EGL_TRUE);
158 }
159 catch(std::bad_alloc&)
160 {
161 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
162 }
163 }
165 const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
166 {
167 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
169 try
170 {
171 egl::Display *display = static_cast<egl::Display*>(dpy);
173 if (!validateDisplay(display))
174 {
175 return NULL;
176 }
178 switch (name)
179 {
180 case EGL_CLIENT_APIS:
181 return egl::success("OpenGL_ES");
182 case EGL_EXTENSIONS:
183 return egl::success(display->getExtensionString());
184 case EGL_VENDOR:
185 return egl::success(display->getVendorString());
186 case EGL_VERSION:
187 return egl::success("1.4 (ANGLE " VERSION_STRING ")");
188 }
190 return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
191 }
192 catch(std::bad_alloc&)
193 {
194 return egl::error(EGL_BAD_ALLOC, (const char*)NULL);
195 }
196 }
198 EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
199 {
200 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
201 "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
202 dpy, configs, config_size, num_config);
204 try
205 {
206 egl::Display *display = static_cast<egl::Display*>(dpy);
208 if (!validateDisplay(display))
209 {
210 return EGL_FALSE;
211 }
213 if (!num_config)
214 {
215 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
216 }
218 const EGLint attribList[] = {EGL_NONE};
220 if (!display->getConfigs(configs, attribList, config_size, num_config))
221 {
222 return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
223 }
225 return egl::success(EGL_TRUE);
226 }
227 catch(std::bad_alloc&)
228 {
229 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
230 }
231 }
233 EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
234 {
235 EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
236 "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
237 dpy, attrib_list, configs, config_size, num_config);
239 try
240 {
241 egl::Display *display = static_cast<egl::Display*>(dpy);
243 if (!validateDisplay(display))
244 {
245 return EGL_FALSE;
246 }
248 if (!num_config)
249 {
250 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
251 }
253 const EGLint attribList[] = {EGL_NONE};
255 if (!attrib_list)
256 {
257 attrib_list = attribList;
258 }
260 display->getConfigs(configs, attrib_list, config_size, num_config);
262 return egl::success(EGL_TRUE);
263 }
264 catch(std::bad_alloc&)
265 {
266 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
267 }
268 }
270 EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
271 {
272 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
273 dpy, config, attribute, value);
275 try
276 {
277 egl::Display *display = static_cast<egl::Display*>(dpy);
279 if (!validateConfig(display, config))
280 {
281 return EGL_FALSE;
282 }
284 if (!display->getConfigAttrib(config, attribute, value))
285 {
286 return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
287 }
289 return egl::success(EGL_TRUE);
290 }
291 catch(std::bad_alloc&)
292 {
293 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
294 }
295 }
297 EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
298 {
299 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
300 "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
302 try
303 {
304 egl::Display *display = static_cast<egl::Display*>(dpy);
306 if (!validateConfig(display, config))
307 {
308 return EGL_NO_SURFACE;
309 }
311 HWND window = (HWND)win;
313 if (!IsWindow(window))
314 {
315 return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
316 }
318 return display->createWindowSurface(window, config, attrib_list);
319 }
320 catch(std::bad_alloc&)
321 {
322 return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
323 }
324 }
326 EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
327 {
328 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
329 dpy, config, attrib_list);
331 try
332 {
333 egl::Display *display = static_cast<egl::Display*>(dpy);
335 if (!validateConfig(display, config))
336 {
337 return EGL_NO_SURFACE;
338 }
340 return display->createOffscreenSurface(config, NULL, attrib_list);
341 }
342 catch(std::bad_alloc&)
343 {
344 return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
345 }
346 }
348 EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
349 {
350 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
351 "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
353 try
354 {
355 egl::Display *display = static_cast<egl::Display*>(dpy);
357 if (!validateConfig(display, config))
358 {
359 return EGL_NO_SURFACE;
360 }
362 UNIMPLEMENTED(); // FIXME
364 return egl::success(EGL_NO_SURFACE);
365 }
366 catch(std::bad_alloc&)
367 {
368 return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
369 }
370 }
372 EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
373 {
374 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
376 try
377 {
378 egl::Display *display = static_cast<egl::Display*>(dpy);
379 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
381 if (!validateSurface(display, eglSurface))
382 {
383 return EGL_FALSE;
384 }
386 if (surface == EGL_NO_SURFACE)
387 {
388 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
389 }
391 display->destroySurface((egl::Surface*)surface);
393 return egl::success(EGL_TRUE);
394 }
395 catch(std::bad_alloc&)
396 {
397 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
398 }
399 }
401 EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
402 {
403 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
404 dpy, surface, attribute, value);
406 try
407 {
408 egl::Display *display = static_cast<egl::Display*>(dpy);
409 egl::Surface *eglSurface = (egl::Surface*)surface;
411 if (!validateSurface(display, eglSurface))
412 {
413 return EGL_FALSE;
414 }
416 if (surface == EGL_NO_SURFACE)
417 {
418 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
419 }
421 switch (attribute)
422 {
423 case EGL_VG_ALPHA_FORMAT:
424 UNIMPLEMENTED(); // FIXME
425 break;
426 case EGL_VG_COLORSPACE:
427 UNIMPLEMENTED(); // FIXME
428 break;
429 case EGL_CONFIG_ID:
430 UNIMPLEMENTED(); // FIXME
431 break;
432 case EGL_HEIGHT:
433 *value = eglSurface->getHeight();
434 break;
435 case EGL_HORIZONTAL_RESOLUTION:
436 UNIMPLEMENTED(); // FIXME
437 break;
438 case EGL_LARGEST_PBUFFER:
439 UNIMPLEMENTED(); // FIXME
440 break;
441 case EGL_MIPMAP_TEXTURE:
442 UNIMPLEMENTED(); // FIXME
443 break;
444 case EGL_MIPMAP_LEVEL:
445 UNIMPLEMENTED(); // FIXME
446 break;
447 case EGL_MULTISAMPLE_RESOLVE:
448 UNIMPLEMENTED(); // FIXME
449 break;
450 case EGL_PIXEL_ASPECT_RATIO:
451 UNIMPLEMENTED(); // FIXME
452 break;
453 case EGL_RENDER_BUFFER:
454 UNIMPLEMENTED(); // FIXME
455 break;
456 case EGL_SWAP_BEHAVIOR:
457 UNIMPLEMENTED(); // FIXME
458 break;
459 case EGL_TEXTURE_FORMAT:
460 UNIMPLEMENTED(); // FIXME
461 break;
462 case EGL_TEXTURE_TARGET:
463 UNIMPLEMENTED(); // FIXME
464 break;
465 case EGL_VERTICAL_RESOLUTION:
466 UNIMPLEMENTED(); // FIXME
467 break;
468 case EGL_WIDTH:
469 *value = eglSurface->getWidth();
470 break;
471 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
472 *value = eglSurface->isPostSubBufferSupported();
473 break;
474 default:
475 return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
476 }
478 return egl::success(EGL_TRUE);
479 }
480 catch(std::bad_alloc&)
481 {
482 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
483 }
484 }
486 EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
487 {
488 TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
489 dpy, surface, attribute, value);
491 try
492 {
493 egl::Display *display = static_cast<egl::Display*>(dpy);
494 egl::Surface *eglSurface = (egl::Surface*)surface;
496 if (!validateSurface(display, eglSurface))
497 {
498 return EGL_FALSE;
499 }
501 if (surface == EGL_NO_SURFACE)
502 {
503 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
504 }
506 switch (attribute)
507 {
508 case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
509 {
510 rx::SwapChain *swapchain = eglSurface->getSwapChain();
511 *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
512 }
513 break;
514 default:
515 return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
516 }
518 return egl::success(EGL_TRUE);
519 }
520 catch(std::bad_alloc&)
521 {
522 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
523 }
524 }
526 EGLBoolean __stdcall eglBindAPI(EGLenum api)
527 {
528 EVENT("(EGLenum api = 0x%X)", api);
530 try
531 {
532 switch (api)
533 {
534 case EGL_OPENGL_API:
535 case EGL_OPENVG_API:
536 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
537 case EGL_OPENGL_ES_API:
538 break;
539 default:
540 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
541 }
543 egl::setCurrentAPI(api);
545 return egl::success(EGL_TRUE);
546 }
547 catch(std::bad_alloc&)
548 {
549 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
550 }
551 }
553 EGLenum __stdcall eglQueryAPI(void)
554 {
555 EVENT("()");
557 try
558 {
559 EGLenum API = egl::getCurrentAPI();
561 return egl::success(API);
562 }
563 catch(std::bad_alloc&)
564 {
565 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
566 }
567 }
569 EGLBoolean __stdcall eglWaitClient(void)
570 {
571 EVENT("()");
573 try
574 {
575 UNIMPLEMENTED(); // FIXME
577 return egl::success(0);
578 }
579 catch(std::bad_alloc&)
580 {
581 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
582 }
583 }
585 EGLBoolean __stdcall eglReleaseThread(void)
586 {
587 EVENT("()");
589 try
590 {
591 eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
593 return egl::success(EGL_TRUE);
594 }
595 catch(std::bad_alloc&)
596 {
597 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
598 }
599 }
601 EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
602 {
603 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
604 "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
605 dpy, buftype, buffer, config, attrib_list);
607 try
608 {
609 egl::Display *display = static_cast<egl::Display*>(dpy);
611 if (!validateConfig(display, config))
612 {
613 return EGL_NO_SURFACE;
614 }
616 if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
617 {
618 return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
619 }
621 return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
622 }
623 catch(std::bad_alloc&)
624 {
625 return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
626 }
627 }
629 EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
630 {
631 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
632 dpy, surface, attribute, value);
634 try
635 {
636 egl::Display *display = static_cast<egl::Display*>(dpy);
637 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
639 if (!validateSurface(display, eglSurface))
640 {
641 return EGL_FALSE;
642 }
644 UNIMPLEMENTED(); // FIXME
646 return egl::success(EGL_TRUE);
647 }
648 catch(std::bad_alloc&)
649 {
650 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
651 }
652 }
654 EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
655 {
656 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
658 try
659 {
660 egl::Display *display = static_cast<egl::Display*>(dpy);
661 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
663 if (!validateSurface(display, eglSurface))
664 {
665 return EGL_FALSE;
666 }
668 if (buffer != EGL_BACK_BUFFER)
669 {
670 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
671 }
673 if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
674 {
675 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
676 }
678 if (eglSurface->getBoundTexture())
679 {
680 return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
681 }
683 if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
684 {
685 return egl::error(EGL_BAD_MATCH, EGL_FALSE);
686 }
688 if (!glBindTexImage(eglSurface))
689 {
690 return egl::error(EGL_BAD_MATCH, EGL_FALSE);
691 }
693 return egl::success(EGL_TRUE);
694 }
695 catch(std::bad_alloc&)
696 {
697 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
698 }
699 }
701 EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
702 {
703 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
705 try
706 {
707 egl::Display *display = static_cast<egl::Display*>(dpy);
708 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
710 if (!validateSurface(display, eglSurface))
711 {
712 return EGL_FALSE;
713 }
715 if (buffer != EGL_BACK_BUFFER)
716 {
717 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
718 }
720 if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
721 {
722 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
723 }
725 if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
726 {
727 return egl::error(EGL_BAD_MATCH, EGL_FALSE);
728 }
730 gl::Texture2D *texture = eglSurface->getBoundTexture();
732 if (texture)
733 {
734 texture->releaseTexImage();
735 }
737 return egl::success(EGL_TRUE);
738 }
739 catch(std::bad_alloc&)
740 {
741 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
742 }
743 }
745 EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
746 {
747 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
749 try
750 {
751 egl::Display *display = static_cast<egl::Display*>(dpy);
753 if (!validateDisplay(display))
754 {
755 return EGL_FALSE;
756 }
758 egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
760 if (draw_surface == NULL)
761 {
762 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
763 }
765 draw_surface->setSwapInterval(interval);
767 return egl::success(EGL_TRUE);
768 }
769 catch(std::bad_alloc&)
770 {
771 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
772 }
773 }
775 EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
776 {
777 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
778 "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
780 try
781 {
782 // Get the requested client version (default is 1) and check it is two.
783 EGLint client_version = 1;
784 bool reset_notification = false;
785 bool robust_access = false;
787 if (attrib_list)
788 {
789 for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
790 {
791 switch (attribute[0])
792 {
793 case EGL_CONTEXT_CLIENT_VERSION:
794 client_version = attribute[1];
795 break;
796 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
797 if (attribute[1] == EGL_TRUE)
798 {
799 return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
800 // robust_access = true;
801 }
802 else if (attribute[1] != EGL_FALSE)
803 return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
804 break;
805 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
806 if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
807 reset_notification = true;
808 else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
809 return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
810 break;
811 default:
812 return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
813 }
814 }
815 }
817 if (client_version != 2)
818 {
819 return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
820 }
822 if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification)
823 {
824 return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
825 }
827 egl::Display *display = static_cast<egl::Display*>(dpy);
829 if (!validateConfig(display, config))
830 {
831 return EGL_NO_CONTEXT;
832 }
834 EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
836 if (context)
837 return egl::success(context);
838 else
839 return egl::error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
840 }
841 catch(std::bad_alloc&)
842 {
843 return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
844 }
845 }
847 EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
848 {
849 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
851 try
852 {
853 egl::Display *display = static_cast<egl::Display*>(dpy);
854 gl::Context *context = static_cast<gl::Context*>(ctx);
856 if (!validateContext(display, context))
857 {
858 return EGL_FALSE;
859 }
861 if (ctx == EGL_NO_CONTEXT)
862 {
863 return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
864 }
866 display->destroyContext(context);
868 return egl::success(EGL_TRUE);
869 }
870 catch(std::bad_alloc&)
871 {
872 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
873 }
874 }
876 EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
877 {
878 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
879 dpy, draw, read, ctx);
881 try
882 {
883 egl::Display *display = static_cast<egl::Display*>(dpy);
884 gl::Context *context = static_cast<gl::Context*>(ctx);
886 if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
887 {
888 return EGL_FALSE;
889 }
891 if (dpy != EGL_NO_DISPLAY)
892 {
893 rx::Renderer *renderer = display->getRenderer();
894 if (renderer->testDeviceLost(true))
895 {
896 return EGL_FALSE;
897 }
899 if (renderer->isDeviceLost())
900 {
901 return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
902 }
903 }
905 if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
906 (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read))))
907 {
908 return EGL_FALSE;
909 }
911 if (draw != read)
912 {
913 UNIMPLEMENTED(); // FIXME
914 }
916 egl::setCurrentDisplay(dpy);
917 egl::setCurrentDrawSurface(draw);
918 egl::setCurrentReadSurface(read);
920 glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
922 return egl::success(EGL_TRUE);
923 }
924 catch(std::bad_alloc&)
925 {
926 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
927 }
928 }
930 EGLContext __stdcall eglGetCurrentContext(void)
931 {
932 EVENT("()");
934 try
935 {
936 EGLContext context = glGetCurrentContext();
938 return egl::success(context);
939 }
940 catch(std::bad_alloc&)
941 {
942 return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
943 }
944 }
946 EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
947 {
948 EVENT("(EGLint readdraw = %d)", readdraw);
950 try
951 {
952 if (readdraw == EGL_READ)
953 {
954 EGLSurface read = egl::getCurrentReadSurface();
955 return egl::success(read);
956 }
957 else if (readdraw == EGL_DRAW)
958 {
959 EGLSurface draw = egl::getCurrentDrawSurface();
960 return egl::success(draw);
961 }
962 else
963 {
964 return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
965 }
966 }
967 catch(std::bad_alloc&)
968 {
969 return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
970 }
971 }
973 EGLDisplay __stdcall eglGetCurrentDisplay(void)
974 {
975 EVENT("()");
977 try
978 {
979 EGLDisplay dpy = egl::getCurrentDisplay();
981 return egl::success(dpy);
982 }
983 catch(std::bad_alloc&)
984 {
985 return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
986 }
987 }
989 EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
990 {
991 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
992 dpy, ctx, attribute, value);
994 try
995 {
996 egl::Display *display = static_cast<egl::Display*>(dpy);
997 gl::Context *context = static_cast<gl::Context*>(ctx);
999 if (!validateContext(display, context))
1000 {
1001 return EGL_FALSE;
1002 }
1004 UNIMPLEMENTED(); // FIXME
1006 return egl::success(0);
1007 }
1008 catch(std::bad_alloc&)
1009 {
1010 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1011 }
1012 }
1014 EGLBoolean __stdcall eglWaitGL(void)
1015 {
1016 EVENT("()");
1018 try
1019 {
1020 UNIMPLEMENTED(); // FIXME
1022 return egl::success(0);
1023 }
1024 catch(std::bad_alloc&)
1025 {
1026 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1027 }
1028 }
1030 EGLBoolean __stdcall eglWaitNative(EGLint engine)
1031 {
1032 EVENT("(EGLint engine = %d)", engine);
1034 try
1035 {
1036 UNIMPLEMENTED(); // FIXME
1038 return egl::success(0);
1039 }
1040 catch(std::bad_alloc&)
1041 {
1042 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1043 }
1044 }
1046 EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
1047 {
1048 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
1050 try
1051 {
1052 egl::Display *display = static_cast<egl::Display*>(dpy);
1053 egl::Surface *eglSurface = (egl::Surface*)surface;
1055 if (!validateSurface(display, eglSurface))
1056 {
1057 return EGL_FALSE;
1058 }
1060 if (display->getRenderer()->isDeviceLost())
1061 {
1062 return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
1063 }
1065 if (surface == EGL_NO_SURFACE)
1066 {
1067 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
1068 }
1070 if (eglSurface->swap())
1071 {
1072 return egl::success(EGL_TRUE);
1073 }
1074 }
1075 catch(std::bad_alloc&)
1076 {
1077 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1078 }
1080 return EGL_FALSE;
1081 }
1083 EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
1084 {
1085 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
1087 try
1088 {
1089 egl::Display *display = static_cast<egl::Display*>(dpy);
1090 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
1092 if (!validateSurface(display, eglSurface))
1093 {
1094 return EGL_FALSE;
1095 }
1097 if (display->getRenderer()->isDeviceLost())
1098 {
1099 return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
1100 }
1102 UNIMPLEMENTED(); // FIXME
1104 return egl::success(0);
1105 }
1106 catch(std::bad_alloc&)
1107 {
1108 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1109 }
1110 }
1112 EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
1113 {
1114 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
1116 try
1117 {
1118 if (x < 0 || y < 0 || width < 0 || height < 0)
1119 {
1120 return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
1121 }
1123 egl::Display *display = static_cast<egl::Display*>(dpy);
1124 egl::Surface *eglSurface = static_cast<egl::Surface*>(surface);
1126 if (!validateSurface(display, eglSurface))
1127 {
1128 return EGL_FALSE;
1129 }
1131 if (display->getRenderer()->isDeviceLost())
1132 {
1133 return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
1134 }
1136 if (surface == EGL_NO_SURFACE)
1137 {
1138 return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
1139 }
1141 if (eglSurface->postSubBuffer(x, y, width, height))
1142 {
1143 return egl::success(EGL_TRUE);
1144 }
1145 }
1146 catch(std::bad_alloc&)
1147 {
1148 return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
1149 }
1151 return EGL_FALSE;
1152 }
1154 __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname)
1155 {
1156 EVENT("(const char *procname = \"%s\")", procname);
1158 try
1159 {
1160 struct Extension
1161 {
1162 const char *name;
1163 __eglMustCastToProperFunctionPointerType address;
1164 };
1166 static const Extension eglExtensions[] =
1167 {
1168 {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE},
1169 {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV},
1170 {"", NULL},
1171 };
1173 for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++)
1174 {
1175 if (strcmp(procname, eglExtensions[ext].name) == 0)
1176 {
1177 return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address;
1178 }
1179 }
1181 return glGetProcAddress(procname);
1182 }
1183 catch(std::bad_alloc&)
1184 {
1185 return egl::error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
1186 }
1187 }
1188 }