2019-12-05 18:22:04 +08:00
/* RetroArch - A frontend for libretro.
* Copyright ( C ) 2010 - 2014 - Hans - Kristian Arntzen
* Copyright ( C ) 2011 - 2017 - Daniel De Matteis
*
* RetroArch is free software : you can redistribute it and / or modify it under the terms
* of the GNU General Public License as published by the Free Software Found -
* ation , either version 3 of the License , or ( at your option ) any later version .
*
* RetroArch is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE . See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with RetroArch .
* If not , see < http : //www.gnu.org/licenses/>.
*/
# include <math.h>
/* UWP/ANGLE EGL context. */
/* necessary for mingw32 multimon defines: */
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K
# endif
# include <tchar.h>
# include <wchar.h>
# include <string.h>
# include <math.h>
# include <dynamic/dylib.h>
# include <string/stdstring.h>
# ifdef HAVE_CONFIG_H
# include "../../config.h"
# endif
# include "../../uwp/uwp_func.h"
# include "gfx/common/win32_common.h"
# include "../../configuration.h"
# include "../../dynamic.h"
# include "../../retroarch.h"
# include "../../verbosity.h"
# include "../../frontend/frontend_driver.h"
2020-07-20 18:22:33 +02:00
# ifdef HAVE_EGL
2019-12-05 18:22:04 +08:00
# include "../common/egl_common.h"
2020-07-20 18:22:33 +02:00
# endif
2019-12-06 15:21:54 +08:00
# ifdef HAVE_ANGLE
# include "../common/angle_common.h"
# endif
2020-07-17 16:46:00 +02:00
/* TODO/FIXME - static globals */
2020-07-17 14:53:49 +02:00
static egl_ctx_data_t uwp_egl ;
2019-12-05 18:22:04 +08:00
# ifdef HAVE_DYNAMIC
static dylib_t dll_handle = NULL ; /* Handle to libGLESv2.dll */
# endif
typedef struct gfx_ctx_cgl_data
{
2020-07-18 14:11:13 +02:00
int interval ;
2019-12-05 18:22:04 +08:00
} gfx_ctx_uwp_data_t ;
bool create_gles_context ( void * corewindow )
{
EGLint n , major , minor ;
EGLint format ;
EGLint attribs [ ] = {
EGL_RENDERABLE_TYPE , EGL_OPENGL_ES2_BIT ,
EGL_SURFACE_TYPE , EGL_WINDOW_BIT ,
EGL_BLUE_SIZE , 8 ,
EGL_GREEN_SIZE , 8 ,
EGL_RED_SIZE , 8 ,
EGL_ALPHA_SIZE , 8 ,
EGL_DEPTH_SIZE , 16 ,
EGL_NONE
} ;
EGLint context_attributes [ ] = {
EGL_CONTEXT_CLIENT_VERSION , 2 ,
EGL_NONE
} ;
2019-12-06 15:21:54 +08:00
# ifdef HAVE_ANGLE
2019-12-05 18:22:04 +08:00
if ( ! angle_init_context ( & uwp_egl , EGL_DEFAULT_DISPLAY ,
& major , & minor , & n , attribs , NULL ) )
2019-12-06 15:21:54 +08:00
# else
if ( ! egl_init_context ( & uwp_egl , EGL_NONE , EGL_DEFAULT_DISPLAY ,
& major , & minor , & n , attribs , NULL ) )
# endif
2019-12-05 18:22:04 +08:00
{
egl_report_error ( ) ;
goto error ;
}
if ( ! egl_get_native_visual_id ( & uwp_egl , & format ) )
goto error ;
if ( ! egl_create_context ( & uwp_egl , context_attributes ) )
{
egl_report_error ( ) ;
goto error ;
}
2020-01-03 06:07:05 +08:00
if ( ! egl_create_surface ( & uwp_egl , uwp_get_corewindow ( ) ) )
2019-12-05 18:22:04 +08:00
goto error ;
return true ;
error :
return false ;
}
static void gfx_ctx_uwp_swap_interval ( void * data , int interval )
{
2020-07-18 14:11:13 +02:00
gfx_ctx_uwp_data_t * uwp = ( gfx_ctx_uwp_data_t * ) data ;
if ( uwp - > interval ! = interval )
2019-12-05 18:22:04 +08:00
{
2020-07-18 14:11:13 +02:00
uwp - > interval = interval ;
egl_set_swap_interval ( & uwp_egl , uwp - > interval ) ;
2019-12-05 18:22:04 +08:00
}
}
static gfx_ctx_proc_t gfx_ctx_uwp_get_proc_address ( const char * symbol )
{
# ifdef HAVE_DYNAMIC
return ( gfx_ctx_proc_t ) GetProcAddress ( ( HINSTANCE ) dll_handle , symbol ) ;
# else
return NULL ;
# endif
}
2020-07-14 16:27:49 +02:00
static void gfx_ctx_uwp_swap_buffers ( void * data ) { egl_swap_buffers ( & uwp_egl ) ; }
2019-12-05 18:22:04 +08:00
static bool gfx_ctx_uwp_set_resize ( void * data ,
2020-07-14 16:27:49 +02:00
unsigned width , unsigned height ) { return false ; }
2019-12-05 18:22:04 +08:00
static void gfx_ctx_uwp_get_video_size ( void * data ,
unsigned * width , unsigned * height )
{
bool quit ;
bool resize ;
2020-07-18 17:09:07 +02:00
win32_check_window ( NULL , & quit , & resize , width , height ) ;
2021-12-24 13:34:30 +00:00
if ( is_running_on_xbox ( ) )
{
//we can set it to 1920x1080 as xbox uwp windowsize is guaranteed to be 1920x1080 and currently there is now way to set angle to use a variable resolution swapchain so regardless of the size the window is always 1080p
width = 1920 ;
height = 1080 ;
}
2019-12-05 18:22:04 +08:00
}
2020-03-07 00:39:06 +01:00
static void * gfx_ctx_uwp_init ( void * video_driver )
2019-12-05 18:22:04 +08:00
{
gfx_ctx_uwp_data_t * uwp = ( gfx_ctx_uwp_data_t * ) calloc ( 1 , sizeof ( * uwp ) ) ;
if ( ! uwp )
return NULL ;
# ifdef HAVE_DYNAMIC
dll_handle = dylib_load ( " libGLESv2.dll " ) ;
# endif
return uwp ;
}
static void gfx_ctx_uwp_destroy ( void * data )
{
gfx_ctx_uwp_data_t * wgl = ( gfx_ctx_uwp_data_t * ) data ;
2020-07-18 14:11:13 +02:00
if ( ! wgl )
return ;
2019-12-05 18:22:04 +08:00
2020-07-14 16:27:49 +02:00
egl_destroy ( & uwp_egl ) ;
2019-12-05 18:22:04 +08:00
# ifdef HAVE_DYNAMIC
dylib_close ( dll_handle ) ;
# endif
}
static bool gfx_ctx_uwp_set_video_mode ( void * data ,
unsigned width , unsigned height ,
bool fullscreen )
{
2020-07-18 14:11:13 +02:00
gfx_ctx_uwp_data_t * uwp = ( gfx_ctx_uwp_data_t * ) data ;
2019-12-05 18:22:04 +08:00
if ( ! win32_set_video_mode ( NULL , width , height , fullscreen ) )
{
RARCH_ERR ( " [UWP EGL]: win32_set_video_mode failed. \n " ) ;
}
2020-07-18 14:11:13 +02:00
if ( ! create_gles_context ( uwp_get_corewindow ( ) ) )
{
2019-12-05 18:22:04 +08:00
RARCH_ERR ( " [UWP EGL]: create_gles_context failed. \n " ) ;
goto error ;
}
2020-07-18 14:11:13 +02:00
gfx_ctx_uwp_swap_interval ( data , uwp - > interval ) ;
2019-12-05 18:22:04 +08:00
return true ;
error :
gfx_ctx_uwp_destroy ( data ) ;
return false ;
}
static void gfx_ctx_uwp_input_driver ( void * data ,
const char * joypad_name ,
input_driver_t * * input , void * * input_data )
{
settings_t * settings = config_get_ptr ( ) ;
/* Plain xinput is supported on UWP, but it
* supports joypad only ( uwp driver was added later ) */
if ( string_is_equal ( settings - > arrays . input_driver , " xinput " ) )
{
2020-08-30 05:29:32 +02:00
void * xinput = input_driver_init_wrap ( & input_xinput , joypad_name ) ;
2020-07-14 16:27:49 +02:00
* input = xinput ? ( input_driver_t * ) & input_xinput : NULL ;
* input_data = xinput ;
2019-12-05 18:22:04 +08:00
}
else
{
2020-08-30 05:29:32 +02:00
void * uwp = input_driver_init_wrap ( & input_uwp , joypad_name ) ;
2020-07-14 16:27:49 +02:00
* input = uwp ? ( input_driver_t * ) & input_uwp : NULL ;
2019-12-05 18:22:04 +08:00
* input_data = uwp ;
}
}
static enum gfx_ctx_api gfx_ctx_uwp_get_api ( void * data )
{
2020-07-14 16:27:49 +02:00
return GFX_CTX_OPENGL_ES_API ;
2019-12-05 18:22:04 +08:00
}
static bool gfx_ctx_uwp_bind_api ( void * data ,
enum gfx_ctx_api api , unsigned major , unsigned minor )
{
if ( api = = GFX_CTX_OPENGL_ES_API )
return true ;
2020-07-14 16:27:49 +02:00
return false ;
2019-12-05 18:22:04 +08:00
}
static void gfx_ctx_uwp_bind_hw_render ( void * data , bool enable )
{
2020-07-14 16:27:49 +02:00
egl_bind_hw_render ( & uwp_egl , enable ) ;
2019-12-05 18:22:04 +08:00
}
static uint32_t gfx_ctx_uwp_get_flags ( void * data )
{
uint32_t flags = 0 ;
# if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
2020-07-14 16:27:49 +02:00
BIT32_SET ( flags , GFX_CTX_FLAGS_SHADERS_SLANG ) ;
2019-12-05 18:22:04 +08:00
# endif
# ifdef HAVE_GLSL
2020-07-14 16:27:49 +02:00
BIT32_SET ( flags , GFX_CTX_FLAGS_SHADERS_GLSL ) ;
2019-12-05 18:22:04 +08:00
# endif
return flags ;
}
const gfx_ctx_driver_t gfx_ctx_uwp = {
gfx_ctx_uwp_init ,
gfx_ctx_uwp_destroy ,
gfx_ctx_uwp_get_api ,
gfx_ctx_uwp_bind_api ,
gfx_ctx_uwp_swap_interval ,
gfx_ctx_uwp_set_video_mode ,
gfx_ctx_uwp_get_video_size ,
NULL , /* get refresh rate */
NULL , /* get video output size */
NULL , /* get video output prev */
NULL , /* get video output next */
win32_get_metrics ,
NULL ,
NULL , /* update title */
2020-07-18 17:09:07 +02:00
win32_check_window ,
2019-12-05 18:22:04 +08:00
gfx_ctx_uwp_set_resize ,
2020-01-04 15:49:23 +01:00
win32_has_focus ,
2019-12-05 18:22:04 +08:00
NULL , /* suppress screensaver */
true , /* has_windowed */
gfx_ctx_uwp_swap_buffers ,
gfx_ctx_uwp_input_driver ,
gfx_ctx_uwp_get_proc_address ,
NULL ,
NULL ,
2020-01-04 15:40:02 +01:00
win32_show_cursor ,
2020-07-20 18:22:33 +02:00
" egl_uwp " ,
2019-12-05 18:22:04 +08:00
gfx_ctx_uwp_get_flags , /* get flags */
NULL , /* set flags */
gfx_ctx_uwp_bind_hw_render ,
NULL ,
NULL
} ;