Move menu_display code to gfx_display

This commit is contained in:
twinaphex 2020-02-17 00:42:49 +01:00
parent 550e8fff6b
commit 6b82089d6c
8 changed files with 456 additions and 441 deletions

View File

@ -1282,7 +1282,7 @@ static void gfx_animation_update_time(
* for some users - so play it safe. Users can always
* set ticker speed to 2x if they prefer)
* Note 2: GLUI uses the new DPI scaling system,
* so scaling multiplier is menu_display_get_dpi_scale()
* so scaling multiplier is gfx_display_get_dpi_scale()
* multiplied by a small correction factor (since the
* default 1.0x speed is just a little faster than the
* non-smooth ticker)

View File

@ -18,10 +18,27 @@
#include "gfx_animation.h"
#include "video_coord_array.h"
#include "../configuration.h"
#include "../verbosity.h"
#define PARTICLES_COUNT 100
/* Number of pixels corner-to-corner on a 1080p
* display:
* > sqrt((1920 * 1920) + (1080 * 1080))
* Note: This is a double, so no suffix */
#define DIAGONAL_PIXELS_1080P 2202.90717008229831581901
/* Standard reference DPI value, used when determining
* DPI-aware menu scaling factors */
#define REFERENCE_DPI 96.0f
/* 'OZONE_SIDEBAR_WIDTH' must be kept in sync
* with ozone menu driver metrics */
#define OZONE_SIDEBAR_WIDTH 408
float osk_dark[16] = {
0.00, 0.00, 0.00, 0.85,
0.00, 0.00, 0.00, 0.85,
@ -44,6 +61,7 @@ static unsigned gfx_display_header_height = 0;
static bool gfx_display_msg_force = false;
static bool gfx_display_framebuf_dirty = false;
static enum menu_driver_id_type menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static video_coord_array_t menu_disp_ca;
@ -167,6 +185,378 @@ static INLINE float gfx_display_randf(float min, float max)
return (rand() * ((max - min) / RAND_MAX)) + min;
}
void gfx_display_set_driver_id(enum menu_driver_id_type type)
{
menu_driver_id = type;
}
enum menu_driver_id_type gfx_display_get_driver_id(void)
{
return menu_driver_id;
}
static float gfx_display_get_adjusted_scale_internal(
float base_scale, float scale_factor, unsigned width)
{
/* Apply user-set scaling factor */
float adjusted_scale = base_scale * scale_factor;
/* Ozone has a capped scale factor */
adjusted_scale = (menu_driver_id == MENU_DRIVER_ID_OZONE) ?
(((float)OZONE_SIDEBAR_WIDTH * adjusted_scale) > ((float)width * 0.3333333f) ?
((float)width * 0.3333333f / (float)OZONE_SIDEBAR_WIDTH) : adjusted_scale) :
adjusted_scale;
/* Ensure final scale is 'sane' */
return (adjusted_scale > 0.0001f) ? adjusted_scale : 1.0f;
}
float gfx_display_get_dpi_scale_internal(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
float diagonal_pixels;
float pixel_scale;
float dpi;
gfx_ctx_metrics_t metrics;
if (scale_cached &&
(width == last_width) &&
(height == last_height))
return scale;
/* Determine the diagonal 'size' of the display
* (or window) in terms of pixels */
diagonal_pixels = (float)sqrt(
(double)((width * width) + (height * height)));
/* TODO/FIXME: On Mac, calling video_context_driver_get_metrics()
* here causes RetroArch to crash (EXC_BAD_ACCESS). This is
* unfortunate, and needs to be fixed at the gfx context driver
* level. Until this is done, all we can do is fallback to using
* the old legacy 'magic number' scaling on Mac platforms. */
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
if (true)
{
scale = (diagonal_pixels / 6.5f) / 212.0f;
scale_cached = true;
last_width = width;
last_height = height;
return scale;
}
#endif
/* Get pixel scale relative to baseline 1080p display */
pixel_scale = diagonal_pixels / DIAGONAL_PIXELS_1080P;
/* Attempt to get display DPI */
metrics.type = DISPLAY_METRIC_DPI;
metrics.value = &dpi;
if (video_context_driver_get_metrics(&metrics) && (dpi > 0.0f))
{
float display_size;
float dpi_scale;
#if defined(ANDROID) || defined(HAVE_COCOATOUCH)
/* Android/iOS devices tell complete lies when
* reporting DPI values. From the Android devices
* I've had access to, the DPI is generally
* overestimated by 17%. All we can do is apply
* a blind correction factor... */
dpi = dpi * 0.83f;
#endif
/* Note: If we are running in windowed mode, this
* 'display size' is actually the window size - which
* kinda makes a mess of everything. Since we cannot
* get fullscreen resolution when running in windowed
* mode, there is nothing we can do about this. So just
* treat the window as a display, and hope for the best... */
display_size = diagonal_pixels / dpi;
dpi_scale = dpi / REFERENCE_DPI;
/* Note: We have tried leveraging every possible metric
* (and numerous studies on TV/monitor/mobile device
* usage habits) to determine an appropriate auto scaling
* factor. *None of these 'smart'/technical methods work
* consistently in the real world* - there is simply too
* much variance.
* So instead we have implemented a very fuzzy/loose
* method which is crude as can be, but actually has
* some semblance of usability... */
if (display_size > 24.0f)
{
/* DPI scaling fails miserably when using large
* displays. Having a UI element that's 1 inch high
* on all screens might seem like a good idea - until
* you realise that a HTPC user is probably sitting
* several metres from their TV, which makes something
* 1 inch high virtually invisible.
* So we make some assumptions:
* - Normal size displays <= 24 inches are probably
* PC monitors, with an eye-to-screen distance of
* 1 arm length. Under these conditions, fixed size
* (DPI scaled) UI elements should be visible for most
* users
* - Large displays > 24 inches start to encroach on
* TV territory. Once we start working with TVs, we
* have to consider users sitting on a couch - and
* in this situation, we fall back to the age-old
* standard of UI elements occupying a fixed fraction
* of the display size (i.e. just look at the menu of
* any console system for the past decade)
* - 24 -> 32 inches is a grey area, where the display
* might be a monitor or a TV. Above 32 inches, a TV
* is almost a certainty. So we simply lerp between
* dpi scaling and pixel scaling as the display size
* increases from 24 to 32 */
float fraction = (display_size > 32.0f) ? 32.0f : display_size;
fraction = fraction - 24.0f;
fraction = fraction / (32.0f - 24.0f);
scale = ((1.0f - fraction) * dpi_scale) + (fraction * pixel_scale);
}
else if (display_size < 12.0f)
{
/* DPI scaling also fails when using very small
* displays - i.e. mobile devices (tablets/phones).
* That 1 inch UI element is going to look pretty
* dumb on a 5 inch screen in landscape orientation...
* We're essentially in the opposite situation to the
* TV case above, and it turns out that a similar
* solution provides relief: as screen size reduces
* from 12 inches to zero, we lerp from dpi scaling
* to pixel scaling */
float fraction = display_size / 12.0f;
scale = ((1.0f - fraction) * pixel_scale) + (fraction * dpi_scale);
}
else
scale = dpi_scale;
}
/* If DPI retrieval is unsupported, all we can do
* is use the raw pixel scale */
else
scale = pixel_scale;
scale_cached = true;
last_width = width;
last_height = height;
return scale;
}
float gfx_display_get_dpi_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
float menu_scale_factor = settings->floats.menu_scale_factor;
/* Scale is based on display metrics - these are a fixed
* hardware property. To minimise performance overheads
* we therefore only call video_context_driver_get_metrics()
* on first run, or when the current video resolution changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
scale = gfx_display_get_dpi_scale_internal(width, height);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = gfx_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
float gfx_display_get_widget_dpi_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
/* When using RGUI, settings->floats.menu_scale_factor
* is ignored
* > If we are not using a widget scale factor override,
* just set menu_scale_factor to 1.0 */
float menu_scale_factor =
settings->bools.menu_widget_scale_auto ?
((menu_driver_id == MENU_DRIVER_ID_RGUI) ?
1.0f : settings->floats.menu_scale_factor) :
settings->floats.menu_widget_scale_factor;
/* Scale is based on display metrics - these are a fixed
* hardware property. To minimise performance overheads
* we therefore only call video_context_driver_get_metrics()
* on first run, or when the current video resolution changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
scale = gfx_display_get_dpi_scale_internal(width, height);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = gfx_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
float gfx_display_get_widget_pixel_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
/* When using RGUI, settings->floats.menu_scale_factor
* is ignored
* > If we are not using a widget scale factor override,
* just set menu_scale_factor to 1.0 */
float menu_scale_factor =
settings->bools.menu_widget_scale_auto ?
((menu_driver_id == MENU_DRIVER_ID_RGUI) ?
1.0f : settings->floats.menu_scale_factor) :
settings->floats.menu_widget_scale_factor;
/* We need to perform a square root here, which
* can be slow on some platforms (not *slow*, but
* it involves enough work that it's worth trying
* to optimise). We therefore cache the pixel scale,
* and only update on first run or when the video
* size changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
/* Baseline reference is a 1080p display */
scale = (float)(
sqrt((double)((width * width) + (height * height))) /
DIAGONAL_PIXELS_1080P);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = gfx_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
/* Ugh... Since we must now have independent scale
* factors for menus and widgets, and most of the internal
* scaling variables are cached/static, a huge amount of
* code duplication is required for the pixel_scale and
* dpi_scale functions. A necessary evil, I suppose... */
#if 0
static float gfx_display_get_pixel_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
float menu_scale_factor = settings->floats.menu_scale_factor;
/* We need to perform a square root here, which
* can be slow on some platforms (not *slow*, but
* it involves enough work that it's worth trying
* to optimise). We therefore cache the pixel scale,
* and only update on first run or when the video
* size changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
/* Baseline reference is a 1080p display */
scale = (float)(
sqrt((double)((width * width) + (height * height))) /
DIAGONAL_PIXELS_1080P);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = gfx_display_get_adjusted_scale_internal(
scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
#endif
/* Check if the current menu driver is compatible
* with your video driver. */

View File

@ -50,6 +50,18 @@ RETRO_BEGIN_DECLS
/* TODO/FIXME - global, not thread-safe */
extern float osk_dark[16];
enum menu_driver_id_type
{
MENU_DRIVER_ID_UNKNOWN = 0,
MENU_DRIVER_ID_RGUI,
MENU_DRIVER_ID_OZONE,
MENU_DRIVER_ID_GLUI,
MENU_DRIVER_ID_XMB,
MENU_DRIVER_ID_XUI,
MENU_DRIVER_ID_STRIPES
};
enum gfx_display_prim_type
{
GFX_DISPLAY_PRIM_NONE = 0,
@ -316,6 +328,15 @@ bool gfx_display_reset_textures_list_buffer(
int gfx_display_osk_ptr_at_pos(void *data, int x, int y,
unsigned width, unsigned height);
enum menu_driver_id_type gfx_display_get_driver_id(void);
void gfx_display_set_driver_id(enum menu_driver_id_type type);
float gfx_display_get_dpi_scale(unsigned width, unsigned height);
float gfx_display_get_widget_dpi_scale(unsigned width, unsigned height);
float gfx_display_get_widget_pixel_scale(unsigned width, unsigned height);
void gfx_display_allocate_white_texture(void);

View File

@ -2287,7 +2287,7 @@ static void materialui_render(void *data,
/* Check whether screen dimensions, menu scale
* factor or layout optimisation settings have changed */
scale_factor = menu_display_get_dpi_scale(width, height);
scale_factor = gfx_display_get_dpi_scale(width, height);
if ((scale_factor != mui->last_scale_factor) ||
(width != mui->last_width) ||
@ -5592,7 +5592,7 @@ static void materialui_menu_animation_update_time(
float *dst,
unsigned video_width, unsigned video_height)
{
*(dst) *= menu_display_get_dpi_scale(video_width, video_height) * 0.8f;
*(dst) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.8f;
}
static void *materialui_init(void **userdata, bool video_is_threaded)
@ -5627,7 +5627,7 @@ static void *materialui_init(void **userdata, bool video_is_threaded)
mui->last_width = width;
mui->last_height = height;
mui->last_scale_factor = menu_display_get_dpi_scale(width, height);
mui->last_scale_factor = gfx_display_get_dpi_scale(width, height);
mui->dip_base_unit_size = mui->last_scale_factor * MUI_DIP_BASE_UNIT_SIZE;
mui->need_compute = false;

View File

@ -129,7 +129,7 @@ static void ozone_menu_animation_update_time(
float *dst,
unsigned video_width, unsigned video_height)
{
*(dst) *= menu_display_get_dpi_scale(video_width, video_height) * 0.5f;
*(dst) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.5f;
}
@ -161,7 +161,7 @@ static void *ozone_init(void **userdata, bool video_is_threaded)
ozone->last_width = width;
ozone->last_height = height;
ozone->last_scale_factor = menu_display_get_dpi_scale(width, height);
ozone->last_scale_factor = gfx_display_get_dpi_scale(width, height);
ozone->selection_buf_old = (file_list_t*)calloc(1, sizeof(file_list_t));
@ -1102,7 +1102,7 @@ static void ozone_render(void *data,
/* Check whether screen dimensions or menu scale
* factor have changed */
scale_factor = menu_display_get_dpi_scale(width, height);
scale_factor = gfx_display_get_dpi_scale(width, height);
if ((scale_factor != ozone->last_scale_factor) ||
(width != ozone->last_width) ||

View File

@ -1913,9 +1913,7 @@ static void menu_driver_set_id(void)
{
const char *driver_name = NULL;
#ifdef HAVE_MENU_WIDGETS
menu_widgets_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
#endif
gfx_display_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
if (!menu_driver_ctx || !menu_driver_ctx->ident)
return;
@ -1925,27 +1923,23 @@ static void menu_driver_set_id(void)
if (string_is_empty(driver_name))
return;
#ifdef HAVE_MENU_WIDGETS
if (string_is_equal(driver_name, "rgui"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_RGUI);
gfx_display_set_driver_id(MENU_DRIVER_ID_RGUI);
else if (string_is_equal(driver_name, "ozone"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_OZONE);
gfx_display_set_driver_id(MENU_DRIVER_ID_OZONE);
else if (string_is_equal(driver_name, "glui"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_GLUI);
gfx_display_set_driver_id(MENU_DRIVER_ID_GLUI);
else if (string_is_equal(driver_name, "xmb"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_XMB);
gfx_display_set_driver_id(MENU_DRIVER_ID_XMB);
else if (string_is_equal(driver_name, "xui"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_XUI);
gfx_display_set_driver_id(MENU_DRIVER_ID_XUI);
else if (string_is_equal(driver_name, "stripes"))
menu_widgets_set_driver_id(MENU_DRIVER_ID_STRIPES);
#endif
gfx_display_set_driver_id(MENU_DRIVER_ID_STRIPES);
}
static bool menu_driver_init_internal(bool video_is_threaded)
{
#ifdef HAVE_MENU_WIDGETS
menu_widgets_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
#endif
gfx_display_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
if (menu_driver_ctx->init)
{
@ -2177,9 +2171,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
free(menu_userdata);
menu_userdata = NULL;
#ifdef HAVE_MENU_WIDGETS
menu_widgets_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
#endif
gfx_display_set_driver_id(MENU_DRIVER_ID_UNKNOWN);
#ifndef HAVE_DYNAMIC
if (frontend_driver_has_fork())

View File

@ -30,7 +30,6 @@
#include "../../accessibility.h"
#endif
#include "../../configuration.h"
#include "../../msg_hash.h"
#include "../../tasks/task_content.h"
@ -39,23 +38,6 @@
#include "../../gfx/gfx_display.h"
#include "../../gfx/font_driver.h"
#include "../menu_driver.h"
/* Number of pixels corner-to-corner on a 1080p
* display:
* > sqrt((1920 * 1920) + (1080 * 1080))
* Note: This is a double, so no suffix */
#define DIAGONAL_PIXELS_1080P 2202.90717008229831581901
/* Standard reference DPI value, used when determining
* DPI-aware menu scaling factors */
#define REFERENCE_DPI 96.0f
/* 'OZONE_SIDEBAR_WIDTH' must be kept in sync
* with ozone menu driver metrics */
#define OZONE_SIDEBAR_WIDTH 408
/* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */
static float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(0x3A3A3A, 1.0f);
@ -114,6 +96,7 @@ static unsigned cheevo_width = 0;
static unsigned cheevo_height = 0;
#endif
#ifdef HAVE_MENU
/* Load content animation */
#define ANIMATION_LOAD_CONTENT_DURATION 333
@ -133,6 +116,10 @@ static float load_content_animation_final_fade_alpha;
static gfx_timer_t load_content_animation_end_timer;
static unsigned load_content_animation_icon_size_initial;
static unsigned load_content_animation_icon_size_target;
#endif
static float menu_widgets_backdrop_orig[16] = {
0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75,
@ -333,386 +320,12 @@ static unsigned msg_queue_task_hourglass_x;
/* Used for both generic and libretro messages */
static unsigned generic_message_height;
static unsigned load_content_animation_icon_size_initial;
static unsigned load_content_animation_icon_size_target;
static unsigned divider_width_1px;
static unsigned last_video_width;
static unsigned last_video_height;
static float last_scale_factor;
static enum menu_driver_id_type menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
void menu_widgets_set_driver_id(enum menu_driver_id_type type)
{
menu_driver_id = type;
}
static float menu_display_get_adjusted_scale_internal(
float base_scale, float scale_factor, unsigned width)
{
/* Apply user-set scaling factor */
float adjusted_scale = base_scale * scale_factor;
/* Ozone has a capped scale factor */
adjusted_scale = (menu_driver_id == MENU_DRIVER_ID_OZONE) ?
(((float)OZONE_SIDEBAR_WIDTH * adjusted_scale) > ((float)width * 0.3333333f) ?
((float)width * 0.3333333f / (float)OZONE_SIDEBAR_WIDTH) : adjusted_scale) :
adjusted_scale;
/* Ensure final scale is 'sane' */
return (adjusted_scale > 0.0001f) ? adjusted_scale : 1.0f;
}
float menu_display_get_dpi_scale_internal(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
float diagonal_pixels;
float pixel_scale;
float dpi;
gfx_ctx_metrics_t metrics;
if (scale_cached &&
(width == last_width) &&
(height == last_height))
return scale;
/* Determine the diagonal 'size' of the display
* (or window) in terms of pixels */
diagonal_pixels = (float)sqrt(
(double)((width * width) + (height * height)));
/* TODO/FIXME: On Mac, calling video_context_driver_get_metrics()
* here causes RetroArch to crash (EXC_BAD_ACCESS). This is
* unfortunate, and needs to be fixed at the gfx context driver
* level. Until this is done, all we can do is fallback to using
* the old legacy 'magic number' scaling on Mac platforms. */
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
if (true)
{
scale = (diagonal_pixels / 6.5f) / 212.0f;
scale_cached = true;
last_width = width;
last_height = height;
return scale;
}
#endif
/* Get pixel scale relative to baseline 1080p display */
pixel_scale = diagonal_pixels / DIAGONAL_PIXELS_1080P;
/* Attempt to get display DPI */
metrics.type = DISPLAY_METRIC_DPI;
metrics.value = &dpi;
if (video_context_driver_get_metrics(&metrics) && (dpi > 0.0f))
{
float display_size;
float dpi_scale;
#if defined(ANDROID) || defined(HAVE_COCOATOUCH)
/* Android/iOS devices tell complete lies when
* reporting DPI values. From the Android devices
* I've had access to, the DPI is generally
* overestimated by 17%. All we can do is apply
* a blind correction factor... */
dpi = dpi * 0.83f;
#endif
/* Note: If we are running in windowed mode, this
* 'display size' is actually the window size - which
* kinda makes a mess of everything. Since we cannot
* get fullscreen resolution when running in windowed
* mode, there is nothing we can do about this. So just
* treat the window as a display, and hope for the best... */
display_size = diagonal_pixels / dpi;
dpi_scale = dpi / REFERENCE_DPI;
/* Note: We have tried leveraging every possible metric
* (and numerous studies on TV/monitor/mobile device
* usage habits) to determine an appropriate auto scaling
* factor. *None of these 'smart'/technical methods work
* consistently in the real world* - there is simply too
* much variance.
* So instead we have implemented a very fuzzy/loose
* method which is crude as can be, but actually has
* some semblance of usability... */
if (display_size > 24.0f)
{
/* DPI scaling fails miserably when using large
* displays. Having a UI element that's 1 inch high
* on all screens might seem like a good idea - until
* you realise that a HTPC user is probably sitting
* several metres from their TV, which makes something
* 1 inch high virtually invisible.
* So we make some assumptions:
* - Normal size displays <= 24 inches are probably
* PC monitors, with an eye-to-screen distance of
* 1 arm length. Under these conditions, fixed size
* (DPI scaled) UI elements should be visible for most
* users
* - Large displays > 24 inches start to encroach on
* TV territory. Once we start working with TVs, we
* have to consider users sitting on a couch - and
* in this situation, we fall back to the age-old
* standard of UI elements occupying a fixed fraction
* of the display size (i.e. just look at the menu of
* any console system for the past decade)
* - 24 -> 32 inches is a grey area, where the display
* might be a monitor or a TV. Above 32 inches, a TV
* is almost a certainty. So we simply lerp between
* dpi scaling and pixel scaling as the display size
* increases from 24 to 32 */
float fraction = (display_size > 32.0f) ? 32.0f : display_size;
fraction = fraction - 24.0f;
fraction = fraction / (32.0f - 24.0f);
scale = ((1.0f - fraction) * dpi_scale) + (fraction * pixel_scale);
}
else if (display_size < 12.0f)
{
/* DPI scaling also fails when using very small
* displays - i.e. mobile devices (tablets/phones).
* That 1 inch UI element is going to look pretty
* dumb on a 5 inch screen in landscape orientation...
* We're essentially in the opposite situation to the
* TV case above, and it turns out that a similar
* solution provides relief: as screen size reduces
* from 12 inches to zero, we lerp from dpi scaling
* to pixel scaling */
float fraction = display_size / 12.0f;
scale = ((1.0f - fraction) * pixel_scale) + (fraction * dpi_scale);
}
else
scale = dpi_scale;
}
/* If DPI retrieval is unsupported, all we can do
* is use the raw pixel scale */
else
scale = pixel_scale;
scale_cached = true;
last_width = width;
last_height = height;
return scale;
}
float menu_display_get_dpi_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
float menu_scale_factor = settings->floats.menu_scale_factor;
/* Scale is based on display metrics - these are a fixed
* hardware property. To minimise performance overheads
* we therefore only call video_context_driver_get_metrics()
* on first run, or when the current video resolution changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
scale = menu_display_get_dpi_scale_internal(width, height);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = menu_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
#ifdef HAVE_MENU_WIDGETS
static float menu_display_get_widget_dpi_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
/* When using RGUI, settings->floats.menu_scale_factor
* is ignored
* > If we are not using a widget scale factor override,
* just set menu_scale_factor to 1.0 */
float menu_scale_factor =
settings->bools.menu_widget_scale_auto ?
((menu_driver_id == MENU_DRIVER_ID_RGUI) ?
1.0f : settings->floats.menu_scale_factor) :
settings->floats.menu_widget_scale_factor;
/* Scale is based on display metrics - these are a fixed
* hardware property. To minimise performance overheads
* we therefore only call video_context_driver_get_metrics()
* on first run, or when the current video resolution changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
scale = menu_display_get_dpi_scale_internal(width, height);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = menu_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
static float menu_display_get_widget_pixel_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
/* When using RGUI, settings->floats.menu_scale_factor
* is ignored
* > If we are not using a widget scale factor override,
* just set menu_scale_factor to 1.0 */
float menu_scale_factor =
settings->bools.menu_widget_scale_auto ?
((menu_driver_id == MENU_DRIVER_ID_RGUI) ?
1.0f : settings->floats.menu_scale_factor) :
settings->floats.menu_widget_scale_factor;
/* We need to perform a square root here, which
* can be slow on some platforms (not *slow*, but
* it involves enough work that it's worth trying
* to optimise). We therefore cache the pixel scale,
* and only update on first run or when the video
* size changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
/* Baseline reference is a 1080p display */
scale = (float)(
sqrt((double)((width * width) + (height * height))) /
DIAGONAL_PIXELS_1080P);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = menu_display_get_adjusted_scale_internal(scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
#endif
/* Ugh... Since we must now have independent scale
* factors for menus and widgets, and most of the internal
* scaling variables are cached/static, a huge amount of
* code duplication is required for the pixel_scale and
* dpi_scale functions. A necessary evil, I suppose... */
#if 0
static float menu_display_get_pixel_scale(unsigned width, unsigned height)
{
static unsigned last_width = 0;
static unsigned last_height = 0;
static float scale = 0.0f;
static bool scale_cached = false;
bool scale_updated = false;
static float last_menu_scale_factor = 0.0f;
static enum menu_driver_id_type last_menu_driver_id = MENU_DRIVER_ID_UNKNOWN;
static float adjusted_scale = 1.0f;
settings_t *settings = config_get_ptr();
float menu_scale_factor = settings->floats.menu_scale_factor;
/* We need to perform a square root here, which
* can be slow on some platforms (not *slow*, but
* it involves enough work that it's worth trying
* to optimise). We therefore cache the pixel scale,
* and only update on first run or when the video
* size changes */
if (!scale_cached ||
(width != last_width) ||
(height != last_height))
{
/* Baseline reference is a 1080p display */
scale = (float)(
sqrt((double)((width * width) + (height * height))) /
DIAGONAL_PIXELS_1080P);
scale_cached = true;
scale_updated = true;
last_width = width;
last_height = height;
}
/* Adjusted scale calculation may also be slow, so
* only update if something changes */
if (scale_updated ||
(menu_scale_factor != last_menu_scale_factor) ||
(menu_driver_id != last_menu_driver_id))
{
adjusted_scale = menu_display_get_adjusted_scale_internal(
scale, menu_scale_factor, width);
last_menu_scale_factor = menu_scale_factor;
last_menu_driver_id = menu_driver_id;
}
return adjusted_scale;
}
#endif
static void msg_widget_msg_transition_animation_done(void *userdata)
{
menu_widget_msg_t *msg = (menu_widget_msg_t*) userdata;
@ -1267,6 +880,9 @@ static void menu_widgets_hourglass_tick(void *userdata)
/* Forward declaration */
static void menu_widgets_layout(
bool is_threaded, const char *dir_assets, char *font_path);
#ifdef HAVE_MENU
bool menu_driver_get_load_content_animation_data(menu_texture_item *icon, char **playlist_name);
#endif
void menu_widgets_iterate(
unsigned width, unsigned height,
@ -1277,9 +893,9 @@ void menu_widgets_iterate(
/* Check whether screen dimensions or menu scale
* factor have changed */
float scale_factor = (menu_driver_id == MENU_DRIVER_ID_XMB) ?
menu_display_get_widget_pixel_scale(width, height) :
menu_display_get_widget_dpi_scale(width, height);
float scale_factor = (gfx_display_get_driver_id() == MENU_DRIVER_ID_XMB) ?
gfx_display_get_widget_pixel_scale(width, height) :
gfx_display_get_widget_dpi_scale(width, height);
if ((scale_factor != last_scale_factor) ||
(width != last_video_width) ||
@ -1727,6 +1343,7 @@ static void menu_widgets_draw_backdrop(video_frame_info_t *video_info, float alp
static void menu_widgets_draw_load_content_animation(video_frame_info_t *video_info)
{
#ifdef HAVE_MENU
/* TODO: change metrics? */
int icon_size = (int) load_content_animation_icon_size;
uint32_t text_alpha = load_content_animation_fade_alpha * 255.0f;
@ -1773,7 +1390,9 @@ static void menu_widgets_draw_load_content_animation(video_frame_info_t *video_i
font_raster_bold.carr.coords.vertices = 0;
/* Everything disappears */
menu_widgets_draw_backdrop(video_info, load_content_animation_final_fade_alpha);
menu_widgets_draw_backdrop(video_info,
load_content_animation_final_fade_alpha);
#endif
}
void menu_widgets_frame(void *data)
@ -2252,10 +1871,12 @@ void menu_widgets_frame(void *data)
);
}
#ifdef HAVE_MENU
/* Load content animation */
if (load_content_animation_running)
menu_widgets_draw_load_content_animation(video_info);
else
#endif
{
font_driver_flush(video_info->width, video_info->height, font_regular, video_info);
font_driver_flush(video_info->width, video_info->height, font_bold, video_info);
@ -2293,9 +1914,9 @@ bool menu_widgets_init(bool video_is_threaded)
* > XMB uses pixel based scaling - all other drivers
* use DPI based scaling */
video_driver_get_size(&last_video_width, &last_video_height);
last_scale_factor = (menu_driver_id == MENU_DRIVER_ID_XMB) ?
menu_display_get_widget_pixel_scale(last_video_width, last_video_height) :
menu_display_get_widget_dpi_scale(last_video_width, last_video_height);
last_scale_factor = (gfx_display_get_driver_id() == MENU_DRIVER_ID_XMB) ?
gfx_display_get_widget_pixel_scale(last_video_width, last_video_height) :
gfx_display_get_widget_dpi_scale(last_video_width, last_video_height);
return true;
@ -2408,8 +2029,10 @@ static void menu_widgets_layout(
msg_queue_default_rect_width_menu_alive = msg_queue_glyph_width * 40;
msg_queue_default_rect_width = last_video_width - msg_queue_regular_text_start - (2 * simple_widget_padding);
#ifdef HAVE_MENU
load_content_animation_icon_size_initial = LOAD_CONTENT_ANIMATION_INITIAL_ICON_SIZE * last_scale_factor;
load_content_animation_icon_size_target = LOAD_CONTENT_ANIMATION_TARGET_ICON_SIZE * last_scale_factor;
#endif
divider_width_1px = (last_scale_factor > 1.0f) ? (unsigned)(last_scale_factor + 0.5f) : 1;
}
@ -2476,9 +2099,9 @@ void menu_widgets_context_reset(bool is_threaded,
/* Update scaling/dimensions */
last_video_width = width;
last_video_height = height;
last_scale_factor = (menu_driver_id == MENU_DRIVER_ID_XMB) ?
menu_display_get_widget_pixel_scale(last_video_width, last_video_height) :
menu_display_get_widget_dpi_scale(last_video_width, last_video_height);
last_scale_factor = (gfx_display_get_driver_id() == MENU_DRIVER_ID_XMB) ?
gfx_display_get_widget_pixel_scale(last_video_width, last_video_height) :
gfx_display_get_widget_dpi_scale(last_video_width, last_video_height);
menu_widgets_layout(is_threaded, dir_assets, font_path);
video_driver_monitor_reset();
@ -2730,12 +2353,15 @@ static void menu_widgets_end_load_content_animation(void *userdata)
void menu_widgets_cleanup_load_content_animation(void)
{
#ifdef HAVE_MENU
load_content_animation_running = false;
free(load_content_animation_content_name);
#endif
}
void menu_widgets_start_load_content_animation(const char *content_name, bool remove_extension)
{
#ifdef HAVE_MENU
/* TODO: finish the animation based on design, correct all timings */
gfx_animation_ctx_entry_t entry;
gfx_timer_ctx_entry_t timer_entry;
@ -2834,6 +2460,7 @@ void menu_widgets_start_load_content_animation(const char *content_name, bool re
/* Draw all the things */
load_content_animation_running = true;
#endif
}
#ifdef HAVE_CHEEVOS

View File

@ -36,17 +36,6 @@
#define HOURGLASS_DURATION 1000
#define GENERIC_MESSAGE_DURATION 3000
enum menu_driver_id_type
{
MENU_DRIVER_ID_UNKNOWN = 0,
MENU_DRIVER_ID_RGUI,
MENU_DRIVER_ID_OZONE,
MENU_DRIVER_ID_GLUI,
MENU_DRIVER_ID_XMB,
MENU_DRIVER_ID_XUI,
MENU_DRIVER_ID_STRIPES
};
bool menu_widgets_init(bool video_is_threaded);
void menu_widgets_free(void);
@ -105,10 +94,6 @@ void menu_widgets_frame(void *data);
bool menu_widgets_set_fps_text(const char *new_fps_text);
void menu_widgets_set_driver_id(enum menu_driver_id_type type);
float menu_display_get_dpi_scale(unsigned width, unsigned height);
enum menu_driver_id_type menu_driver_ident_id(void);
#endif