From 462a4b24fd5e4b72c15d87dc3d9078a2396a160d Mon Sep 17 00:00:00 2001 From: Mats Date: Fri, 4 Jan 2019 21:42:20 +0100 Subject: [PATCH] libnx: refactor all the code of the now deprecated gfx api over to the new nwindow / framebuffer api --- frontend/drivers/platform_switch.c | 29 +++----- gfx/common/switch_common.h | 9 +++ gfx/drivers/switch_nx_gfx.c | 104 +++++++++++++++++------------ gfx/drivers_context/switch_ctx.c | 10 +-- gfx/drivers_font/switch_font.c | 22 +++--- 5 files changed, 99 insertions(+), 75 deletions(-) diff --git a/frontend/drivers/platform_switch.c b/frontend/drivers/platform_switch.c index 59e38b6d44..1233e9e042 100644 --- a/frontend/drivers/platform_switch.c +++ b/frontend/drivers/platform_switch.c @@ -258,9 +258,6 @@ static void frontend_switch_deinit(void *data) if (psmInitialized) psmExit(); -#ifndef HAVE_OPENGL - gfxExit(); -#endif appletUnlockExit(); #endif } @@ -402,18 +399,24 @@ void frontend_switch_showsplash(void) { printf("[Splash] Showing splashScreen\n"); + NWindow *win = nwindowGetDefault(); + Framebuffer fb; + framebufferCreate(&fb, win, 1280, 720, PIXEL_FORMAT_RGBA_8888, 2); + framebufferMakeLinear(&fb); + if (splashData) { uint32_t width = 0; uint32_t height = 0; - uint32_t *frambuffer = (uint32_t *)gfxGetFramebuffer(&width, &height); + uint32_t stride; + uint32_t *frambuffer = (uint32_t *)framebufferBegin(&fb, &stride); - gfx_slow_swizzling_blit(frambuffer, splashData, width, height, 0, 0, false); + gfx_cpy_dsp_buf(frambuffer, splashData, width, height, stride, false); - gfxFlushBuffers(); - gfxSwapBuffers(); - gfxWaitForVsync(); + framebufferEnd(&fb); } + + framebufferClose(&fb); } /* From rpng_test.c */ @@ -670,16 +673,6 @@ static void frontend_switch_init(void *data) appletHook(&applet_hook_cookie, on_applet_hook, NULL); appletSetFocusHandlingMode(AppletFocusHandlingMode_NoSuspend); -#ifndef HAVE_OPENGL - /* Init Resolution before initDefault */ - gfxInitResolution(1280, 720); - - gfxInitDefault(); - gfxSetMode(GfxMode_TiledDouble); - - gfxConfigureTransform(0); -#endif /* HAVE_OPENGL */ - bool recording_supported = false; appletIsGamePlayRecordingSupported(&recording_supported); if(recording_supported) diff --git a/gfx/common/switch_common.h b/gfx/common/switch_common.h index aa1813bf4c..5bb601ad92 100644 --- a/gfx/common/switch_common.h +++ b/gfx/common/switch_common.h @@ -56,6 +56,13 @@ typedef struct bool o_size; uint32_t o_height; uint32_t o_width; + + NWindow *win; + Framebuffer fb; + + // needed for the switch font driver + uint32_t *out_buffer; + uint32_t stride; } switch_video_t; typedef struct @@ -72,8 +79,10 @@ typedef struct bool resize; unsigned width, height; float refresh_rate; + NWindow *win; } switch_ctx_data_t; void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, int tx, int ty, bool blend); +void gfx_cpy_dsp_buf(uint32_t *buffer, uint32_t *image, int w, int h, uint32_t stride, bool blend); #endif diff --git a/gfx/drivers/switch_nx_gfx.c b/gfx/drivers/switch_nx_gfx.c index 0200e1658a..93d1d7b86d 100644 --- a/gfx/drivers/switch_nx_gfx.c +++ b/gfx/drivers/switch_nx_gfx.c @@ -130,18 +130,47 @@ void gfx_slow_swizzling_blit(uint32_t *buffer, uint32_t *image, int w, int h, in } } +void gfx_cpy_dsp_buf(uint32_t *buffer, uint32_t *image, int w, int h, uint32_t stride, bool blend) +{ + uint32_t *dest = buffer; + uint32_t *src = image; + for (uint32_t y = 0; y < h; y ++) + { + for (uint32_t x = 0; x < w; x ++) + { + uint32_t pos = y * stride / sizeof(uint32_t) + x; + uint32_t pixel = *src; + + if (blend) /* supercheap masking */ + { + uint32_t dst = dest[pos]; + uint8_t src_a = ((pixel & 0xFF000000) >> 24); + + if (src_a > 0) + pixel &= 0x00FFFFFF; + else + pixel = dst; + } + + dest[pos] = pixel; + + src++; + } + } +} + /* needed to clear surface completely as hw scaling doesn't always scale to full resoution perflectly */ static void clear_screen(switch_video_t *sw) { - uint32_t *out_buffer = NULL; - gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height); + nwindowSetDimensions(sw->win, sw->vp.full_width, sw->vp.full_height); - out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL); + uint32_t stride; - memset(out_buffer, 0, gfxGetFramebufferSize()); + uint32_t *out_buffer = (uint32_t*)framebufferBegin(&sw->fb, &stride); - gfxFlushBuffers(); - gfxSwapBuffers(); + memset(out_buffer, 0, stride * 720); + + framebufferEnd(&sw->fb); } static void *switch_init(const video_info_t *video, @@ -152,6 +181,11 @@ static void *switch_init(const video_info_t *video, if (!sw) return NULL; + sw->win = nwindowGetDefault(); + + framebufferCreate(&sw->fb, sw->win, 1280, 720, PIXEL_FORMAT_RGBA_8888, 2); + framebufferMakeLinear(&sw->fb); + printf("loading switch gfx driver, width: %d, height: %d threaded: %d smooth %d\n", video->width, video->height, video->is_threaded, video->smooth); sw->vp.x = 0; sw->vp.y = 0; @@ -186,18 +220,6 @@ static void *switch_init(const video_info_t *video, *input_data = switchinput; } -#ifdef HAVE_LIBNX -#ifdef HAVE_OPENGL - // Init Resolution before initDefault - gfxInitResolution(1280, 720); - - gfxInitDefault(); - gfxSetMode(GfxMode_TiledDouble); - - gfxConfigureTransform(0); -#endif // HAVE_OPENGL -#endif - font_driver_init_osd(sw, false, video->is_threaded, FONT_DRIVER_RENDER_SWITCH); @@ -398,8 +420,8 @@ static bool switch_frame(void *data, const void *frame, sw->hw_scale.x_offset = ceil((sw->hw_scale.width - sw->scaler.out_width) / 2.0); if (!video_info->menu_is_alive) { - clear_screen(sw); - gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height); + clear_screen(sw); + nwindowSetDimensions(sw->win, sw->hw_scale.width, sw->hw_scale.height); } } sw->scaler.out_fmt = SCALER_FMT_ABGR8888; @@ -418,12 +440,16 @@ static bool switch_frame(void *data, const void *frame, sw->should_resize = false; } - out_buffer = (uint32_t *)gfxGetFramebuffer(NULL, NULL); + uint32_t stride; + + out_buffer = (uint32_t *)framebufferBegin(&sw->fb, &stride); + sw->out_buffer = out_buffer; + sw->stride = stride; if (sw->in_menu && !video_info->menu_is_alive && sw->smooth) { - memset(out_buffer, 0, sw->vp.full_width * sw->vp.full_height * 4); - gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height); + memset(out_buffer, 0, stride * sw->vp.full_height);; + nwindowSetDimensions(sw->win, sw->hw_scale.width, sw->hw_scale.height); } sw->in_menu = video_info->menu_is_alive; @@ -434,12 +460,12 @@ static bool switch_frame(void *data, const void *frame, if (sw->menu_texture.pixels) { #ifdef HAVE_NXRGUI - gfx_slow_swizzling_blit(out_buffer, nx_backgroundImage, sw->vp.full_width, sw->vp.full_height, 0, 0, false); + gfx_cpy_dsp_buf(out_buffer, nx_backgroundImage, sw->vp.full_width, sw->vp.full_height, stride, false); #else - memset(out_buffer, 0, gfxGetFramebufferSize()); + memset(out_buffer, 0, stride * sw->vp.full_height);; #endif scaler_ctx_scale(&sw->menu_texture.scaler, sw->tmp_image + ((sw->vp.full_height - sw->menu_texture.tgth) / 2) * sw->vp.full_width + ((sw->vp.full_width - sw->menu_texture.tgtw) / 2), sw->menu_texture.pixels); - gfx_slow_swizzling_blit(out_buffer, sw->tmp_image, sw->vp.full_width, sw->vp.full_height, 0, 0, true); + gfx_cpy_dsp_buf(out_buffer, sw->tmp_image, sw->vp.full_width, sw->vp.full_height, stride, true); } } else if (sw->smooth) /* bilinear */ @@ -453,16 +479,16 @@ static bool switch_frame(void *data, const void *frame, for (y = 0; y < h; y++) for (x = 0; x < w; x++) - out_buffer[gfxGetFramebufferDisplayOffset(x + sw->hw_scale.x_offset, y)] = sw->image[y * w + x]; + out_buffer[y * stride / sizeof(uint32_t) + (x + sw->hw_scale.x_offset)] = sw->image[y * w + x]; } else { struct scaler_ctx *ctx = &sw->scaler; scaler_ctx_scale(ctx, sw->image + (sw->vp.y * sw->vp.full_width) + sw->vp.x, frame); - gfx_slow_swizzling_blit(out_buffer, sw->image, sw->vp.full_width, sw->vp.full_height, 0, 0, false); + gfx_cpy_dsp_buf(out_buffer, sw->image, sw->vp.full_width, sw->vp.full_height, stride, false); #ifdef HAVE_NXRGUI if (tmp_overlay) - gfx_slow_swizzling_blit(out_buffer, tmp_overlay, sw->vp.full_width, sw->vp.full_height, 0, 0, true); + gfx_cpy_dsp_buf(out_buffer, tmp_overlay, sw->vp.full_width, sw->vp.full_height, stride, true); #endif } @@ -478,10 +504,7 @@ static bool switch_frame(void *data, const void *frame, if (msg) font_driver_render_msg(video_info, NULL, msg, NULL); - gfxFlushBuffers(); - gfxSwapBuffers(); - if (sw->vsync) - gfxWaitForVsync(); + framebufferEnd(&sw->fb); return true; } @@ -520,16 +543,13 @@ static bool switch_has_windowed(void *data) static void switch_free(void *data) { switch_video_t *sw = data; + + framebufferClose(&sw->fb); + if (sw->menu_texture.pixels) free(sw->menu_texture.pixels); free(sw); - -#ifdef HAVE_LIBNX -#ifdef HAVE_OPENGL - gfxExit(); -#endif // HAVE_OPENGL -#endif } static bool switch_set_shader(void *data, @@ -633,15 +653,13 @@ static void switch_apply_state_changes(void *data) static void switch_set_texture_enable(void *data, bool enable, bool full_screen) { switch_video_t *sw = data; - if (!sw->menu_texture.enable && enable) - gfxConfigureResolution(sw->vp.full_width, sw->vp.full_height); + nwindowSetDimensions(sw->win, sw->vp.full_width, sw->vp.full_height); else if (!enable && sw->menu_texture.enable && sw->smooth) { clear_screen(sw); - gfxConfigureResolution(sw->hw_scale.width, sw->hw_scale.height); + nwindowSetDimensions(sw->win, sw->hw_scale.width, sw->hw_scale.height); } - sw->menu_texture.enable = enable; sw->menu_texture.fullscreen = full_screen; } diff --git a/gfx/drivers_context/switch_ctx.c b/gfx/drivers_context/switch_ctx.c index 1bdfe71447..a162363b50 100644 --- a/gfx/drivers_context/switch_ctx.c +++ b/gfx/drivers_context/switch_ctx.c @@ -97,8 +97,8 @@ static void *switch_ctx_init(video_frame_info_t *video_info, void *video_driver) #endif // Needs to be here - gfxInitResolutionDefault(); // 1080p - gfxConfigureResolution(1920, 1080); + ctx_nx->win = nwindowGetDefault(); + nwindowSetDimensions(ctx_nx->win, 1920, 1080); #ifdef HAVE_EGL if (!egl_init_context(&ctx_nx->egl, EGL_NONE, EGL_DEFAULT_DISPLAY, @@ -139,7 +139,7 @@ static void switch_ctx_check_window(void *data, bool *quit, *resize = true; printf("[NXGL]: Resizing to %dx%d\n", *width, *height); - gfxConfigureCrop(0, 1080 - ctx_nx->height, ctx_nx->width, 1080); + nwindowSetCrop(ctx_nx->win, 0, 1080 - ctx_nx->height, ctx_nx->width, 1080); } *quit = (bool)false; @@ -174,11 +174,11 @@ static bool switch_ctx_set_video_mode(void *data, #endif #ifdef HAVE_EGL - if (!egl_create_surface(&ctx_nx->egl, &ctx_nx->native_window)) + if (!egl_create_surface(&ctx_nx->egl, ctx_nx->win)) goto error; #endif - gfxConfigureCrop(0, 1080 - ctx_nx->height, ctx_nx->width, 1080); + nwindowSetCrop(ctx_nx->win, 0, 1080 - ctx_nx->height, ctx_nx->width, 1080); return true; diff --git a/gfx/drivers_font/switch_font.c b/gfx/drivers_font/switch_font.c index 0b9d5be7f3..e9489bdb1d 100644 --- a/gfx/drivers_font/switch_font.c +++ b/gfx/drivers_font/switch_font.c @@ -115,15 +115,19 @@ static void switch_font_render_line( float scale, const unsigned int color, float pos_x, float pos_y, unsigned text_align) { + switch_video_t* sw = (switch_video_t*)video_info->userdata; + + if(!sw) + return; + int delta_x = 0; int delta_y = 0; - unsigned fbWidth = 0; - unsigned fbHeight = 0; + unsigned fbWidth = sw->vp.full_width; + unsigned fbHeight = sw->vp.full_height; + + if (sw->out_buffer) { - uint32_t *out_buffer = (uint32_t *)gfxGetFramebuffer(&fbWidth, &fbHeight); - if (out_buffer) - { int x = roundf(pos_x * fbWidth); int y = roundf((1.0f - pos_y) * fbHeight); @@ -148,7 +152,7 @@ static void switch_font_render_line( i += skip - 1; const struct font_glyph *glyph = - font->font_driver->get_glyph(font->font_data, code); + font->font_driver->get_glyph(font->font_data, code); if (!glyph) /* Do something smarter here ... */ glyph = font->font_driver->get_glyph(font->font_data, '?'); @@ -169,12 +173,12 @@ static void switch_font_render_line( uint8_t *row = &font->atlas->buffer[y * font->atlas->width]; for (int x = tex_x; x < tex_x + width; x++) { - if (!row[x]) - continue; + if (!row[x]) + continue; int x1 = off_x + (x - tex_x); int y1 = off_y + (y - tex_y); if (x1 < fbWidth && y1 < fbHeight) - out_buffer[gfxGetFramebufferDisplayOffset(x1, y1)] = color; + sw->out_buffer[y1 * sw->stride / sizeof(uint32_t) + x1] = color; } }