| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  context_egl_uwp.cpp                                                   */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*                         This file is part of:                          */ | 
					
						
							|  |  |  | /*                             GODOT ENGINE                               */ | 
					
						
							|  |  |  | /*                        https://godotengine.org                         */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ | 
					
						
							|  |  |  | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining  */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the        */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including    */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,    */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to     */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to  */ | 
					
						
							|  |  |  | /* the following conditions:                                              */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be         */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.        */ | 
					
						
							|  |  |  | /*                                                                        */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | #include "context_egl_uwp.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 14:51:32 +02:00
										 |  |  | #include <EGL/eglext.h>
 | 
					
						
							| 
									
										
										
										
											2014-12-20 15:30:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-21 22:47:52 -03:00
										 |  |  | using Platform::Exception; | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | void ContextEGL_UWP::release_current() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext); | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | void ContextEGL_UWP::make_current() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | int ContextEGL_UWP::get_window_width() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	return width; | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | int ContextEGL_UWP::get_window_height() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	return height; | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | void ContextEGL_UWP::reset() { | 
					
						
							| 
									
										
										
										
											2014-12-20 15:30:06 -03:00
										 |  |  | 	cleanup(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window = CoreWindow::GetForCurrentThread(); | 
					
						
							|  |  |  | 	initialize(); | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-20 15:30:06 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | void ContextEGL_UWP::swap_buffers() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE) { | 
					
						
							|  |  |  | 		cleanup(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		window = CoreWindow::GetForCurrentThread(); | 
					
						
							|  |  |  | 		initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// tell rasterizer to reload textures and stuff?
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | Error ContextEGL_UWP::initialize() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	EGLint configAttribList[] = { | 
					
						
							|  |  |  | 		EGL_RED_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_GREEN_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_BLUE_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_ALPHA_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_DEPTH_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_STENCIL_SIZE, 8, | 
					
						
							|  |  |  | 		EGL_SAMPLE_BUFFERS, 0, | 
					
						
							|  |  |  | 		EGL_NONE | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EGLint surfaceAttribList[] = { | 
					
						
							|  |  |  | 		EGL_NONE, EGL_NONE | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EGLint numConfigs = 0; | 
					
						
							|  |  |  | 	EGLint majorVersion = 1; | 
					
						
							| 
									
										
										
										
											2018-07-12 16:21:35 -03:00
										 |  |  | 	EGLint minorVersion; | 
					
						
							|  |  |  | 	if (driver == GLES_2_0) { | 
					
						
							|  |  |  | 		minorVersion = 0; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		minorVersion = 5; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	EGLDisplay display = EGL_NO_DISPLAY; | 
					
						
							|  |  |  | 	EGLContext context = EGL_NO_CONTEXT; | 
					
						
							|  |  |  | 	EGLSurface surface = EGL_NO_SURFACE; | 
					
						
							|  |  |  | 	EGLConfig config = nullptr; | 
					
						
							| 
									
										
										
										
											2018-07-12 16:21:35 -03:00
										 |  |  | 	EGLint contextAttribs[3]; | 
					
						
							|  |  |  | 	if (driver == GLES_2_0) { | 
					
						
							|  |  |  | 		contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION; | 
					
						
							|  |  |  | 		contextAttribs[1] = 2; | 
					
						
							|  |  |  | 		contextAttribs[2] = EGL_NONE; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION; | 
					
						
							|  |  |  | 		contextAttribs[1] = 3; | 
					
						
							|  |  |  | 		contextAttribs[2] = EGL_NONE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	try { | 
					
						
							| 
									
										
										
										
											2017-11-09 23:36:08 +01:00
										 |  |  | 		const EGLint displayAttributes[] = { | 
					
						
							|  |  |  | 			/*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
 | 
					
						
							|  |  |  | 			EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, | 
					
						
							|  |  |  | 			EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, | 
					
						
							|  |  |  | 			EGL_NONE,*/ | 
					
						
							|  |  |  | 			// These are the default display attributes, used to request ANGLE's D3D11 renderer.
 | 
					
						
							|  |  |  | 			// eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
 | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | 			EGL_PLATFORM_ANGLE_TYPE_ANGLE, | 
					
						
							|  |  |  | 			EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, | 
					
						
							| 
									
										
										
										
											2017-11-09 23:36:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
 | 
					
						
							|  |  |  | 			// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
 | 
					
						
							| 
									
										
										
										
											2018-07-12 16:21:35 -03:00
										 |  |  | 			EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, | 
					
						
							|  |  |  | 			EGL_TRUE, | 
					
						
							| 
									
										
										
										
											2017-11-09 23:36:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
 | 
					
						
							|  |  |  | 			// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
 | 
					
						
							|  |  |  | 			// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
 | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | 			EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, | 
					
						
							|  |  |  | 			EGL_TRUE, | 
					
						
							| 
									
										
										
										
											2017-11-09 23:36:08 +01:00
										 |  |  | 			EGL_NONE, | 
					
						
							|  |  |  | 		}; | 
					
						
							| 
									
										
										
										
											2014-12-20 15:30:06 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!eglGetPlatformDisplayEXT) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to get function eglGetPlatformDisplayEXT"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 		if (display == EGL_NO_DISPLAY) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (eglInitialize(display, &majorVersion, &minorVersion) == EGL_FALSE) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		if (eglGetConfigs(display, nullptr, 0, &numConfigs) == EGL_FALSE) { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) == EGL_FALSE) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig count"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable *>(window), surfaceAttribList); | 
					
						
							|  |  |  | 		if (surface == EGL_NO_SURFACE) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to create EGL fullscreen surface"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); | 
					
						
							|  |  |  | 		if (context == EGL_NO_CONTEXT) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to create EGL context"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { | 
					
						
							|  |  |  | 			throw Exception::CreateException(E_FAIL, L"Failed to make fullscreen EGLSurface current"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} catch (...) { | 
					
						
							|  |  |  | 		return FAILED; | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	mEglDisplay = display; | 
					
						
							|  |  |  | 	mEglSurface = surface; | 
					
						
							|  |  |  | 	mEglContext = context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	eglQuerySurface(display, surface, EGL_WIDTH, &width); | 
					
						
							|  |  |  | 	eglQuerySurface(display, surface, EGL_HEIGHT, &height); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | void ContextEGL_UWP::cleanup() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) { | 
					
						
							|  |  |  | 		eglDestroySurface(mEglDisplay, mEglSurface); | 
					
						
							|  |  |  | 		mEglSurface = EGL_NO_SURFACE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) { | 
					
						
							|  |  |  | 		eglDestroyContext(mEglDisplay, mEglContext); | 
					
						
							|  |  |  | 		mEglContext = EGL_NO_CONTEXT; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mEglDisplay != EGL_NO_DISPLAY) { | 
					
						
							|  |  |  | 		eglTerminate(mEglDisplay); | 
					
						
							|  |  |  | 		mEglDisplay = EGL_NO_DISPLAY; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | ContextEGL_UWP::ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver) : | 
					
						
							| 
									
										
										
										
											2017-12-06 21:36:34 +01:00
										 |  |  | 		mEglDisplay(EGL_NO_DISPLAY), | 
					
						
							|  |  |  | 		mEglContext(EGL_NO_CONTEXT), | 
					
						
							| 
									
										
										
										
											2018-07-12 16:21:35 -03:00
										 |  |  | 		mEglSurface(EGL_NO_SURFACE), | 
					
						
							|  |  |  | 		driver(p_driver), | 
					
						
							| 
									
										
										
										
											2020-11-24 10:12:55 +01:00
										 |  |  | 		window(p_window), | 
					
						
							|  |  |  | 		vsync(false) {} | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-12 15:43:54 +01:00
										 |  |  | ContextEGL_UWP::~ContextEGL_UWP() { | 
					
						
							| 
									
										
										
										
											2014-10-03 00:10:51 -03:00
										 |  |  | 	cleanup(); | 
					
						
							| 
									
										
										
										
											2022-02-16 13:56:32 +01:00
										 |  |  | } |