mirror of
https://github.com/libretro/RetroArch
synced 2025-02-03 08:54:13 +00:00
Merge pull request #1784 from heuripedes/master
Fix XMB performance regression
This commit is contained in:
commit
ca7982e739
@ -995,12 +995,16 @@ static void xmb_draw_items(xmb_handle_t *xmb, gl_t *gl,
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned width, height;
|
unsigned width, height;
|
||||||
math_matrix_4x4 mymat, mrot, mscal;
|
math_matrix_4x4 mymat, mrot, mscal;
|
||||||
const char *label = NULL;
|
const char *label = NULL;
|
||||||
xmb_node_t *core_node = NULL;
|
xmb_node_t *core_node = NULL;
|
||||||
size_t end = 0;
|
size_t end = 0;
|
||||||
uint64_t frame_count = video_driver_get_frame_count();
|
uint64_t frame_count = video_driver_get_frame_count();
|
||||||
|
char name[PATH_MAX_LENGTH] = {0};
|
||||||
|
char value[PATH_MAX_LENGTH] = {0};
|
||||||
|
menu_entry_t entry = {{0}};
|
||||||
|
menu_handle_t *menu = menu_driver_get_ptr();
|
||||||
|
|
||||||
if (!list || !list->size)
|
if (!list || !list->size || !menu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
video_driver_get_size(&width, &height);
|
video_driver_get_size(&width, &height);
|
||||||
@ -1021,17 +1025,18 @@ static void xmb_draw_items(xmb_handle_t *xmb, gl_t *gl,
|
|||||||
for (i = 0; i < end; i++)
|
for (i = 0; i < end; i++)
|
||||||
{
|
{
|
||||||
float icon_x, icon_y;
|
float icon_x, icon_y;
|
||||||
char name[PATH_MAX_LENGTH] = {0};
|
|
||||||
char value[PATH_MAX_LENGTH] = {0};
|
|
||||||
menu_entry_t entry = {{0}};
|
|
||||||
GLuint texture_switch = 0;
|
GLuint texture_switch = 0;
|
||||||
GLuint icon = 0;
|
GLuint icon = 0;
|
||||||
xmb_node_t * node = (xmb_node_t*)menu_list_get_userdata_at_offset(list, i);
|
xmb_node_t * node = (xmb_node_t*)menu_list_get_userdata_at_offset(list, i);
|
||||||
menu_handle_t *menu = menu_driver_get_ptr();
|
|
||||||
uint32_t hash_label = 0;
|
uint32_t hash_label = 0;
|
||||||
uint32_t hash_value = 0;
|
uint32_t hash_value = 0;
|
||||||
bool do_draw_text = false;
|
bool do_draw_text = false;
|
||||||
|
|
||||||
|
*name = *value = 0;
|
||||||
|
*entry.path = *entry.label = *entry.value = 0;
|
||||||
|
entry.idx = entry.spacing = entry.type = 0;
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -252,48 +252,54 @@ static float easing_out_in_bounce(float t, float b, float c, float d)
|
|||||||
|
|
||||||
void menu_animation_free(animation_t *animation)
|
void menu_animation_free(animation_t *animation)
|
||||||
{
|
{
|
||||||
size_t i;
|
struct tween *t, *tnext;
|
||||||
|
|
||||||
if (!animation)
|
if (!animation)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < animation->size; i++)
|
for (t = animation->alive; t; t = tnext)
|
||||||
{
|
{
|
||||||
if (animation->list[i].subject)
|
tnext = t->next;
|
||||||
animation->list[i].subject = NULL;
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(animation->list);
|
for (t = animation->dead; t; t = tnext)
|
||||||
|
{
|
||||||
|
tnext = t->next;
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
animation->alive = NULL;
|
||||||
|
animation->dead = NULL;
|
||||||
|
animation->allocated = 0;
|
||||||
|
|
||||||
free(animation);
|
free(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tween *menu_animation_get_free_slot(animation_t *animation)
|
static struct tween *menu_animation_get_slot(animation_t *animation)
|
||||||
{
|
{
|
||||||
struct tween *slot = NULL;
|
struct tween *slot = NULL;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < animation->size; ++i)
|
if (!animation->dead)
|
||||||
{
|
{
|
||||||
if (!animation->list[i].alive)
|
size_t count = ((animation->allocated + 1) * 2) - animation->allocated;
|
||||||
{
|
unsigned i;
|
||||||
slot = &animation->list[i];
|
|
||||||
memset(slot, 0, sizeof(*slot));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!slot)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
|
||||||
if (animation->size >= animation->capacity)
|
|
||||||
{
|
{
|
||||||
animation->capacity++;
|
slot = calloc(1, sizeof(struct tween));
|
||||||
animation->list = (struct tween*)realloc(animation->list,
|
slot->next = animation->dead;
|
||||||
animation->capacity * sizeof(struct tween));
|
animation->dead = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
slot = &animation->list[animation->size++];
|
animation->allocated += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slot = animation->dead;
|
||||||
|
animation->dead = slot->next;
|
||||||
|
slot->next = animation->alive;
|
||||||
|
animation->alive = slot;
|
||||||
|
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,16 +308,30 @@ void menu_animation_kill_by_subject(animation_t *animation, size_t count, const
|
|||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
float **sub = (float**)subjects;
|
float **sub = (float**)subjects;
|
||||||
|
|
||||||
for (i = 0; i < animation->size; ++i)
|
struct tween *t, *tnext, *tprev = NULL;
|
||||||
|
for (t = animation->alive; t; t = tnext)
|
||||||
{
|
{
|
||||||
|
bool killed = false;
|
||||||
|
tnext = t->next;
|
||||||
|
|
||||||
for (j = 0; j < count; ++j)
|
for (j = 0; j < count; ++j)
|
||||||
{
|
{
|
||||||
if (animation->list[i].subject == sub[j])
|
if (t->subject == sub[j])
|
||||||
{
|
{
|
||||||
animation->list[i].alive = 0;
|
if (tprev)
|
||||||
animation->list[i].subject = NULL;
|
tprev->next = tnext;
|
||||||
|
else
|
||||||
|
animation->alive = tnext;
|
||||||
|
|
||||||
|
tnext = t->next;
|
||||||
|
t->next = animation->dead;
|
||||||
|
animation->dead = t;
|
||||||
|
killed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!killed)
|
||||||
|
tprev = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,9 +339,8 @@ bool menu_animation_push(animation_t *animation,
|
|||||||
float duration, float target_value, float* subject,
|
float duration, float target_value, float* subject,
|
||||||
enum animation_easing_type easing_enum, tween_cb cb)
|
enum animation_easing_type easing_enum, tween_cb cb)
|
||||||
{
|
{
|
||||||
struct tween *slot = menu_animation_get_free_slot(animation);
|
struct tween *slot = menu_animation_get_slot(animation);
|
||||||
|
|
||||||
slot->alive = 1;
|
|
||||||
slot->duration = duration;
|
slot->duration = duration;
|
||||||
slot->running_since = 0;
|
slot->running_since = 0;
|
||||||
slot->initial_value = *subject;
|
slot->initial_value = *subject;
|
||||||
@ -447,14 +466,13 @@ bool menu_animation_push(animation_t *animation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int menu_animation_iterate(struct tween *tween, float dt,
|
static int menu_animation_iterate(struct tween *tween, float dt,
|
||||||
unsigned *active_tweens)
|
unsigned *active_tweens, bool *dead)
|
||||||
{
|
{
|
||||||
if (!tween)
|
if (!tween)
|
||||||
return -1;
|
return -1;
|
||||||
if (tween->running_since >= tween->duration || !tween->alive)
|
if (tween->running_since >= tween->duration)
|
||||||
{
|
{
|
||||||
tween->alive = 0;
|
*dead = true;
|
||||||
tween->subject = NULL;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,9 +485,11 @@ static int menu_animation_iterate(struct tween *tween, float dt,
|
|||||||
tween->target_value - tween->initial_value,
|
tween->target_value - tween->initial_value,
|
||||||
tween->duration);
|
tween->duration);
|
||||||
|
|
||||||
|
*dead = false;
|
||||||
if (tween->running_since >= tween->duration)
|
if (tween->running_since >= tween->duration)
|
||||||
{
|
{
|
||||||
*tween->subject = tween->target_value;
|
*tween->subject = tween->target_value;
|
||||||
|
*dead = true;
|
||||||
|
|
||||||
if (tween->cb)
|
if (tween->cb)
|
||||||
tween->cb();
|
tween->cb();
|
||||||
@ -487,15 +507,36 @@ bool menu_animation_update(animation_t *animation, float dt)
|
|||||||
unsigned active_tweens = 0;
|
unsigned active_tweens = 0;
|
||||||
menu_handle_t *menu = menu_driver_get_ptr();
|
menu_handle_t *menu = menu_driver_get_ptr();
|
||||||
|
|
||||||
for(i = 0; i < animation->size; i++)
|
struct tween *t, *tnext, *tprev = NULL;
|
||||||
menu_animation_iterate(&animation->list[i], dt, &active_tweens);
|
|
||||||
|
|
||||||
if (!active_tweens)
|
unsigned active = 0;
|
||||||
|
for (t = animation->alive; t; t = tnext)
|
||||||
{
|
{
|
||||||
animation->size = 0;
|
bool dead = false;
|
||||||
return false;
|
tnext = t->next;
|
||||||
|
|
||||||
|
menu_animation_iterate(t, dt, &active_tweens, &dead);
|
||||||
|
|
||||||
|
if (dead)
|
||||||
|
{
|
||||||
|
if (tprev)
|
||||||
|
tprev->next = tnext;
|
||||||
|
else
|
||||||
|
animation->alive = tnext;
|
||||||
|
|
||||||
|
t->next = animation->dead;
|
||||||
|
animation->dead = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tprev = t;
|
||||||
|
active++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!animation->alive)
|
||||||
|
return false;
|
||||||
|
|
||||||
menu->animation_is_active = true;
|
menu->animation_is_active = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -30,7 +30,8 @@ typedef void (*tween_cb) (void);
|
|||||||
|
|
||||||
struct tween
|
struct tween
|
||||||
{
|
{
|
||||||
int alive;
|
struct tween *next;
|
||||||
|
|
||||||
float duration;
|
float duration;
|
||||||
float running_since;
|
float running_since;
|
||||||
float initial_value;
|
float initial_value;
|
||||||
@ -42,10 +43,10 @@ struct tween
|
|||||||
|
|
||||||
typedef struct animation
|
typedef struct animation
|
||||||
{
|
{
|
||||||
struct tween *list;
|
struct tween *alive;
|
||||||
|
struct tween *dead;
|
||||||
|
|
||||||
size_t capacity;
|
size_t allocated;
|
||||||
size_t size;
|
|
||||||
} animation_t;
|
} animation_t;
|
||||||
|
|
||||||
enum animation_easing_type
|
enum animation_easing_type
|
||||||
|
Loading…
x
Reference in New Issue
Block a user