diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index 547696b25b..b3ec46706a 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -542,7 +542,7 @@ struct sunxi_video unsigned int menu_height; unsigned int menu_pitch; - bool aspect_changed; + float aspect_ratio; }; static void sunxi_blank_console(struct sunxi_video *_dispvars) @@ -633,6 +633,11 @@ static void *sunxi_gfx_init(const video_info_t *video, _dispvars->keep_vsync = true; _dispvars->menu_active = false; _dispvars->bytes_per_pixel = video->rgb32 ? 4 : 2; + /* It's very important that we set aspect here because the + * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() + * and we don't want the main surface to be setup in set_aspect() + * before we get to gfx_frame(). */ + _dispvars->aspect_ratio = video_driver_get_aspect_ratio(); switch (_dispvars->bytes_per_pixel) { @@ -745,29 +750,7 @@ static void sunxi_setup_scale (void *data, _dispvars->pages[i].address = ((uint32_t*) _dispvars->sunxi_disp->framebuffer_addr + (_dispvars->sunxi_disp->yres + i * _dispvars->src_height) * _dispvars->dst_pitch/4); } - switch (settings->video.aspect_ratio_idx) - { - case ASPECT_RATIO_4_3: - aspect = (float)4 / (float)3; - break; - case ASPECT_RATIO_16_9: - aspect = (float)16 / (float)9; - break; - case ASPECT_RATIO_16_10: - aspect = (float)16 / (float)10; - break; - case ASPECT_RATIO_16_15: - aspect = (float)16 / (float)15; - break; - case ASPECT_RATIO_CORE: - aspect = (float)_dispvars->src_width / (float)_dispvars->src_height; - break; - default: - aspect = (float)_dispvars->src_width / (float)_dispvars->src_height; - break; - } - - visible_width = _dispvars->sunxi_disp->yres * aspect; + visible_width = _dispvars->sunxi_disp->yres * _dispvars->aspect_ratio; xpos = (_dispvars->sunxi_disp->xres - visible_width) / 2; /* setup layer window */ @@ -898,40 +881,43 @@ static void sunxi_set_texture_enable(void *data, bool state, bool full_screen) static void sunxi_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { - uint16_t src_pix; - uint32_t R, G, B, dst_pix; - unsigned int i, j; struct sunxi_video *_dispvars = (struct sunxi_video*)data; - - /* We have to go on a pixel format conversion adventure for now, until we can - * convince RGUI to output in an 8888 format. */ - unsigned int src_pitch = width * 2; - unsigned int dst_pitch = _dispvars->sunxi_disp->xres * 4; - unsigned int dst_width = _dispvars->sunxi_disp->xres; - uint32_t line[dst_width]; + + if (_dispvars->menu_active) { + uint16_t src_pix; + uint32_t R, G, B, dst_pix; + unsigned int i, j; + + /* We have to go on a pixel format conversion adventure for now, until we can + * convince RGUI to output in an 8888 format. */ + unsigned int src_pitch = width * 2; + unsigned int dst_pitch = _dispvars->sunxi_disp->xres * 4; + unsigned int dst_width = _dispvars->sunxi_disp->xres; + uint32_t line[dst_width]; - /* Remember, memcpy() works with 8bits pointers for increments. */ - char *dst_base_addr = (char*)(_dispvars->pages[0].address); - char *src_base_addr = (char*)frame; + /* Remember, memcpy() works with 8bits pointers for increments. */ + char *dst_base_addr = (char*)(_dispvars->pages[0].address); + char *src_base_addr = (char*)frame; - for (i = 0; i < height; i++) - { - for (j = 0; j < src_pitch / 2; j++) + for (i = 0; i < height; i++) { - src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); - /* The hex AND is for keeping only the part we need for each component. */ - R = (src_pix << 8) & 0x00FF0000; - G = (src_pix << 4) & 0x0000FF00; - B = (src_pix << 0) & 0x000000FF; - line[j] = (0 | R | G | B); + for (j = 0; j < src_pitch / 2; j++) + { + src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); + /* The hex AND is for keeping only the part we need for each component. */ + R = (src_pix << 8) & 0x00FF0000; + G = (src_pix << 4) & 0x0000FF00; + B = (src_pix << 0) & 0x000000FF; + line[j] = (0 | R | G | B); + } + memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch); } - memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch); - } - /* Issue pageflip. Will flip on next vsync. */ - sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp, - _dispvars->sunxi_disp->bits_per_pixel, - _dispvars->pages[0].offset, width, height, _dispvars->sunxi_disp->xres); + /* Issue pageflip. Will flip on next vsync. */ + sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp, + _dispvars->sunxi_disp->bits_per_pixel, + _dispvars->pages[0].offset, width, height, _dispvars->sunxi_disp->xres); + } } static uint64_t sunxi_get_frame_count(void *data) @@ -942,6 +928,17 @@ static uint64_t sunxi_get_frame_count(void *data) return _dispvars->frame_count; } +static void sunxi_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) +{ + struct sunxi_video *_dispvars = (struct sunxi_video*)data; + /* Here we obtain the new aspect ratio. */ + float new_aspect = aspectratio_lut[aspect_ratio_idx].value; + if (new_aspect != _dispvars->aspect_ratio) { + _dispvars->aspect_ratio = new_aspect; + sunxi_setup_scale(_dispvars, _dispvars->src_width, _dispvars->src_height, _dispvars->src_pitch); + } +} + static const video_poke_interface_t sunxi_poke_interface = { sunxi_get_frame_count, NULL, /* set_video_mode */ @@ -951,7 +948,7 @@ static const video_poke_interface_t sunxi_poke_interface = { NULL, /* get_video_output_next */ NULL, /* get_current_framebuffer */ NULL, /* get_proc_address */ - NULL, /* sunxi_set_aspect_ratio */ + sunxi_set_aspect_ratio, NULL, /* sunxi_apply_state_changes */ #ifdef HAVE_MENU sunxi_set_texture_frame,