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 18bool 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 33bool 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 48bool 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 63bool 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 78extern "C" 79{ 80EGLint __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 94EGLDisplay __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 121EGLBoolean __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 153EGLBoolean __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 178const 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 213EGLBoolean __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 250EGLBoolean __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 289EGLBoolean __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 318EGLSurface __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 385EGLSurface __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 411EGLSurface __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 437EGLBoolean __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 467EGLBoolean __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 552EGLBoolean __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 581EGLenum __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 599EGLBoolean __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 617EGLBoolean __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 635EGLSurface __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 662EGLBoolean __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 688EGLBoolean __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 713EGLBoolean __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 738EGLBoolean __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 770EGLContext __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 818EGLBoolean __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 848EGLBoolean __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 896EGLContext __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 914EGLSurface __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 943EGLDisplay __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 961EGLBoolean __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 987EGLBoolean __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 1005EGLBoolean __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 1023EGLBoolean __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 1056EGLBoolean __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 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