Home | History | Annotate | Download | only in libEGL
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // main.cpp: DLL entry point and management of thread-local data.
     16 
     17 #include "main.h"
     18 
     19 #include "libEGL.hpp"
     20 #include "Context.hpp"
     21 #include "Surface.hpp"
     22 
     23 #include "resource.h"
     24 #include "Common/Thread.hpp"
     25 #include "Common/SharedLibrary.hpp"
     26 #include "common/debug.h"
     27 
     28 #include <EGL/eglext.h>
     29 
     30 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
     31 
     32 #if !defined(_MSC_VER)
     33 #define CONSTRUCTOR __attribute__((constructor))
     34 #define DESTRUCTOR __attribute__((destructor))
     35 #else
     36 #define CONSTRUCTOR
     37 #define DESTRUCTOR
     38 #endif
     39 
     40 namespace egl
     41 {
     42 Current *attachThread()
     43 {
     44 	TRACE("()");
     45 
     46 	if(currentTLS == TLS_OUT_OF_INDEXES)
     47 	{
     48 		currentTLS = sw::Thread::allocateLocalStorageKey();
     49 	}
     50 
     51 	Current *current = (Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(Current));
     52 
     53 	current->error = EGL_SUCCESS;
     54 	current->API = EGL_OPENGL_ES_API;
     55 	current->context = nullptr;
     56 	current->drawSurface = nullptr;
     57 	current->readSurface = nullptr;
     58 
     59 	return current;
     60 }
     61 
     62 void detachThread()
     63 {
     64 	TRACE("()");
     65 
     66 	eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
     67 
     68 	sw::Thread::freeLocalStorage(currentTLS);
     69 }
     70 
     71 CONSTRUCTOR void attachProcess()
     72 {
     73 	TRACE("()");
     74 
     75 	#if !defined(ANGLE_DISABLE_TRACE) && defined(TRACE_OUTPUT_FILE)
     76 		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
     77 
     78 		if(debug)
     79 		{
     80 			fclose(debug);
     81 			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
     82 			fclose(debug);
     83 		}
     84 	#endif
     85 
     86 	attachThread();
     87 }
     88 
     89 DESTRUCTOR void detachProcess()
     90 {
     91 	TRACE("()");
     92 
     93 	detachThread();
     94 	sw::Thread::freeLocalStorageKey(currentTLS);
     95 }
     96 }
     97 
     98 #if defined(_WIN32)
     99 #ifdef DEBUGGER_WAIT_DIALOG
    100 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    101 {
    102 	RECT rect;
    103 
    104 	switch(uMsg)
    105 	{
    106 	case WM_INITDIALOG:
    107 		GetWindowRect(GetDesktopWindow(), &rect);
    108 		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
    109 		SetTimer(hwnd, 1, 100, NULL);
    110 		return TRUE;
    111 	case WM_COMMAND:
    112 		if(LOWORD(wParam) == IDCANCEL)
    113 		{
    114 			EndDialog(hwnd, 0);
    115 		}
    116 		break;
    117 	case WM_TIMER:
    118 		if(IsDebuggerPresent())
    119 		{
    120 			EndDialog(hwnd, 0);
    121 		}
    122 	}
    123 
    124 	return FALSE;
    125 }
    126 
    127 static void WaitForDebugger(HINSTANCE instance)
    128 {
    129 	if(!IsDebuggerPresent())
    130 	{
    131 		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
    132 		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
    133 		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
    134 	}
    135 }
    136 #endif
    137 
    138 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
    139 {
    140 	switch(reason)
    141 	{
    142 	case DLL_PROCESS_ATTACH:
    143 		#ifdef DEBUGGER_WAIT_DIALOG
    144 			WaitForDebugger(instance);
    145 		#endif
    146 		egl::attachProcess();
    147 		break;
    148 	case DLL_THREAD_ATTACH:
    149 		egl::attachThread();
    150 		break;
    151 	case DLL_THREAD_DETACH:
    152 		egl::detachThread();
    153 		break;
    154 	case DLL_PROCESS_DETACH:
    155 		egl::detachProcess();
    156 		break;
    157 	default:
    158 		break;
    159 	}
    160 
    161 	return TRUE;
    162 }
    163 #endif
    164 
    165 namespace egl
    166 {
    167 static Current *getCurrent(void)
    168 {
    169 	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
    170 
    171 	if(!current)
    172 	{
    173 		current = attachThread();
    174 	}
    175 
    176 	return current;
    177 }
    178 
    179 void setCurrentError(EGLint error)
    180 {
    181 	Current *current = getCurrent();
    182 
    183 	current->error = error;
    184 }
    185 
    186 EGLint getCurrentError()
    187 {
    188 	Current *current = getCurrent();
    189 
    190 	return current->error;
    191 }
    192 
    193 void setCurrentAPI(EGLenum API)
    194 {
    195 	Current *current = getCurrent();
    196 
    197 	current->API = API;
    198 }
    199 
    200 EGLenum getCurrentAPI()
    201 {
    202 	Current *current = getCurrent();
    203 
    204 	return current->API;
    205 }
    206 
    207 void setCurrentContext(egl::Context *ctx)
    208 {
    209 	Current *current = getCurrent();
    210 
    211 	if(ctx)
    212 	{
    213 		ctx->addRef();
    214 	}
    215 
    216 	if(current->context)
    217 	{
    218 		current->context->release();
    219 	}
    220 
    221 	current->context = ctx;
    222 }
    223 
    224 NO_SANITIZE_FUNCTION egl::Context *getCurrentContext()
    225 {
    226 	Current *current = getCurrent();
    227 
    228 	return current->context;
    229 }
    230 
    231 void setCurrentDrawSurface(egl::Surface *surface)
    232 {
    233 	Current *current = getCurrent();
    234 
    235 	if(surface)
    236 	{
    237 		surface->addRef();
    238 	}
    239 
    240 	if(current->drawSurface)
    241 	{
    242 		current->drawSurface->release();
    243 	}
    244 
    245 	current->drawSurface = surface;
    246 }
    247 
    248 egl::Surface *getCurrentDrawSurface()
    249 {
    250 	Current *current = getCurrent();
    251 
    252 	return current->drawSurface;
    253 }
    254 
    255 void setCurrentReadSurface(egl::Surface *surface)
    256 {
    257 	Current *current = getCurrent();
    258 
    259 	if(surface)
    260 	{
    261 		surface->addRef();
    262 	}
    263 
    264 	if(current->readSurface)
    265 	{
    266 		current->readSurface->release();
    267 	}
    268 
    269 	current->readSurface = surface;
    270 }
    271 
    272 egl::Surface *getCurrentReadSurface()
    273 {
    274 	Current *current = getCurrent();
    275 
    276 	return current->readSurface;
    277 }
    278 
    279 void error(EGLint errorCode)
    280 {
    281 	egl::setCurrentError(errorCode);
    282 
    283 	if(errorCode != EGL_SUCCESS)
    284 	{
    285 		switch(errorCode)
    286 		{
    287 		case EGL_NOT_INITIALIZED:     TRACE("\t! Error generated: not initialized\n");     break;
    288 		case EGL_BAD_ACCESS:          TRACE("\t! Error generated: bad access\n");          break;
    289 		case EGL_BAD_ALLOC:           TRACE("\t! Error generated: bad alloc\n");           break;
    290 		case EGL_BAD_ATTRIBUTE:       TRACE("\t! Error generated: bad attribute\n");       break;
    291 		case EGL_BAD_CONFIG:          TRACE("\t! Error generated: bad config\n");          break;
    292 		case EGL_BAD_CONTEXT:         TRACE("\t! Error generated: bad context\n");         break;
    293 		case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;
    294 		case EGL_BAD_DISPLAY:         TRACE("\t! Error generated: bad display\n");         break;
    295 		case EGL_BAD_MATCH:           TRACE("\t! Error generated: bad match\n");           break;
    296 		case EGL_BAD_NATIVE_PIXMAP:   TRACE("\t! Error generated: bad native pixmap\n");   break;
    297 		case EGL_BAD_NATIVE_WINDOW:   TRACE("\t! Error generated: bad native window\n");   break;
    298 		case EGL_BAD_PARAMETER:       TRACE("\t! Error generated: bad parameter\n");       break;
    299 		case EGL_BAD_SURFACE:         TRACE("\t! Error generated: bad surface\n");         break;
    300 		case EGL_CONTEXT_LOST:        TRACE("\t! Error generated: context lost\n");        break;
    301 		default:                      TRACE("\t! Error generated: <0x%X>\n", errorCode);   break;
    302 		}
    303 	}
    304 }
    305 }
    306 
    307 namespace egl
    308 {
    309 EGLint GetError(void);
    310 EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
    311 EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
    312 EGLBoolean Terminate(EGLDisplay dpy);
    313 const char *QueryString(EGLDisplay dpy, EGLint name);
    314 EGLBoolean GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
    315 EGLBoolean ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
    316 EGLBoolean GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
    317 EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list);
    318 EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
    319 EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
    320 EGLBoolean DestroySurface(EGLDisplay dpy, EGLSurface surface);
    321 EGLBoolean QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
    322 EGLBoolean BindAPI(EGLenum api);
    323 EGLenum QueryAPI(void);
    324 EGLBoolean WaitClient(void);
    325 EGLBoolean ReleaseThread(void);
    326 EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
    327 EGLBoolean SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
    328 EGLBoolean BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
    329 EGLBoolean ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
    330 EGLBoolean SwapInterval(EGLDisplay dpy, EGLint interval);
    331 EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
    332 EGLBoolean DestroyContext(EGLDisplay dpy, EGLContext ctx);
    333 EGLBoolean MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
    334 EGLContext GetCurrentContext(void);
    335 EGLSurface GetCurrentSurface(EGLint readdraw);
    336 EGLDisplay GetCurrentDisplay(void);
    337 EGLBoolean QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
    338 EGLBoolean WaitGL(void);
    339 EGLBoolean WaitNative(EGLint engine);
    340 EGLBoolean SwapBuffers(EGLDisplay dpy, EGLSurface surface);
    341 EGLBoolean CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
    342 EGLImageKHR CreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
    343 EGLBoolean DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image);
    344 EGLDisplay GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
    345 EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
    346 EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
    347 EGLSyncKHR CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
    348 EGLBoolean DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
    349 EGLint ClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
    350 EGLBoolean GetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
    351 __eglMustCastToProperFunctionPointerType GetProcAddress(const char *procname);
    352 }
    353 
    354 extern "C"
    355 {
    356 EGLAPI EGLint EGLAPIENTRY eglGetError(void)
    357 {
    358 	return egl::GetError();
    359 }
    360 
    361 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
    362 {
    363 	return egl::GetDisplay(display_id);
    364 }
    365 
    366 EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
    367 {
    368 	return egl::Initialize(dpy, major, minor);
    369 }
    370 
    371 EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
    372 {
    373 	return egl::Terminate(dpy);
    374 }
    375 
    376 EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
    377 {
    378 	return egl::QueryString(dpy, name);
    379 }
    380 
    381 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
    382 {
    383 	return egl::GetConfigs(dpy, configs, config_size, num_config);
    384 }
    385 
    386 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
    387 {
    388 	return egl::ChooseConfig(dpy, attrib_list, configs, config_size, num_config);
    389 }
    390 
    391 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
    392 {
    393 	return egl::GetConfigAttrib(dpy, config, attribute, value);
    394 }
    395 
    396 EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)
    397 {
    398 	return egl::CreateWindowSurface(dpy, config, window, attrib_list);
    399 }
    400 
    401 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
    402 {
    403 	return egl::CreatePbufferSurface(dpy, config, attrib_list);
    404 }
    405 
    406 EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
    407 {
    408 	return egl::CreatePixmapSurface(dpy, config, pixmap, attrib_list);
    409 }
    410 
    411 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
    412 {
    413 	return egl::DestroySurface(dpy, surface);
    414 }
    415 
    416 EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
    417 {
    418 	return egl::QuerySurface(dpy, surface, attribute, value);
    419 }
    420 
    421 EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
    422 {
    423 	return egl::BindAPI(api);
    424 }
    425 
    426 EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)
    427 {
    428 	return egl::QueryAPI();
    429 }
    430 
    431 EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)
    432 {
    433 	return egl::WaitClient();
    434 }
    435 
    436 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)
    437 {
    438 	return egl::ReleaseThread();
    439 }
    440 
    441 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
    442 {
    443 	return egl::CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
    444 }
    445 
    446 EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
    447 {
    448 	return egl::SurfaceAttrib(dpy, surface, attribute, value);
    449 }
    450 
    451 EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
    452 {
    453 	return egl::BindTexImage(dpy, surface, buffer);
    454 }
    455 
    456 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
    457 {
    458 	return egl::ReleaseTexImage(dpy, surface, buffer);
    459 }
    460 
    461 EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
    462 {
    463 	return egl::SwapInterval(dpy, interval);
    464 }
    465 
    466 EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
    467 {
    468 	return egl::CreateContext(dpy, config, share_context, attrib_list);
    469 }
    470 
    471 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
    472 {
    473 	return egl::DestroyContext(dpy, ctx);
    474 }
    475 
    476 EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
    477 {
    478 	return egl::MakeCurrent(dpy, draw, read, ctx);
    479 }
    480 
    481 EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)
    482 {
    483 	return egl::GetCurrentContext();
    484 }
    485 
    486 EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
    487 {
    488 	return egl::GetCurrentSurface(readdraw);
    489 }
    490 
    491 EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
    492 {
    493 	return egl::GetCurrentDisplay();
    494 }
    495 
    496 EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
    497 {
    498 	return egl::QueryContext(dpy, ctx, attribute, value);
    499 }
    500 
    501 EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
    502 {
    503 	return egl::WaitClient();
    504 }
    505 
    506 EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
    507 {
    508 	return egl::WaitNative(engine);
    509 }
    510 
    511 EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
    512 {
    513 	return egl::SwapBuffers(dpy, surface);
    514 }
    515 
    516 EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
    517 {
    518 	return egl::CopyBuffers(dpy, surface, target);
    519 }
    520 
    521 EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
    522 {
    523 	return egl::CreateImageKHR(dpy, ctx, target, buffer, attrib_list);
    524 }
    525 
    526 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
    527 {
    528 	return egl::DestroyImageKHR(dpy, image);
    529 }
    530 
    531 EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
    532 {
    533 	return egl::GetPlatformDisplayEXT(platform, native_display, attrib_list);
    534 }
    535 
    536 EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list)
    537 {
    538 	return egl::CreatePlatformWindowSurfaceEXT(dpy, config, native_window, attrib_list);
    539 }
    540 
    541 EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list)
    542 {
    543 	return egl::CreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);
    544 }
    545 
    546 EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
    547 {
    548 	return egl::CreateSyncKHR(dpy, type, attrib_list);
    549 }
    550 
    551 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
    552 {
    553 	return egl::DestroySyncKHR(dpy, sync);
    554 }
    555 
    556 EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
    557 {
    558 	return egl::ClientWaitSyncKHR(dpy, sync, flags, timeout);
    559 }
    560 
    561 EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
    562 {
    563 	return egl::GetSyncAttribKHR(dpy, sync, attribute, value);
    564 }
    565 
    566 EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
    567 {
    568 	return egl::GetProcAddress(procname);
    569 }
    570 }
    571 
    572 LibEGLexports::LibEGLexports()
    573 {
    574 	this->eglGetError = egl::GetError;
    575 	this->eglGetDisplay = egl::GetDisplay;
    576 	this->eglInitialize = egl::Initialize;
    577 	this->eglTerminate = egl::Terminate;
    578 	this->eglQueryString = egl::QueryString;
    579 	this->eglGetConfigs = egl::GetConfigs;
    580 	this->eglChooseConfig = egl::ChooseConfig;
    581 	this->eglGetConfigAttrib = egl::GetConfigAttrib;
    582 	this->eglCreateWindowSurface = egl::CreateWindowSurface;
    583 	this->eglCreatePbufferSurface = egl::CreatePbufferSurface;
    584 	this->eglCreatePixmapSurface = egl::CreatePixmapSurface;
    585 	this->eglDestroySurface = egl::DestroySurface;
    586 	this->eglQuerySurface = egl::QuerySurface;
    587 	this->eglBindAPI = egl::BindAPI;
    588 	this->eglQueryAPI = egl::QueryAPI;
    589 	this->eglWaitClient = egl::WaitClient;
    590 	this->eglReleaseThread = egl::ReleaseThread;
    591 	this->eglCreatePbufferFromClientBuffer = egl::CreatePbufferFromClientBuffer;
    592 	this->eglSurfaceAttrib = egl::SurfaceAttrib;
    593 	this->eglBindTexImage = egl::BindTexImage;
    594 	this->eglReleaseTexImage = egl::ReleaseTexImage;
    595 	this->eglSwapInterval = egl::SwapInterval;
    596 	this->eglCreateContext = egl::CreateContext;
    597 	this->eglDestroyContext = egl::DestroyContext;
    598 	this->eglMakeCurrent = egl::MakeCurrent;
    599 	this->eglGetCurrentContext = egl::GetCurrentContext;
    600 	this->eglGetCurrentSurface = egl::GetCurrentSurface;
    601 	this->eglGetCurrentDisplay = egl::GetCurrentDisplay;
    602 	this->eglQueryContext = egl::QueryContext;
    603 	this->eglWaitGL = egl::WaitGL;
    604 	this->eglWaitNative = egl::WaitNative;
    605 	this->eglSwapBuffers = egl::SwapBuffers;
    606 	this->eglCopyBuffers = egl::CopyBuffers;
    607 	this->eglCreateImageKHR = egl::CreateImageKHR;
    608 	this->eglDestroyImageKHR = egl::DestroyImageKHR;
    609 	this->eglGetProcAddress = egl::GetProcAddress;
    610 	this->eglCreateSyncKHR = egl::CreateSyncKHR;
    611 	this->eglDestroySyncKHR = egl::DestroySyncKHR;
    612 	this->eglClientWaitSyncKHR = egl::ClientWaitSyncKHR;
    613 	this->eglGetSyncAttribKHR = egl::GetSyncAttribKHR;
    614 
    615 	this->clientGetCurrentContext = egl::getCurrentContext;
    616 }
    617 
    618 extern "C" EGLAPI LibEGLexports *libEGL_swiftshader()
    619 {
    620 	static LibEGLexports libEGL;
    621 	return &libEGL;
    622 }
    623 
    624 LibGLES_CM libGLES_CM;
    625 LibGLESv2 libGLESv2;
    626