Anim: precalculate bounding indices for key drawing in the Graph Editor

While the drawing code already skipped drawing any key points that are not in view,
it did that with an `if` check within the `for` loop. This can be speed up quite a bit
by calculating the bounding indices beforehand and only iterating that range.

| - | Before | After |
| - | - | - |
| `draw_fcurve_selected_keyframe_vertices` | 44850ns | 3194ns |
| `graph_main_region_draw` | 32ms | 21ms |

Test file used
https://download.blender.org/ftp/sybren/animation-rigging/heavy_mocap_test.blend

Pull Request: https://projects.blender.org/blender/blender/pulls/120521
This commit is contained in:
Christoph Lendenfeld
2024-04-12 12:41:45 +02:00
committed by Christoph Lendenfeld
parent 4ae9948f3a
commit 3eda9619f9

View File

@@ -203,28 +203,23 @@ static void draw_cross(float position[2], const float scale[2], uint attr_id)
GPU_matrix_pop();
}
static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, bool sel, uint pos)
static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu,
bool sel,
uint pos,
const blender::int2 &bounding_indices)
{
const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
set_fcurve_vertex_color(fcu, sel);
immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert);
BezTriple *bezt = fcu->bezt;
for (int i = 0; i < fcu->totvert; i++, bezt++) {
/* As an optimization step, only draw those in view
* - We apply a correction factor to ensure that points
* don't pop in/out due to slight twitches of view size.
for (int i = bounding_indices[0]; i <= bounding_indices[1]; i++) {
BezTriple *bezt = &fcu->bezt[i];
/* 'Keyframe' vertex only, as handle lines and handles have already been drawn
* - only draw those with correct selection state for the current drawing color
* -
*/
if (IN_RANGE(bezt->vec[1][0], (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
/* 'Keyframe' vertex only, as handle lines and handles have already been drawn
* - only draw those with correct selection state for the current drawing color
* -
*/
if ((bezt->f2 & SELECT) == sel) {
immVertex2fv(pos, bezt->vec[1]);
}
if ((bezt->f2 & SELECT) == sel) {
immVertex2fv(pos, bezt->vec[1]);
}
}
@@ -270,8 +265,10 @@ static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, const uint p
immUniform1f("size", (UI_GetThemeValuef(TH_VERTEX_SIZE) * UI_SCALE_FAC) * 0.8f);
}
draw_fcurve_selected_keyframe_vertices(fcu, v2d, false, pos);
draw_fcurve_selected_keyframe_vertices(fcu, v2d, true, pos);
const blender::int2 bounding_indices = get_bounding_bezt_indices(
fcu, v2d->cur.xmin, v2d->cur.xmax);
draw_fcurve_selected_keyframe_vertices(fcu, false, pos, bounding_indices);
draw_fcurve_selected_keyframe_vertices(fcu, true, pos, bounding_indices);
draw_fcurve_active_vertex(fcu, v2d, pos);
immUnbindProgram();