OpenDingux: Enable selection of image interpolation method when using 'sdl_dingux' gfx driver

This commit is contained in:
jdgleaver 2020-10-05 14:31:26 +01:00
parent 35d7e0ccdf
commit 80f1da2fb1
12 changed files with 252 additions and 36 deletions

View File

@ -37,6 +37,11 @@
#include "gfx/common/ctr_common.h"
#endif
/* Required for OpenDingux IPU filter setting */
#if defined(DINGUX)
#include "dingux/dingux_utils.h"
#endif
#if defined(HW_RVL)
#define MAX_GAMMA_SETTING 30
#elif defined(GEKKO)
@ -315,7 +320,7 @@
#endif
/* Smooths picture. */
#if defined(_3DS) || defined(GEKKO) || defined(HW_RVL) || defined(PSP) || defined(VITA) || defined(SN_TARGET_PSP2) || defined(PS2) || defined(_XBOX)
#if defined(_3DS) || defined(GEKKO) || defined(HW_RVL) || defined(PSP) || defined(VITA) || defined(SN_TARGET_PSP2) || defined(PS2) || defined(_XBOX) || defined(DINGUX)
#define DEFAULT_VIDEO_SMOOTH true
#else
#define DEFAULT_VIDEO_SMOOTH false
@ -365,6 +370,9 @@
/* Enables aspect ratio correction (1:1 PAR) when
* using the IPU hardware scaler in Dingux devices */
#define DEFAULT_DINGUX_IPU_KEEP_ASPECT true
/* Sets image filtering method when using the
* IPU hardware scaler in Dingux devices */
#define DEFAULT_DINGUX_IPU_FILTER_TYPE DINGUX_IPU_FILTER_BICUBIC
#endif
/* Save configuration file on exit. */

View File

@ -1999,6 +1999,10 @@ static struct config_uint_setting *populate_settings_uint(
SETTING_UINT("video_3ds_display_mode", &settings->uints.video_3ds_display_mode, true, video_3ds_display_mode, false);
#endif
#if defined(DINGUX)
SETTING_UINT("video_dingux_ipu_filter_type", &settings->uints.video_dingux_ipu_filter_type, true, DEFAULT_DINGUX_IPU_FILTER_TYPE, false);
#endif
#ifdef HAVE_MENU
SETTING_UINT("playlist_entry_remove_enable", &settings->uints.playlist_entry_remove_enable, true, DEFAULT_PLAYLIST_ENTRY_REMOVE_ENABLE, false);
SETTING_UINT("playlist_show_inline_core_name", &settings->uints.playlist_show_inline_core_name, true, DEFAULT_PLAYLIST_SHOW_INLINE_CORE_NAME, false);

View File

@ -194,6 +194,7 @@ typedef struct settings
unsigned video_record_scale_factor;
unsigned video_stream_scale_factor;
unsigned video_3ds_display_mode;
unsigned video_dingux_ipu_filter_type;
#ifdef HAVE_VIDEO_LAYOUT
unsigned video_layout_selected_view;
#endif

View File

@ -20,10 +20,12 @@
#include "dingux_utils.h"
#define DINGUX_ALLOW_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/allow_downscaling"
#define DINGUX_KEEP_ASPECT_RATIO_FILE "/sys/devices/platform/jz-lcd.0/keep_aspect_ratio"
#define DINGUX_INTEGER_SCALING_FILE "/sys/devices/platform/jz-lcd.0/integer_scaling"
#define DINGUX_BATTERY_CAPACITY_FILE "/sys/class/power_supply/battery/capacity"
#define DINGUX_ALLOW_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/allow_downscaling"
#define DINGUX_KEEP_ASPECT_RATIO_FILE "/sys/devices/platform/jz-lcd.0/keep_aspect_ratio"
#define DINGUX_INTEGER_SCALING_FILE "/sys/devices/platform/jz-lcd.0/integer_scaling"
#define DINGUX_SHARPNESS_UPSCALING_FILE "/sys/devices/platform/jz-lcd.0/sharpness_upscaling"
#define DINGUX_SHARPNESS_DOWNSCALING_FILE "/sys/devices/platform/jz-lcd.0/sharpness_downscaling"
#define DINGUX_BATTERY_CAPACITY_FILE "/sys/class/power_supply/battery/capacity"
/* Enables/disables downscaling when using
* the IPU hardware scaler */
@ -60,7 +62,7 @@ bool dingux_ipu_set_aspect_ratio_enable(bool enable)
}
/* Enables/disables integer scaling when
* when using the IPU hardware scaler */
* using the IPU hardware scaler */
bool dingux_ipu_set_integer_scaling_enable(bool enable)
{
const char *path = DINGUX_INTEGER_SCALING_FILE;
@ -75,6 +77,55 @@ bool dingux_ipu_set_integer_scaling_enable(bool enable)
path, enable_str, 1);
}
/* Sets the image filtering method when
* using the IPU hardware scaler */
bool dingux_ipu_set_filter_type(enum dingux_ipu_filter_type filter_type)
{
/* Sharpness settings range is [0,32]
* - 0: nearest-neighbour
* - 1: bilinear
* - 2...32: bicubic (translating to a sharpness
* factor of -0.25..-4.0 internally)
* Default bicubic sharpness factor is
* (-0.125 * 8) = -1.0 */
const char *upscaling_path = DINGUX_SHARPNESS_UPSCALING_FILE;
const char *downscaling_path = DINGUX_SHARPNESS_DOWNSCALING_FILE;
const char *sharpness_str = "8";
bool upscaling_success = false;
bool downscaling_success = false;
/* Check filter type */
switch (filter_type)
{
case DINGUX_IPU_FILTER_BILINEAR:
sharpness_str = "1";
break;
case DINGUX_IPU_FILTER_NEAREST:
sharpness_str = "0";
break;
default:
/* sharpness_str is already set to 8
* by default */
break;
}
/* Set upscaling sharpness */
if (path_is_valid(upscaling_path))
upscaling_success = filestream_write_file(
upscaling_path, sharpness_str, 1);
else
upscaling_success = false;
/* Set downscaling sharpness */
if (path_is_valid(downscaling_path))
downscaling_success = filestream_write_file(
downscaling_path, sharpness_str, 1);
else
downscaling_success = false;
return (upscaling_success && downscaling_success);
}
/* Fetches internal battery level */
int dingux_get_battery_level(void)
{

View File

@ -25,6 +25,19 @@
RETRO_BEGIN_DECLS
/* Specifies all possible image filtering
* methods when using the IPU hardware scaler
* > Note: We do not allow 'fine tuning' of the
* bicubic sharpness factor, since anything
* other than the default value looks terrible... */
enum dingux_ipu_filter_type
{
DINGUX_IPU_FILTER_BICUBIC = 0,
DINGUX_IPU_FILTER_BILINEAR,
DINGUX_IPU_FILTER_NEAREST,
DINGUX_IPU_FILTER_LAST
};
/* Enables/disables downscaling when using
* the IPU hardware scaler */
bool dingux_ipu_set_downscaling_enable(bool enable);
@ -36,9 +49,13 @@ bool dingux_ipu_set_downscaling_enable(bool enable);
bool dingux_ipu_set_aspect_ratio_enable(bool enable);
/* Enables/disables integer scaling when
* when using the IPU hardware scaler */
* using the IPU hardware scaler */
bool dingux_ipu_set_integer_scaling_enable(bool enable);
/* Sets the image filtering method when
* using the IPU hardware scaler */
bool dingux_ipu_set_filter_type(enum dingux_ipu_filter_type filter_type);
/* Fetches internal battery level */
int dingux_get_battery_level(void);

View File

@ -55,12 +55,14 @@ typedef struct sdl_dingux_video
SDL_Surface *screen;
unsigned frame_width;
unsigned frame_height;
enum dingux_ipu_filter_type filter_type;
uint32_t font_colour32;
uint16_t font_colour16;
uint16_t menu_texture[SDL_DINGUX_MENU_WIDTH * SDL_DINGUX_MENU_HEIGHT];
bool font_lut[SDL_DINGUX_NUM_FONT_GLYPHS][FONT_WIDTH * FONT_HEIGHT];
bool rgb32;
bool vsync;
bool keep_aspect;
bool integer_scaling;
bool menu_active;
bool was_in_menu;
@ -313,8 +315,14 @@ static void sdl_dingux_gfx_free(void *data)
/* It is good manners to leave IPU scaling
* parameters in the default state when
* shutting down */
dingux_ipu_set_aspect_ratio_enable(true);
dingux_ipu_set_integer_scaling_enable(false);
if (!vid->keep_aspect)
dingux_ipu_set_aspect_ratio_enable(true);
if (vid->integer_scaling)
dingux_ipu_set_integer_scaling_enable(false);
if (vid->filter_type != DINGUX_IPU_FILTER_BICUBIC)
dingux_ipu_set_filter_type(DINGUX_IPU_FILTER_BICUBIC);
free(vid);
}
@ -322,18 +330,21 @@ static void sdl_dingux_gfx_free(void *data)
static void *sdl_dingux_gfx_init(const video_info_t *video,
input_driver_t **input, void **input_data)
{
sdl_dingux_video_t *vid = NULL;
settings_t *settings = config_get_ptr();
bool ipu_keep_aspect = settings->bools.video_dingux_ipu_keep_aspect;
bool ipu_integer_scaling = settings->bools.video_scale_integer;
const char *input_joypad_driver = settings->arrays.input_joypad_driver;
uint32_t surface_flags = (video->vsync) ?
sdl_dingux_video_t *vid = NULL;
settings_t *settings = config_get_ptr();
bool ipu_keep_aspect = settings->bools.video_dingux_ipu_keep_aspect;
bool ipu_integer_scaling = settings->bools.video_scale_integer;
enum dingux_ipu_filter_type ipu_filter_type = (enum dingux_ipu_filter_type)
settings->uints.video_dingux_ipu_filter_type;
const char *input_joypad_driver = settings->arrays.input_joypad_driver;
uint32_t surface_flags = (video->vsync) ?
(SDL_HWSURFACE | SDL_TRIPLEBUF | SDL_FULLSCREEN) :
(SDL_HWSURFACE | SDL_FULLSCREEN);
dingux_ipu_set_downscaling_enable(true);
dingux_ipu_set_aspect_ratio_enable(ipu_keep_aspect);
dingux_ipu_set_integer_scaling_enable(ipu_integer_scaling);
dingux_ipu_set_filter_type(ipu_filter_type);
if (SDL_WasInit(0) == 0)
{
@ -362,7 +373,9 @@ static void *sdl_dingux_gfx_init(const video_info_t *video,
vid->frame_height = SDL_DINGUX_MENU_HEIGHT;
vid->rgb32 = video->rgb32;
vid->vsync = video->vsync;
vid->keep_aspect = ipu_keep_aspect;
vid->integer_scaling = ipu_integer_scaling;
vid->filter_type = ipu_filter_type;
vid->menu_active = false;
vid->was_in_menu = false;
vid->quitting = false;
@ -688,17 +701,40 @@ static void sdl_dingux_gfx_viewport_info(void *data, struct video_viewport *vp)
static void sdl_dingux_set_filtering(void *data, unsigned index, bool smooth, bool ctx_scaling)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
settings_t *settings = config_get_ptr();
enum dingux_ipu_filter_type ipu_filter_type = (settings) ?
(enum dingux_ipu_filter_type)settings->uints.video_dingux_ipu_filter_type :
DINGUX_IPU_FILTER_BICUBIC;
if (!vid || !settings)
return;
/* Update IPU filter setting, if required */
if (vid->filter_type != ipu_filter_type)
{
dingux_ipu_set_filter_type(ipu_filter_type);
vid->filter_type = ipu_filter_type;
}
}
static void sdl_dingux_apply_state_changes(void *data)
{
sdl_dingux_video_t *vid = (sdl_dingux_video_t*)data;
settings_t *settings = config_get_ptr();
bool ipu_keep_aspect = (settings) ? settings->bools.video_dingux_ipu_keep_aspect : true;
bool ipu_integer_scaling = (settings) ? settings->bools.video_scale_integer : false;
if (!vid || !settings)
return;
/* Update 'keep aspect ratio' state, if required */
if (vid->keep_aspect != ipu_keep_aspect)
{
dingux_ipu_set_aspect_ratio_enable(ipu_keep_aspect);
vid->keep_aspect = ipu_keep_aspect;
}
/* Update integer scaling state, if required */
if (vid->integer_scaling != ipu_integer_scaling)
{

View File

@ -3001,6 +3001,10 @@ MSG_HASH(
MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT,
"video_dingux_ipu_keep_aspect"
)
MSG_HASH(
MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE,
"video_dingux_ipu_filter_type"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION,

View File

@ -1352,6 +1352,28 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SMOOTH,
"Adds a slight blur to the image to take the edge off of the hard pixel edges. This option has very little impact on performance."
)
#if defined(DINGUX)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_TYPE,
"Image Interpolation"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_DINGUX_IPU_FILTER_TYPE,
"Specifies image interpolation method when scaling content via the internal IPU. 'Bicubic' or 'Bilinear' is recommended when using CPU-powered video filters. This option has no performance impact."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BICUBIC,
"Bicubic"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BILINEAR,
"Bilinear"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_NEAREST,
"Nearest Neighbour"
)
#endif
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DELAY,
"Auto-Shader Delay"

View File

@ -809,6 +809,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_disc_information,
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_aspect_ratio, MENU_ENUM_SUBLABEL_VIDEO_ASPECT_RATIO)
#if defined(DINGUX)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_ipu_keep_aspect, MENU_ENUM_SUBLABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_dingux_ipu_filter_type, MENU_ENUM_SUBLABEL_VIDEO_DINGUX_IPU_FILTER_TYPE)
#endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_viewport_custom_height, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_viewport_custom_width, MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH)
@ -1806,6 +1807,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_dingux_ipu_keep_aspect);
break;
case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_dingux_ipu_filter_type);
break;
#endif
case MENU_ENUM_LABEL_CORE_INFORMATION:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_information);

View File

@ -5694,6 +5694,12 @@ unsigned menu_displaylist_build_list(
MENU_ENUM_LABEL_VIDEO_CTX_SCALING,
PARSE_ONLY_BOOL, false) == 0)
count++;
#if defined(DINGUX)
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE,
PARSE_ONLY_UINT, false) == 0)
count++;
#endif
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_SHADER_DELAY,
PARSE_ONLY_UINT, false) == 0)

View File

@ -5075,6 +5075,38 @@ static void setting_get_string_representation_uint_video_3ds_display_mode(
}
#endif
#if defined(DINGUX)
static void setting_get_string_representation_uint_video_dingux_ipu_filter_type(
rarch_setting_t *setting,
char *s, size_t len)
{
if (!setting)
return;
switch (*setting->value.target.unsigned_integer)
{
case DINGUX_IPU_FILTER_BICUBIC:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BICUBIC),
len);
break;
case DINGUX_IPU_FILTER_BILINEAR:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BILINEAR),
len);
break;
case DINGUX_IPU_FILTER_NEAREST:
strlcpy(s,
msg_hash_to_str(
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_NEAREST),
len);
break;
}
}
#endif
/* A protected driver is such that the user cannot set to "null" using the UI.
* Can prevent the user from locking him/herself out of the program. */
static bool setting_is_protected_driver(rarch_setting_t *setting)
@ -7126,13 +7158,11 @@ static void general_write_handler(rarch_setting_t *setting)
break;
case MENU_ENUM_LABEL_VIDEO_SMOOTH:
case MENU_ENUM_LABEL_VIDEO_CTX_SCALING:
#if defined(DINGUX)
case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE:
#endif
video_driver_set_filtering(1, settings->bools.video_ctx_scaling, settings->bools.video_ctx_scaling);
break;
#if defined(DINGUX)
case MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_KEEP_ASPECT:
dingux_ipu_set_aspect_ratio_enable(*setting->value.target.boolean);
break;
#endif
case MENU_ENUM_LABEL_VIDEO_ROTATION:
{
rarch_system_info_t *system = runloop_get_system_info();
@ -10506,6 +10536,10 @@ static bool setting_append_list(
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(
list,
list_info,
CMD_EVENT_VIDEO_APPLY_STATE_CHANGES);
}
#endif
@ -10699,22 +10733,46 @@ static bool setting_append_list(
menu_settings_list_current_add_range(list, list_info, 0, 24, 1, true, true);
#endif
CONFIG_BOOL(
list, list_info,
&settings->bools.video_smooth,
MENU_ENUM_LABEL_VIDEO_SMOOTH,
MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH,
DEFAULT_VIDEO_SMOOTH,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE
);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);
#if defined(DINGUX)
if (string_is_equal(settings->arrays.video_driver, "sdl_dingux"))
{
CONFIG_UINT(
list, list_info,
&settings->uints.video_dingux_ipu_filter_type,
MENU_ENUM_LABEL_VIDEO_DINGUX_IPU_FILTER_TYPE,
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_TYPE,
DEFAULT_DINGUX_IPU_FILTER_TYPE,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_video_dingux_ipu_filter_type;
menu_settings_list_current_add_range(list, list_info, 0, DINGUX_IPU_FILTER_LAST - 1, 1, true, true);
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
}
else
#endif
{
CONFIG_BOOL(
list, list_info,
&settings->bools.video_smooth,
MENU_ENUM_LABEL_VIDEO_SMOOTH,
MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH,
DEFAULT_VIDEO_SMOOTH,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE
);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);
}
#ifdef HAVE_ODROIDGO2
CONFIG_BOOL(

View File

@ -2332,6 +2332,11 @@ enum msg_hash_enums
MENU_LABEL(VIDEO_ASPECT_RATIO_INDEX),
#if defined(DINGUX)
MENU_LABEL(VIDEO_DINGUX_IPU_KEEP_ASPECT),
MENU_LABEL(VIDEO_DINGUX_IPU_FILTER_TYPE),
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BICUBIC,
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_BILINEAR,
MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_IPU_FILTER_NEAREST,
#endif
MENU_LABEL(VIDEO_VFILTER),
MENU_LABEL(VIDEO_GPU_RECORD),