mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-09-06 17:58:39 +00:00
Dont calculate animation easing values multiple times for indentical easing curves
This commit is contained in:
parent
89dbb25b5f
commit
88e18a985d
3 changed files with 62 additions and 6 deletions
|
|
@ -182,6 +182,29 @@ identity_easing_curve(void *p_ UNUSED, double t, monotonic_t duration UNUSED) {
|
|||
return t;
|
||||
}
|
||||
|
||||
bool
|
||||
animations_equal(const Animation *a, const Animation *b) {
|
||||
if (a == b) return true;
|
||||
if (!a || !b) return false;
|
||||
if (a->count != b->count) return false;
|
||||
for (size_t i = 0; i < a->count; i++) {
|
||||
const animation_function *fa = &a->functions[i];
|
||||
const animation_function *fb = &b->functions[i];
|
||||
if (fa->curve != fb->curve || fa->y_at_start != fb->y_at_start || fa->y_size != fb->y_size) return false;
|
||||
if (fa->curve == cubic_bezier_easing_curve) {
|
||||
if (memcmp(fa->params, fb->params, sizeof(BezierParameters)) != 0) return false;
|
||||
} else if (fa->curve == linear_easing_curve) {
|
||||
const LinearParameters *pa = fa->params, *pb = fb->params;
|
||||
if (pa->count != pb->count) return false;
|
||||
if (memcmp(pa->buf, pb->buf, 2 * pa->count * sizeof(double)) != 0) return false;
|
||||
} else if (fa->curve == step_easing_curve) {
|
||||
if (memcmp(fa->params, fb->params, sizeof(StepsParameters)) != 0) return false;
|
||||
}
|
||||
// identity_easing_curve has no params; function-pointer equality above is sufficient
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
double
|
||||
apply_easing_curve(const Animation *a, double val, monotonic_t duration) {
|
||||
val = unit_value(val);
|
||||
|
|
|
|||
|
|
@ -26,3 +26,4 @@ void add_cubic_bezier_animation(Animation *a, double y_at_start, double y_at_end
|
|||
void add_linear_animation(Animation *a, double y_at_start, double y_at_end, size_t count, const double *x, const double *y);
|
||||
void add_steps_animation(Animation *a, double y_at_start, double y_at_end, size_t count, EasingStep step);
|
||||
Animation *free_animation(Animation *a);
|
||||
bool animations_equal(const Animation *a, const Animation *b);
|
||||
|
|
|
|||
|
|
@ -401,6 +401,7 @@ typedef struct CustomShaderGroup {
|
|||
monotonic_t animation_end_duration; // nanoseconds; 0 = no time limit
|
||||
monotonic_t animation_step; // nanoseconds between animation samples
|
||||
Animation *animation_curve; // parsed easing curve; NULL = no animation
|
||||
bool animation_curve_is_shared; // true if animation_curve is owned by an earlier group
|
||||
} CustomShaderGroup;
|
||||
|
||||
typedef struct CustomShaderPipeline {
|
||||
|
|
@ -2364,6 +2365,13 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now)
|
|||
bool backbuffer_is_main = true;
|
||||
bool last_group_rendered = false;
|
||||
|
||||
struct AnimCacheEntry {
|
||||
Animation *curve;
|
||||
monotonic_t started_at, duration;
|
||||
float progress;
|
||||
} anim_cache[MAX_CUSTOM_SHADER_GROUPS];
|
||||
size_t num_anim_cached = 0;
|
||||
|
||||
for (unsigned g = 0; g < num_groups; g++) {
|
||||
const CustomShaderGroup *cg = &custom_shaders.end.groups[g];
|
||||
const bool is_last = (g == num_groups - 1);
|
||||
|
|
@ -2436,11 +2444,24 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now)
|
|||
|
||||
float anim_progress = 0.0f;
|
||||
if (cg->animation_start_events != 0 && cg->animation_end_duration > 0 && os_window->shader_group_anim[g].active) {
|
||||
double elapsed = (double)(now - os_window->shader_group_anim[g].started_at);
|
||||
double t = elapsed / (double)cg->animation_end_duration;
|
||||
if (t < 0.0) t = 0.0;
|
||||
if (t > 1.0) t = 1.0;
|
||||
anim_progress = (float)(cg->animation_curve ? apply_easing_curve(cg->animation_curve, t, cg->animation_end_duration) : t);
|
||||
monotonic_t started_at = os_window->shader_group_anim[g].started_at;
|
||||
bool cached = false;
|
||||
for (size_t c = 0; c < num_anim_cached; c++) {
|
||||
if (anim_cache[c].curve == cg->animation_curve && anim_cache[c].started_at == started_at &&
|
||||
anim_cache[c].duration == cg->animation_end_duration) {
|
||||
anim_progress = anim_cache[c].progress;
|
||||
cached = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cached) {
|
||||
double elapsed = (double)(now - started_at);
|
||||
double t = elapsed / (double)cg->animation_end_duration;
|
||||
if (t < 0.0) t = 0.0;
|
||||
if (t > 1.0) t = 1.0;
|
||||
anim_progress = (float)(cg->animation_curve ? apply_easing_curve(cg->animation_curve, t, cg->animation_end_duration) : t);
|
||||
anim_cache[num_anim_cached++] = (struct AnimCacheEntry){cg->animation_curve, started_at, cg->animation_end_duration, anim_progress};
|
||||
}
|
||||
}
|
||||
glUniform1i(group_loc, (GLint)g);
|
||||
glUniform4f(viewport_loc, vp_x, vp_y, vp_w, vp_h);
|
||||
|
|
@ -2618,7 +2639,10 @@ pygpu_driver_version_string(PyObject *self UNUSED, PyObject *args UNUSED) {
|
|||
|
||||
static void
|
||||
free_custom_shader_pipeline(CustomShaderPipeline *p) {
|
||||
for (size_t i = 0; i < p->num_groups; i++) p->groups[i].animation_curve = free_animation(p->groups[i].animation_curve);
|
||||
for (size_t i = 0; i < p->num_groups; i++) {
|
||||
if (p->groups[i].animation_curve_is_shared) p->groups[i].animation_curve = NULL;
|
||||
else p->groups[i].animation_curve = free_animation(p->groups[i].animation_curve);
|
||||
}
|
||||
}
|
||||
|
||||
static NamedTexture
|
||||
|
|
@ -2702,6 +2726,14 @@ transfer_pipeline_to_struct(PyObject *pg, CustomShaderPipeline *p) {
|
|||
PyObject *acurve = PyDict_GetItemString(g, "animation_curve");
|
||||
if (acurve && PyObject_IsTrue(acurve)) {
|
||||
if ((cg->animation_curve = alloc_animation()) != NULL) add_easing_function(cg->animation_curve, acurve, 0.0, 1.0);
|
||||
for (Py_ssize_t j = 0; j < i; j++) {
|
||||
if (animations_equal(p->groups[j].animation_curve, cg->animation_curve)) {
|
||||
free_animation(cg->animation_curve);
|
||||
cg->animation_curve = p->groups[j].animation_curve;
|
||||
cg->animation_curve_is_shared = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *astep = PyDict_GetItemString(g, "animation_step");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue