Fix T62880 Severe FPS drop with multiple bone shapes

Fix instancing batches not being reused by custom bone shapes.

Drawing thoses is now faster than 2.79 (40fps instead of  30fps)
This commit is contained in:
Clément Foucault 2019-04-26 14:02:58 +02:00
parent 03d482d212
commit 50d75cd528
Notes: blender-bot 2023-02-14 07:39:44 +01:00
Referenced by issue #62880, [Regression] Severe FPS drop with multiple bone shapes in 2.8
5 changed files with 57 additions and 10 deletions

View File

@ -345,7 +345,6 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
const eGPUShaderConfig sh_cfg,
Object *custom)
{
/* grr, not re-using instances! */
struct GPUBatch *surf = DRW_cache_object_surface_get(custom);
struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL);
struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom);
@ -358,23 +357,43 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4],
mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat);
}
BLI_assert(g_data.passes.custom_shapes != NULL);
if (surf && g_data.passes.bone_solid != NULL) {
DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid(
g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg);
DRWShadingGroup *shgrp_geom_solid = BLI_ghash_lookup(g_data.passes.custom_shapes, surf);
if (shgrp_geom_solid == NULL) {
/* NOTE! g_data.transparent require a separate shading group if the
* object is transparent. This is done by passing a different ghash
* for transparent armature in pose mode. */
shgrp_geom_solid = shgroup_instance_bone_shape_solid(
g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg);
BLI_ghash_insert(g_data.passes.custom_shapes, surf, shgrp_geom_solid);
}
DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color);
}
if (edges && outline_color[3] > 0.0f) {
DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline(
g_data.passes.bone_outline, edges, sh_cfg);
DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, edges);
if (shgrp_geom_wire == NULL) {
shgrp_geom_wire = shgroup_instance_bone_shape_outline(
g_data.passes.bone_outline, edges, sh_cfg);
BLI_ghash_insert(g_data.passes.custom_shapes, edges, shgrp_geom_wire);
}
DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color);
}
if (ledges) {
DRWShadingGroup *shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
float final_color[4];
copy_v3_v3(final_color, outline_color);
final_color[3] = 1.0f; /* hack */
DRWShadingGroup *shgrp_geom_ledges = BLI_ghash_lookup(g_data.passes.custom_shapes, ledges);
if (shgrp_geom_ledges == NULL) {
shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges);
BLI_ghash_insert(g_data.passes.custom_shapes, ledges, shgrp_geom_ledges);
}
float final_color[4] = {outline_color[0], outline_color[1], outline_color[2], 1.0f};
DRW_shgroup_call_dynamic_add(shgrp_geom_ledges, final_bonemat, final_color);
}
}

View File

@ -216,6 +216,7 @@ typedef struct DRWArmaturePasses {
struct DRWPass *bone_envelope;
struct DRWPass *bone_axes;
struct DRWPass *relationship_lines;
struct GHash *custom_shapes;
} DRWArmaturePasses;
void DRW_shgroup_armature_object(struct Object *ob,

View File

@ -126,6 +126,7 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship[ghost],
.custom_shapes = NULL, /* Not needed in edit mode. */
};
DRW_shgroup_armature_edit(ob, passes, transp);
}

View File

@ -53,6 +53,8 @@
#include "BKE_particle.h"
#include "BKE_tracking.h"
#include "BLI_ghash.h"
#include "ED_view3d.h"
#include "GPU_batch.h"
@ -273,6 +275,8 @@ typedef struct OBJECT_PrivateData {
OBJECT_ShadingGroupList sgl;
OBJECT_ShadingGroupList sgl_ghost;
GHash *custom_shapes;
/* Outlines */
DRWShadingGroup *outlines_active;
DRWShadingGroup *outlines_select;
@ -1040,6 +1044,8 @@ static void OBJECT_cache_init(void *vedata)
g_data->xray_enabled_and_not_wire = g_data->xray_enabled &&
draw_ctx->v3d->shading.type > OB_WIRE;
g_data->custom_shapes = BLI_ghash_ptr_new(__func__);
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_WIRE;
@ -3288,6 +3294,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
.bone_envelope = sgl->bone_envelope,
.bone_axes = sgl->bone_axes,
.relationship_lines = NULL, /* Don't draw relationship lines */
.custom_shapes = stl->g_data->custom_shapes,
};
DRW_shgroup_armature_object(ob, view_layer, passes, is_wire);
}
@ -3395,6 +3402,11 @@ static void OBJECT_cache_finish(void *vedata)
DRW_pass_sort_shgroup_z(stl->g_data->sgl.image_empties);
DRW_pass_sort_shgroup_z(stl->g_data->sgl_ghost.image_empties);
if (stl->g_data->custom_shapes) {
/* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
BLI_ghash_free(stl->g_data->custom_shapes, NULL, NULL);
}
}
static void OBJECT_draw_scene(void *vedata)

View File

@ -72,6 +72,7 @@ typedef struct POSE_Data {
typedef struct POSE_PrivateData {
DRWShadingGroup *bone_selection_shgrp;
DRWShadingGroup *bone_selection_invert_shgrp;
GHash *custom_shapes[2];
float blend_color[4];
float blend_color_invert[4];
bool transparent_bones;
@ -139,6 +140,8 @@ static void POSE_cache_init(void *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND | DRW_STATE_WIRE;
psl->relationship[i] = DRW_pass_create("Bone Relationship Pass", state);
ppd->custom_shapes[i] = BLI_ghash_ptr_new(__func__);
}
{
@ -213,6 +216,7 @@ static void POSE_cache_populate(void *vedata, Object *ob)
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship[ghost],
.custom_shapes = ppd->custom_shapes[transp],
};
DRW_shgroup_armature_pose(ob, passes, transp);
}
@ -231,6 +235,16 @@ static void POSE_cache_populate(void *vedata, Object *ob)
}
}
static void POSE_cache_finish(void *vedata)
{
POSE_PrivateData *ppd = ((POSE_Data *)vedata)->stl->g_data;
/* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */
for (int i = 0; i < 2; i++) {
BLI_ghash_free(ppd->custom_shapes[i], NULL, NULL);
}
}
/**
* Return true if armature should be handled by the pose mode engine.
*/
@ -323,7 +337,7 @@ DrawEngineType draw_engine_pose_type = {
&POSE_engine_free,
&POSE_cache_init,
&POSE_cache_populate,
NULL,
&POSE_cache_finish,
NULL,
&POSE_draw_scene,
NULL,