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