Renderer fixes and improvements.

This commit is contained in:
OBattler
2020-11-28 07:04:40 +01:00
parent bdd4499eb3
commit 19e093e554
8 changed files with 313 additions and 357 deletions

View File

@@ -82,7 +82,6 @@ static SDL_Window *sdl_win = NULL;
static SDL_Renderer *sdl_render = NULL;
static SDL_Texture *sdl_tex = NULL;
static HWND sdl_parent_hwnd = NULL;
static HWND sdl_hwnd = NULL;
static int sdl_w, sdl_h;
static int sdl_fs, sdl_flags = -1;
static int cur_w, cur_h;
@@ -181,6 +180,7 @@ sdl_stretch(int *w, int *h, int *x, int *y)
switch (video_fullscreen_scale) {
case FULLSCR_SCALE_FULL:
default:
*w = sdl_w;
*h = sdl_h;
*x = 0;
@@ -225,8 +225,6 @@ sdl_stretch(int *w, int *h, int *x, int *y)
*y = (int) dy;
break;
}
sdl_reinit_texture();
}
@@ -236,17 +234,7 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h)
SDL_Rect r_src;
int ret;
if (!sdl_enabled) {
video_blit_complete();
return;
}
if ((y1 == y2) || (h <= 0)) {
video_blit_complete();
return;
}
if (render_buffer == NULL) {
if (!sdl_enabled || (y1 == y2) || (h <= 0) || (render_buffer == NULL)) {
video_blit_complete();
return;
}
@@ -260,13 +248,6 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h)
SDL_UpdateTexture(sdl_tex, &r_src, &(render_buffer->dat)[y1 * w], w * 4);
video_blit_complete();
if (sdl_fs) {
sdl_log("sdl_blit(%i, %i, %i, %i, %i, %i) (%i, %i)\n", x, y, y1, y2, w, h, unscaled_size_x, efscrnsz_y);
if (w == unscaled_size_x)
sdl_resize(w, h);
sdl_log("(%08X, %08X, %08X)\n", sdl_win, sdl_render, sdl_tex);
}
SDL_RenderClear(sdl_render);
r_src.x = 0;
@@ -279,11 +260,31 @@ sdl_blit(int x, int y, int y1, int y2, int w, int h)
sdl_log("SDL: unable to copy texture to renderer (%s)\n", sdl_GetError());
SDL_RenderPresent(sdl_render);
SDL_UnlockMutex(sdl_mutex);
}
static void
sdl_destroy_window(void)
{
if (sdl_win != NULL) {
SDL_DestroyWindow(sdl_win);
sdl_win = NULL;
}
}
static void
sdl_destroy_texture(void)
{
/* SDL_DestroyRenderer also automatically destroys all associated textures. */
if (sdl_render != NULL) {
SDL_DestroyRenderer(sdl_render);
sdl_render = NULL;
}
}
void
sdl_close(void)
{
@@ -300,32 +301,10 @@ sdl_close(void)
sdl_mutex = NULL;
}
if (sdl_tex != NULL) {
SDL_DestroyTexture(sdl_tex);
sdl_tex = NULL;
}
if (sdl_render != NULL) {
SDL_DestroyRenderer(sdl_render);
sdl_render = NULL;
}
if (sdl_win != NULL) {
SDL_DestroyWindow(sdl_win);
sdl_win = NULL;
}
if (sdl_hwnd != NULL) {
plat_set_input(hwndMain);
ShowWindow(hwndRender, TRUE);
SetFocus(hwndMain);
if (sdl_fs)
DestroyWindow(sdl_hwnd);
sdl_hwnd = NULL;
}
sdl_destroy_texture();
sdl_destroy_window();
ImmAssociateContext(hwndMain, NULL);
SetFocus(hwndMain);
if (sdl_parent_hwnd != NULL) {
DestroyWindow(sdl_parent_hwnd);
@@ -334,7 +313,6 @@ sdl_close(void)
/* Quit. */
SDL_Quit();
sdl_flags = -1;
}
@@ -359,13 +337,87 @@ sdl_select_best_hw_driver(void)
}
static void
sdl_reinit_texture(void)
{
if (sdl_flags == -1)
return;
sdl_destroy_texture();
if (sdl_flags & RENDERER_HARDWARE) {
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
} else
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
}
void
sdl_set_fs(int fs)
{
int w = 0, h = 0, x = 0, y = 0;
RECT rect;
SDL_LockMutex(sdl_mutex);
sdl_enabled = 0;
sdl_destroy_texture();
if (fs) {
ShowWindow(sdl_parent_hwnd, TRUE);
SetParent(hwndRender, sdl_parent_hwnd);
ShowWindow(hwndRender, TRUE);
MoveWindow(sdl_parent_hwnd, 0, 0, sdl_w, sdl_h, TRUE);
/* Show the window, make it topmost, and give it focus. */
w = unscaled_size_x;
h = efscrnsz_y;
sdl_stretch(&w, &h, &x, &y);
MoveWindow(hwndRender, x, y, w, h, TRUE);
ImmAssociateContext(sdl_parent_hwnd, NULL);
SetFocus(sdl_parent_hwnd);
/* Redirect RawInput to this new window. */
old_capture = mouse_capture;
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
mouse_capture = 1;
} else {
SetParent(hwndRender, hwndMain);
ShowWindow(sdl_parent_hwnd, FALSE);
ShowWindow(hwndRender, TRUE);
ImmAssociateContext(hwndMain, NULL);
SetFocus(hwndMain);
mouse_capture = old_capture;
if (mouse_capture) {
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
} else
ClipCursor(&oldclip);
}
sdl_fs = fs;
if (fs)
sdl_flags |= RENDERER_FULL_SCREEN;
else
sdl_flags &= ~RENDERER_FULL_SCREEN;
sdl_reinit_texture();
sdl_enabled = 1;
SDL_UnlockMutex(sdl_mutex);
}
static int
sdl_init_common(int flags)
{
wchar_t temp[128];
SDL_version ver;
int w = 0, h = 0, x = 0, y = 0;
RECT rect;
sdl_log("SDL: init (fs=%d)\n", fs);
@@ -386,111 +438,24 @@ sdl_init_common(int flags)
sdl_select_best_hw_driver();
}
if (flags & RENDERER_FULL_SCREEN) {
/* Get the size of the (current) desktop. */
sdl_w = GetSystemMetrics(SM_CXSCREEN);
sdl_h = GetSystemMetrics(SM_CYSCREEN);
/* Get the size of the (current) desktop. */
sdl_w = GetSystemMetrics(SM_CXSCREEN);
sdl_h = GetSystemMetrics(SM_CYSCREEN);
/* Create the desktop-covering window. */
_swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W);
sdl_parent_hwnd = CreateWindow(SUB_CLASS_NAME,
temp,
WS_POPUP,
0, 0, sdl_w, sdl_h,
HWND_DESKTOP,
NULL,
hinstance,
NULL);
/* Create the desktop-covering window. */
_swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W);
sdl_parent_hwnd = CreateWindow(SDL_CLASS_NAME, temp, WS_POPUP, 0, 0, sdl_w, sdl_h,
HWND_DESKTOP, NULL, hinstance, NULL);
ShowWindow(sdl_parent_hwnd, FALSE);
SetWindowPos(sdl_parent_hwnd, HWND_TOPMOST,
0, 0, sdl_w, sdl_h, SWP_SHOWWINDOW);
sdl_flags = flags;
/* Create the actual rendering window. */
_swprintf(temp, L"%s v%s", EMU_NAME_W, EMU_VERSION_W);
sdl_hwnd = CreateWindow(SUB_CLASS_NAME,
temp,
WS_POPUP,
0, 0, sdl_w, sdl_h,
sdl_parent_hwnd,
NULL,
hinstance,
NULL);
sdl_log("SDL: FS %dx%d window at %08lx\n", sdl_w, sdl_h, sdl_hwnd);
/* Redirect RawInput to this new window. */
plat_set_input(sdl_hwnd);
SetFocus(sdl_hwnd);
/* Show the window, make it topmost, and give it focus. */
w = unscaled_size_x;
h = efscrnsz_y;
sdl_stretch(&w, &h, &x, &y);
SetWindowPos(sdl_hwnd, sdl_parent_hwnd,
x, y, w, h, SWP_SHOWWINDOW);
/* Now create the SDL window from that. */
sdl_win = SDL_CreateWindowFrom((void *)sdl_hwnd);
old_capture = mouse_capture;
GetWindowRect(sdl_hwnd, &rect);
ClipCursor(&rect);
mouse_capture = 1;
} else {
/* Create the SDL window from the render window. */
sdl_win = SDL_CreateWindowFrom((void *)hwndRender);
mouse_capture = old_capture;
if (mouse_capture) {
GetWindowRect(hwndRender, &rect);
ClipCursor(&rect);
} else {
ClipCursor(&oldclip);
}
}
if (sdl_win == NULL) {
sdl_log("SDL: unable to CreateWindowFrom (%s)\n", SDL_GetError());
sdl_close();
return(0);
}
/*
* TODO:
* SDL_RENDERER_SOFTWARE, because SDL tries to do funky stuff
* otherwise (it turns off Win7 Aero and it looks like it's
* trying to switch to fullscreen even though the window is
* not a fullscreen window?)
*/
if (flags & RENDERER_HARDWARE) {
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
} else
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
if (sdl_render == NULL) {
sdl_log("SDL: unable to create renderer (%s)\n", SDL_GetError());
sdl_close();
return(0);
}
/*
* TODO:
* Actually the source is (apparently) XRGB8888, but the alpha
* channel seems to be set to 255 everywhere, so ARGB8888 works
* just as well.
*/
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
if (sdl_tex == NULL) {
sdl_log("SDL: unable to create texture (%s)\n", SDL_GetError());
sdl_close();
return(0);
}
sdl_win = SDL_CreateWindowFrom((void *)hwndRender);
sdl_set_fs(video_fullscreen & 1);
/* Make sure we get a clean exit. */
atexit(sdl_close);
@@ -498,14 +463,9 @@ sdl_init_common(int flags)
/* Register our renderer! */
video_setblit(sdl_blit);
sdl_fs = !!(flags & RENDERER_FULL_SCREEN);
sdl_enabled = 1;
sdl_mutex = SDL_CreateMutex();
sdl_flags = flags;
return(1);
}
@@ -531,47 +491,6 @@ sdl_initho(HWND h)
}
int
sdl_inits_fs(HWND h)
{
return sdl_init_common(RENDERER_FULL_SCREEN);
}
int
sdl_inith_fs(HWND h)
{
return sdl_init_common(RENDERER_FULL_SCREEN | RENDERER_HARDWARE);
}
int
sdl_initho_fs(HWND h)
{
return sdl_init_common(RENDERER_FULL_SCREEN | RENDERER_HARDWARE | RENDERER_OPENGL);
}
void
sdl_reinit_texture()
{
if ((sdl_render == NULL) || (sdl_flags == -1))
return;
SDL_DestroyTexture(sdl_tex);
SDL_DestroyRenderer(sdl_render);
if (sdl_flags & RENDERER_HARDWARE) {
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2");
} else
sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_SOFTWARE);
sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 2048, 2048);
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy);
}
int
sdl_pause(void)
{
@@ -584,6 +503,9 @@ sdl_resize(int x, int y)
{
int ww = 0, wh = 0, wx = 0, wy = 0;
if (video_fullscreen & 2)
return;
if ((x == cur_w) && (y == cur_h))
return;
@@ -594,7 +516,7 @@ sdl_resize(int x, int y)
if (sdl_fs) {
sdl_stretch(&ww, &wh, &wx, &wy);
MoveWindow(sdl_hwnd, wx, wy, ww, wh, TRUE);
MoveWindow(hwndRender, wx, wy, ww, wh, TRUE);
}
cur_w = x;
@@ -605,6 +527,9 @@ sdl_resize(int x, int y)
cur_ww = ww;
cur_wh = wh;
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
SDL_SetWindowPosition(sdl_win, cur_wx, cur_wy);
sdl_reinit_texture();
SDL_UnlockMutex(sdl_mutex);
@@ -619,7 +544,11 @@ sdl_enable(int enable)
SDL_LockMutex(sdl_mutex);
sdl_enabled = enable;
if (enable)
if (enable == 1) {
SDL_SetWindowSize(sdl_win, cur_ww, cur_wh);
sdl_reinit_texture();
}
SDL_UnlockMutex(sdl_mutex);
}