libnx: refactor all the code of the now deprecated gfx api over to the new nwindow / framebuffer api

This commit is contained in:
Mats 2019-01-04 21:42:20 +01:00 committed by Mats A
parent 74c8c13102
commit 462a4b24fd
5 changed files with 99 additions and 75 deletions

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}
}