1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libEGL/libEGL.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1188 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +// libEGL.cpp: Implements the exported EGL functions. 1.11 + 1.12 +#include <exception> 1.13 + 1.14 +#include "common/debug.h" 1.15 +#include "common/version.h" 1.16 +#include "libGLESv2/Context.h" 1.17 +#include "libGLESv2/Texture.h" 1.18 +#include "libGLESv2/main.h" 1.19 +#include "libGLESv2/renderer/SwapChain.h" 1.20 + 1.21 +#include "libEGL/main.h" 1.22 +#include "libEGL/Display.h" 1.23 +#include "libEGL/Surface.h" 1.24 + 1.25 +bool validateDisplay(egl::Display *display) 1.26 +{ 1.27 + if (display == EGL_NO_DISPLAY) 1.28 + { 1.29 + return egl::error(EGL_BAD_DISPLAY, false); 1.30 + } 1.31 + 1.32 + if (!display->isInitialized()) 1.33 + { 1.34 + return egl::error(EGL_NOT_INITIALIZED, false); 1.35 + } 1.36 + 1.37 + return true; 1.38 +} 1.39 + 1.40 +bool validateConfig(egl::Display *display, EGLConfig config) 1.41 +{ 1.42 + if (!validateDisplay(display)) 1.43 + { 1.44 + return false; 1.45 + } 1.46 + 1.47 + if (!display->isValidConfig(config)) 1.48 + { 1.49 + return egl::error(EGL_BAD_CONFIG, false); 1.50 + } 1.51 + 1.52 + return true; 1.53 +} 1.54 + 1.55 +bool validateContext(egl::Display *display, gl::Context *context) 1.56 +{ 1.57 + if (!validateDisplay(display)) 1.58 + { 1.59 + return false; 1.60 + } 1.61 + 1.62 + if (!display->isValidContext(context)) 1.63 + { 1.64 + return egl::error(EGL_BAD_CONTEXT, false); 1.65 + } 1.66 + 1.67 + return true; 1.68 +} 1.69 + 1.70 +bool validateSurface(egl::Display *display, egl::Surface *surface) 1.71 +{ 1.72 + if (!validateDisplay(display)) 1.73 + { 1.74 + return false; 1.75 + } 1.76 + 1.77 + if (!display->isValidSurface(surface)) 1.78 + { 1.79 + return egl::error(EGL_BAD_SURFACE, false); 1.80 + } 1.81 + 1.82 + return true; 1.83 +} 1.84 + 1.85 +extern "C" 1.86 +{ 1.87 +EGLint __stdcall eglGetError(void) 1.88 +{ 1.89 + EVENT("()"); 1.90 + 1.91 + EGLint error = egl::getCurrentError(); 1.92 + 1.93 + if (error != EGL_SUCCESS) 1.94 + { 1.95 + egl::setCurrentError(EGL_SUCCESS); 1.96 + } 1.97 + 1.98 + return error; 1.99 +} 1.100 + 1.101 +EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id) 1.102 +{ 1.103 + EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); 1.104 + 1.105 + try 1.106 + { 1.107 + return egl::Display::getDisplay(display_id); 1.108 + } 1.109 + catch(std::bad_alloc&) 1.110 + { 1.111 + return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); 1.112 + } 1.113 +} 1.114 + 1.115 +EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 1.116 +{ 1.117 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", 1.118 + dpy, major, minor); 1.119 + 1.120 + try 1.121 + { 1.122 + if (dpy == EGL_NO_DISPLAY) 1.123 + { 1.124 + return egl::error(EGL_BAD_DISPLAY, EGL_FALSE); 1.125 + } 1.126 + 1.127 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.128 + 1.129 + if (!display->initialize()) 1.130 + { 1.131 + return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE); 1.132 + } 1.133 + 1.134 + if (major) *major = 1; 1.135 + if (minor) *minor = 4; 1.136 + 1.137 + return egl::success(EGL_TRUE); 1.138 + } 1.139 + catch(std::bad_alloc&) 1.140 + { 1.141 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.142 + } 1.143 +} 1.144 + 1.145 +EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) 1.146 +{ 1.147 + EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); 1.148 + 1.149 + try 1.150 + { 1.151 + if (dpy == EGL_NO_DISPLAY) 1.152 + { 1.153 + return egl::error(EGL_BAD_DISPLAY, EGL_FALSE); 1.154 + } 1.155 + 1.156 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.157 + 1.158 + display->terminate(); 1.159 + 1.160 + return egl::success(EGL_TRUE); 1.161 + } 1.162 + catch(std::bad_alloc&) 1.163 + { 1.164 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.165 + } 1.166 +} 1.167 + 1.168 +const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) 1.169 +{ 1.170 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); 1.171 + 1.172 + try 1.173 + { 1.174 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.175 + 1.176 + if (!validateDisplay(display)) 1.177 + { 1.178 + return NULL; 1.179 + } 1.180 + 1.181 + switch (name) 1.182 + { 1.183 + case EGL_CLIENT_APIS: 1.184 + return egl::success("OpenGL_ES"); 1.185 + case EGL_EXTENSIONS: 1.186 + return egl::success(display->getExtensionString()); 1.187 + case EGL_VENDOR: 1.188 + return egl::success(display->getVendorString()); 1.189 + case EGL_VERSION: 1.190 + return egl::success("1.4 (ANGLE " VERSION_STRING ")"); 1.191 + } 1.192 + 1.193 + return egl::error(EGL_BAD_PARAMETER, (const char*)NULL); 1.194 + } 1.195 + catch(std::bad_alloc&) 1.196 + { 1.197 + return egl::error(EGL_BAD_ALLOC, (const char*)NULL); 1.198 + } 1.199 +} 1.200 + 1.201 +EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) 1.202 +{ 1.203 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " 1.204 + "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", 1.205 + dpy, configs, config_size, num_config); 1.206 + 1.207 + try 1.208 + { 1.209 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.210 + 1.211 + if (!validateDisplay(display)) 1.212 + { 1.213 + return EGL_FALSE; 1.214 + } 1.215 + 1.216 + if (!num_config) 1.217 + { 1.218 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.219 + } 1.220 + 1.221 + const EGLint attribList[] = {EGL_NONE}; 1.222 + 1.223 + if (!display->getConfigs(configs, attribList, config_size, num_config)) 1.224 + { 1.225 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1.226 + } 1.227 + 1.228 + return egl::success(EGL_TRUE); 1.229 + } 1.230 + catch(std::bad_alloc&) 1.231 + { 1.232 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.233 + } 1.234 +} 1.235 + 1.236 +EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) 1.237 +{ 1.238 + EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " 1.239 + "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", 1.240 + dpy, attrib_list, configs, config_size, num_config); 1.241 + 1.242 + try 1.243 + { 1.244 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.245 + 1.246 + if (!validateDisplay(display)) 1.247 + { 1.248 + return EGL_FALSE; 1.249 + } 1.250 + 1.251 + if (!num_config) 1.252 + { 1.253 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.254 + } 1.255 + 1.256 + const EGLint attribList[] = {EGL_NONE}; 1.257 + 1.258 + if (!attrib_list) 1.259 + { 1.260 + attrib_list = attribList; 1.261 + } 1.262 + 1.263 + display->getConfigs(configs, attrib_list, config_size, num_config); 1.264 + 1.265 + return egl::success(EGL_TRUE); 1.266 + } 1.267 + catch(std::bad_alloc&) 1.268 + { 1.269 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.270 + } 1.271 +} 1.272 + 1.273 +EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) 1.274 +{ 1.275 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", 1.276 + dpy, config, attribute, value); 1.277 + 1.278 + try 1.279 + { 1.280 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.281 + 1.282 + if (!validateConfig(display, config)) 1.283 + { 1.284 + return EGL_FALSE; 1.285 + } 1.286 + 1.287 + if (!display->getConfigAttrib(config, attribute, value)) 1.288 + { 1.289 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1.290 + } 1.291 + 1.292 + return egl::success(EGL_TRUE); 1.293 + } 1.294 + catch(std::bad_alloc&) 1.295 + { 1.296 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.297 + } 1.298 +} 1.299 + 1.300 +EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) 1.301 +{ 1.302 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " 1.303 + "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); 1.304 + 1.305 + try 1.306 + { 1.307 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.308 + 1.309 + if (!validateConfig(display, config)) 1.310 + { 1.311 + return EGL_NO_SURFACE; 1.312 + } 1.313 + 1.314 + HWND window = (HWND)win; 1.315 + 1.316 + if (!IsWindow(window)) 1.317 + { 1.318 + return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 1.319 + } 1.320 + 1.321 + return display->createWindowSurface(window, config, attrib_list); 1.322 + } 1.323 + catch(std::bad_alloc&) 1.324 + { 1.325 + return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1.326 + } 1.327 +} 1.328 + 1.329 +EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) 1.330 +{ 1.331 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", 1.332 + dpy, config, attrib_list); 1.333 + 1.334 + try 1.335 + { 1.336 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.337 + 1.338 + if (!validateConfig(display, config)) 1.339 + { 1.340 + return EGL_NO_SURFACE; 1.341 + } 1.342 + 1.343 + return display->createOffscreenSurface(config, NULL, attrib_list); 1.344 + } 1.345 + catch(std::bad_alloc&) 1.346 + { 1.347 + return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1.348 + } 1.349 +} 1.350 + 1.351 +EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) 1.352 +{ 1.353 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " 1.354 + "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); 1.355 + 1.356 + try 1.357 + { 1.358 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.359 + 1.360 + if (!validateConfig(display, config)) 1.361 + { 1.362 + return EGL_NO_SURFACE; 1.363 + } 1.364 + 1.365 + UNIMPLEMENTED(); // FIXME 1.366 + 1.367 + return egl::success(EGL_NO_SURFACE); 1.368 + } 1.369 + catch(std::bad_alloc&) 1.370 + { 1.371 + return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1.372 + } 1.373 +} 1.374 + 1.375 +EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) 1.376 +{ 1.377 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); 1.378 + 1.379 + try 1.380 + { 1.381 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.382 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.383 + 1.384 + if (!validateSurface(display, eglSurface)) 1.385 + { 1.386 + return EGL_FALSE; 1.387 + } 1.388 + 1.389 + if (surface == EGL_NO_SURFACE) 1.390 + { 1.391 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.392 + } 1.393 + 1.394 + display->destroySurface((egl::Surface*)surface); 1.395 + 1.396 + return egl::success(EGL_TRUE); 1.397 + } 1.398 + catch(std::bad_alloc&) 1.399 + { 1.400 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.401 + } 1.402 +} 1.403 + 1.404 +EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) 1.405 +{ 1.406 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", 1.407 + dpy, surface, attribute, value); 1.408 + 1.409 + try 1.410 + { 1.411 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.412 + egl::Surface *eglSurface = (egl::Surface*)surface; 1.413 + 1.414 + if (!validateSurface(display, eglSurface)) 1.415 + { 1.416 + return EGL_FALSE; 1.417 + } 1.418 + 1.419 + if (surface == EGL_NO_SURFACE) 1.420 + { 1.421 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.422 + } 1.423 + 1.424 + switch (attribute) 1.425 + { 1.426 + case EGL_VG_ALPHA_FORMAT: 1.427 + UNIMPLEMENTED(); // FIXME 1.428 + break; 1.429 + case EGL_VG_COLORSPACE: 1.430 + UNIMPLEMENTED(); // FIXME 1.431 + break; 1.432 + case EGL_CONFIG_ID: 1.433 + UNIMPLEMENTED(); // FIXME 1.434 + break; 1.435 + case EGL_HEIGHT: 1.436 + *value = eglSurface->getHeight(); 1.437 + break; 1.438 + case EGL_HORIZONTAL_RESOLUTION: 1.439 + UNIMPLEMENTED(); // FIXME 1.440 + break; 1.441 + case EGL_LARGEST_PBUFFER: 1.442 + UNIMPLEMENTED(); // FIXME 1.443 + break; 1.444 + case EGL_MIPMAP_TEXTURE: 1.445 + UNIMPLEMENTED(); // FIXME 1.446 + break; 1.447 + case EGL_MIPMAP_LEVEL: 1.448 + UNIMPLEMENTED(); // FIXME 1.449 + break; 1.450 + case EGL_MULTISAMPLE_RESOLVE: 1.451 + UNIMPLEMENTED(); // FIXME 1.452 + break; 1.453 + case EGL_PIXEL_ASPECT_RATIO: 1.454 + UNIMPLEMENTED(); // FIXME 1.455 + break; 1.456 + case EGL_RENDER_BUFFER: 1.457 + UNIMPLEMENTED(); // FIXME 1.458 + break; 1.459 + case EGL_SWAP_BEHAVIOR: 1.460 + UNIMPLEMENTED(); // FIXME 1.461 + break; 1.462 + case EGL_TEXTURE_FORMAT: 1.463 + UNIMPLEMENTED(); // FIXME 1.464 + break; 1.465 + case EGL_TEXTURE_TARGET: 1.466 + UNIMPLEMENTED(); // FIXME 1.467 + break; 1.468 + case EGL_VERTICAL_RESOLUTION: 1.469 + UNIMPLEMENTED(); // FIXME 1.470 + break; 1.471 + case EGL_WIDTH: 1.472 + *value = eglSurface->getWidth(); 1.473 + break; 1.474 + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: 1.475 + *value = eglSurface->isPostSubBufferSupported(); 1.476 + break; 1.477 + default: 1.478 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1.479 + } 1.480 + 1.481 + return egl::success(EGL_TRUE); 1.482 + } 1.483 + catch(std::bad_alloc&) 1.484 + { 1.485 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.486 + } 1.487 +} 1.488 + 1.489 +EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value) 1.490 +{ 1.491 + TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", 1.492 + dpy, surface, attribute, value); 1.493 + 1.494 + try 1.495 + { 1.496 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.497 + egl::Surface *eglSurface = (egl::Surface*)surface; 1.498 + 1.499 + if (!validateSurface(display, eglSurface)) 1.500 + { 1.501 + return EGL_FALSE; 1.502 + } 1.503 + 1.504 + if (surface == EGL_NO_SURFACE) 1.505 + { 1.506 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.507 + } 1.508 + 1.509 + switch (attribute) 1.510 + { 1.511 + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: 1.512 + { 1.513 + rx::SwapChain *swapchain = eglSurface->getSwapChain(); 1.514 + *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL); 1.515 + } 1.516 + break; 1.517 + default: 1.518 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1.519 + } 1.520 + 1.521 + return egl::success(EGL_TRUE); 1.522 + } 1.523 + catch(std::bad_alloc&) 1.524 + { 1.525 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.526 + } 1.527 +} 1.528 + 1.529 +EGLBoolean __stdcall eglBindAPI(EGLenum api) 1.530 +{ 1.531 + EVENT("(EGLenum api = 0x%X)", api); 1.532 + 1.533 + try 1.534 + { 1.535 + switch (api) 1.536 + { 1.537 + case EGL_OPENGL_API: 1.538 + case EGL_OPENVG_API: 1.539 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation 1.540 + case EGL_OPENGL_ES_API: 1.541 + break; 1.542 + default: 1.543 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.544 + } 1.545 + 1.546 + egl::setCurrentAPI(api); 1.547 + 1.548 + return egl::success(EGL_TRUE); 1.549 + } 1.550 + catch(std::bad_alloc&) 1.551 + { 1.552 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.553 + } 1.554 +} 1.555 + 1.556 +EGLenum __stdcall eglQueryAPI(void) 1.557 +{ 1.558 + EVENT("()"); 1.559 + 1.560 + try 1.561 + { 1.562 + EGLenum API = egl::getCurrentAPI(); 1.563 + 1.564 + return egl::success(API); 1.565 + } 1.566 + catch(std::bad_alloc&) 1.567 + { 1.568 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.569 + } 1.570 +} 1.571 + 1.572 +EGLBoolean __stdcall eglWaitClient(void) 1.573 +{ 1.574 + EVENT("()"); 1.575 + 1.576 + try 1.577 + { 1.578 + UNIMPLEMENTED(); // FIXME 1.579 + 1.580 + return egl::success(0); 1.581 + } 1.582 + catch(std::bad_alloc&) 1.583 + { 1.584 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.585 + } 1.586 +} 1.587 + 1.588 +EGLBoolean __stdcall eglReleaseThread(void) 1.589 +{ 1.590 + EVENT("()"); 1.591 + 1.592 + try 1.593 + { 1.594 + eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); 1.595 + 1.596 + return egl::success(EGL_TRUE); 1.597 + } 1.598 + catch(std::bad_alloc&) 1.599 + { 1.600 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.601 + } 1.602 +} 1.603 + 1.604 +EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) 1.605 +{ 1.606 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " 1.607 + "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", 1.608 + dpy, buftype, buffer, config, attrib_list); 1.609 + 1.610 + try 1.611 + { 1.612 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.613 + 1.614 + if (!validateConfig(display, config)) 1.615 + { 1.616 + return EGL_NO_SURFACE; 1.617 + } 1.618 + 1.619 + if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) 1.620 + { 1.621 + return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 1.622 + } 1.623 + 1.624 + return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list); 1.625 + } 1.626 + catch(std::bad_alloc&) 1.627 + { 1.628 + return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1.629 + } 1.630 +} 1.631 + 1.632 +EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) 1.633 +{ 1.634 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", 1.635 + dpy, surface, attribute, value); 1.636 + 1.637 + try 1.638 + { 1.639 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.640 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.641 + 1.642 + if (!validateSurface(display, eglSurface)) 1.643 + { 1.644 + return EGL_FALSE; 1.645 + } 1.646 + 1.647 + UNIMPLEMENTED(); // FIXME 1.648 + 1.649 + return egl::success(EGL_TRUE); 1.650 + } 1.651 + catch(std::bad_alloc&) 1.652 + { 1.653 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.654 + } 1.655 +} 1.656 + 1.657 +EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1.658 +{ 1.659 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); 1.660 + 1.661 + try 1.662 + { 1.663 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.664 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.665 + 1.666 + if (!validateSurface(display, eglSurface)) 1.667 + { 1.668 + return EGL_FALSE; 1.669 + } 1.670 + 1.671 + if (buffer != EGL_BACK_BUFFER) 1.672 + { 1.673 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.674 + } 1.675 + 1.676 + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) 1.677 + { 1.678 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.679 + } 1.680 + 1.681 + if (eglSurface->getBoundTexture()) 1.682 + { 1.683 + return egl::error(EGL_BAD_ACCESS, EGL_FALSE); 1.684 + } 1.685 + 1.686 + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) 1.687 + { 1.688 + return egl::error(EGL_BAD_MATCH, EGL_FALSE); 1.689 + } 1.690 + 1.691 + if (!glBindTexImage(eglSurface)) 1.692 + { 1.693 + return egl::error(EGL_BAD_MATCH, EGL_FALSE); 1.694 + } 1.695 + 1.696 + return egl::success(EGL_TRUE); 1.697 + } 1.698 + catch(std::bad_alloc&) 1.699 + { 1.700 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.701 + } 1.702 +} 1.703 + 1.704 +EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1.705 +{ 1.706 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); 1.707 + 1.708 + try 1.709 + { 1.710 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.711 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.712 + 1.713 + if (!validateSurface(display, eglSurface)) 1.714 + { 1.715 + return EGL_FALSE; 1.716 + } 1.717 + 1.718 + if (buffer != EGL_BACK_BUFFER) 1.719 + { 1.720 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.721 + } 1.722 + 1.723 + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) 1.724 + { 1.725 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.726 + } 1.727 + 1.728 + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) 1.729 + { 1.730 + return egl::error(EGL_BAD_MATCH, EGL_FALSE); 1.731 + } 1.732 + 1.733 + gl::Texture2D *texture = eglSurface->getBoundTexture(); 1.734 + 1.735 + if (texture) 1.736 + { 1.737 + texture->releaseTexImage(); 1.738 + } 1.739 + 1.740 + return egl::success(EGL_TRUE); 1.741 + } 1.742 + catch(std::bad_alloc&) 1.743 + { 1.744 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.745 + } 1.746 +} 1.747 + 1.748 +EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) 1.749 +{ 1.750 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); 1.751 + 1.752 + try 1.753 + { 1.754 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.755 + 1.756 + if (!validateDisplay(display)) 1.757 + { 1.758 + return EGL_FALSE; 1.759 + } 1.760 + 1.761 + egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface()); 1.762 + 1.763 + if (draw_surface == NULL) 1.764 + { 1.765 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.766 + } 1.767 + 1.768 + draw_surface->setSwapInterval(interval); 1.769 + 1.770 + return egl::success(EGL_TRUE); 1.771 + } 1.772 + catch(std::bad_alloc&) 1.773 + { 1.774 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.775 + } 1.776 +} 1.777 + 1.778 +EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) 1.779 +{ 1.780 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " 1.781 + "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); 1.782 + 1.783 + try 1.784 + { 1.785 + // Get the requested client version (default is 1) and check it is two. 1.786 + EGLint client_version = 1; 1.787 + bool reset_notification = false; 1.788 + bool robust_access = false; 1.789 + 1.790 + if (attrib_list) 1.791 + { 1.792 + for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2) 1.793 + { 1.794 + switch (attribute[0]) 1.795 + { 1.796 + case EGL_CONTEXT_CLIENT_VERSION: 1.797 + client_version = attribute[1]; 1.798 + break; 1.799 + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: 1.800 + if (attribute[1] == EGL_TRUE) 1.801 + { 1.802 + return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented 1.803 + // robust_access = true; 1.804 + } 1.805 + else if (attribute[1] != EGL_FALSE) 1.806 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); 1.807 + break; 1.808 + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: 1.809 + if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) 1.810 + reset_notification = true; 1.811 + else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) 1.812 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); 1.813 + break; 1.814 + default: 1.815 + return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); 1.816 + } 1.817 + } 1.818 + } 1.819 + 1.820 + if (client_version != 2) 1.821 + { 1.822 + return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1.823 + } 1.824 + 1.825 + if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification) 1.826 + { 1.827 + return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT); 1.828 + } 1.829 + 1.830 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.831 + 1.832 + if (!validateConfig(display, config)) 1.833 + { 1.834 + return EGL_NO_CONTEXT; 1.835 + } 1.836 + 1.837 + EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access); 1.838 + 1.839 + if (context) 1.840 + return egl::success(context); 1.841 + else 1.842 + return egl::error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); 1.843 + } 1.844 + catch(std::bad_alloc&) 1.845 + { 1.846 + return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); 1.847 + } 1.848 +} 1.849 + 1.850 +EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 1.851 +{ 1.852 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); 1.853 + 1.854 + try 1.855 + { 1.856 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.857 + gl::Context *context = static_cast<gl::Context*>(ctx); 1.858 + 1.859 + if (!validateContext(display, context)) 1.860 + { 1.861 + return EGL_FALSE; 1.862 + } 1.863 + 1.864 + if (ctx == EGL_NO_CONTEXT) 1.865 + { 1.866 + return egl::error(EGL_BAD_CONTEXT, EGL_FALSE); 1.867 + } 1.868 + 1.869 + display->destroyContext(context); 1.870 + 1.871 + return egl::success(EGL_TRUE); 1.872 + } 1.873 + catch(std::bad_alloc&) 1.874 + { 1.875 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.876 + } 1.877 +} 1.878 + 1.879 +EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) 1.880 +{ 1.881 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", 1.882 + dpy, draw, read, ctx); 1.883 + 1.884 + try 1.885 + { 1.886 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.887 + gl::Context *context = static_cast<gl::Context*>(ctx); 1.888 + 1.889 + if (ctx != EGL_NO_CONTEXT && !validateContext(display, context)) 1.890 + { 1.891 + return EGL_FALSE; 1.892 + } 1.893 + 1.894 + if (dpy != EGL_NO_DISPLAY) 1.895 + { 1.896 + rx::Renderer *renderer = display->getRenderer(); 1.897 + if (renderer->testDeviceLost(true)) 1.898 + { 1.899 + return EGL_FALSE; 1.900 + } 1.901 + 1.902 + if (renderer->isDeviceLost()) 1.903 + { 1.904 + return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); 1.905 + } 1.906 + } 1.907 + 1.908 + if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) || 1.909 + (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read)))) 1.910 + { 1.911 + return EGL_FALSE; 1.912 + } 1.913 + 1.914 + if (draw != read) 1.915 + { 1.916 + UNIMPLEMENTED(); // FIXME 1.917 + } 1.918 + 1.919 + egl::setCurrentDisplay(dpy); 1.920 + egl::setCurrentDrawSurface(draw); 1.921 + egl::setCurrentReadSurface(read); 1.922 + 1.923 + glMakeCurrent(context, display, static_cast<egl::Surface*>(draw)); 1.924 + 1.925 + return egl::success(EGL_TRUE); 1.926 + } 1.927 + catch(std::bad_alloc&) 1.928 + { 1.929 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.930 + } 1.931 +} 1.932 + 1.933 +EGLContext __stdcall eglGetCurrentContext(void) 1.934 +{ 1.935 + EVENT("()"); 1.936 + 1.937 + try 1.938 + { 1.939 + EGLContext context = glGetCurrentContext(); 1.940 + 1.941 + return egl::success(context); 1.942 + } 1.943 + catch(std::bad_alloc&) 1.944 + { 1.945 + return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); 1.946 + } 1.947 +} 1.948 + 1.949 +EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) 1.950 +{ 1.951 + EVENT("(EGLint readdraw = %d)", readdraw); 1.952 + 1.953 + try 1.954 + { 1.955 + if (readdraw == EGL_READ) 1.956 + { 1.957 + EGLSurface read = egl::getCurrentReadSurface(); 1.958 + return egl::success(read); 1.959 + } 1.960 + else if (readdraw == EGL_DRAW) 1.961 + { 1.962 + EGLSurface draw = egl::getCurrentDrawSurface(); 1.963 + return egl::success(draw); 1.964 + } 1.965 + else 1.966 + { 1.967 + return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 1.968 + } 1.969 + } 1.970 + catch(std::bad_alloc&) 1.971 + { 1.972 + return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1.973 + } 1.974 +} 1.975 + 1.976 +EGLDisplay __stdcall eglGetCurrentDisplay(void) 1.977 +{ 1.978 + EVENT("()"); 1.979 + 1.980 + try 1.981 + { 1.982 + EGLDisplay dpy = egl::getCurrentDisplay(); 1.983 + 1.984 + return egl::success(dpy); 1.985 + } 1.986 + catch(std::bad_alloc&) 1.987 + { 1.988 + return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); 1.989 + } 1.990 +} 1.991 + 1.992 +EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) 1.993 +{ 1.994 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", 1.995 + dpy, ctx, attribute, value); 1.996 + 1.997 + try 1.998 + { 1.999 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.1000 + gl::Context *context = static_cast<gl::Context*>(ctx); 1.1001 + 1.1002 + if (!validateContext(display, context)) 1.1003 + { 1.1004 + return EGL_FALSE; 1.1005 + } 1.1006 + 1.1007 + UNIMPLEMENTED(); // FIXME 1.1008 + 1.1009 + return egl::success(0); 1.1010 + } 1.1011 + catch(std::bad_alloc&) 1.1012 + { 1.1013 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1014 + } 1.1015 +} 1.1016 + 1.1017 +EGLBoolean __stdcall eglWaitGL(void) 1.1018 +{ 1.1019 + EVENT("()"); 1.1020 + 1.1021 + try 1.1022 + { 1.1023 + UNIMPLEMENTED(); // FIXME 1.1024 + 1.1025 + return egl::success(0); 1.1026 + } 1.1027 + catch(std::bad_alloc&) 1.1028 + { 1.1029 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1030 + } 1.1031 +} 1.1032 + 1.1033 +EGLBoolean __stdcall eglWaitNative(EGLint engine) 1.1034 +{ 1.1035 + EVENT("(EGLint engine = %d)", engine); 1.1036 + 1.1037 + try 1.1038 + { 1.1039 + UNIMPLEMENTED(); // FIXME 1.1040 + 1.1041 + return egl::success(0); 1.1042 + } 1.1043 + catch(std::bad_alloc&) 1.1044 + { 1.1045 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1046 + } 1.1047 +} 1.1048 + 1.1049 +EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) 1.1050 +{ 1.1051 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); 1.1052 + 1.1053 + try 1.1054 + { 1.1055 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.1056 + egl::Surface *eglSurface = (egl::Surface*)surface; 1.1057 + 1.1058 + if (!validateSurface(display, eglSurface)) 1.1059 + { 1.1060 + return EGL_FALSE; 1.1061 + } 1.1062 + 1.1063 + if (display->getRenderer()->isDeviceLost()) 1.1064 + { 1.1065 + return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); 1.1066 + } 1.1067 + 1.1068 + if (surface == EGL_NO_SURFACE) 1.1069 + { 1.1070 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.1071 + } 1.1072 + 1.1073 + if (eglSurface->swap()) 1.1074 + { 1.1075 + return egl::success(EGL_TRUE); 1.1076 + } 1.1077 + } 1.1078 + catch(std::bad_alloc&) 1.1079 + { 1.1080 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1081 + } 1.1082 + 1.1083 + return EGL_FALSE; 1.1084 +} 1.1085 + 1.1086 +EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 1.1087 +{ 1.1088 + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); 1.1089 + 1.1090 + try 1.1091 + { 1.1092 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.1093 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.1094 + 1.1095 + if (!validateSurface(display, eglSurface)) 1.1096 + { 1.1097 + return EGL_FALSE; 1.1098 + } 1.1099 + 1.1100 + if (display->getRenderer()->isDeviceLost()) 1.1101 + { 1.1102 + return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); 1.1103 + } 1.1104 + 1.1105 + UNIMPLEMENTED(); // FIXME 1.1106 + 1.1107 + return egl::success(0); 1.1108 + } 1.1109 + catch(std::bad_alloc&) 1.1110 + { 1.1111 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1112 + } 1.1113 +} 1.1114 + 1.1115 +EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) 1.1116 +{ 1.1117 + 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); 1.1118 + 1.1119 + try 1.1120 + { 1.1121 + if (x < 0 || y < 0 || width < 0 || height < 0) 1.1122 + { 1.1123 + return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); 1.1124 + } 1.1125 + 1.1126 + egl::Display *display = static_cast<egl::Display*>(dpy); 1.1127 + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); 1.1128 + 1.1129 + if (!validateSurface(display, eglSurface)) 1.1130 + { 1.1131 + return EGL_FALSE; 1.1132 + } 1.1133 + 1.1134 + if (display->getRenderer()->isDeviceLost()) 1.1135 + { 1.1136 + return egl::error(EGL_CONTEXT_LOST, EGL_FALSE); 1.1137 + } 1.1138 + 1.1139 + if (surface == EGL_NO_SURFACE) 1.1140 + { 1.1141 + return egl::error(EGL_BAD_SURFACE, EGL_FALSE); 1.1142 + } 1.1143 + 1.1144 + if (eglSurface->postSubBuffer(x, y, width, height)) 1.1145 + { 1.1146 + return egl::success(EGL_TRUE); 1.1147 + } 1.1148 + } 1.1149 + catch(std::bad_alloc&) 1.1150 + { 1.1151 + return egl::error(EGL_BAD_ALLOC, EGL_FALSE); 1.1152 + } 1.1153 + 1.1154 + return EGL_FALSE; 1.1155 +} 1.1156 + 1.1157 +__eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname) 1.1158 +{ 1.1159 + EVENT("(const char *procname = \"%s\")", procname); 1.1160 + 1.1161 + try 1.1162 + { 1.1163 + struct Extension 1.1164 + { 1.1165 + const char *name; 1.1166 + __eglMustCastToProperFunctionPointerType address; 1.1167 + }; 1.1168 + 1.1169 + static const Extension eglExtensions[] = 1.1170 + { 1.1171 + {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE}, 1.1172 + {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV}, 1.1173 + {"", NULL}, 1.1174 + }; 1.1175 + 1.1176 + for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++) 1.1177 + { 1.1178 + if (strcmp(procname, eglExtensions[ext].name) == 0) 1.1179 + { 1.1180 + return (__eglMustCastToProperFunctionPointerType)eglExtensions[ext].address; 1.1181 + } 1.1182 + } 1.1183 + 1.1184 + return glGetProcAddress(procname); 1.1185 + } 1.1186 + catch(std::bad_alloc&) 1.1187 + { 1.1188 + return egl::error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL); 1.1189 + } 1.1190 +} 1.1191 +}