[Bf-blender-cvs] [ab7214ca2ef] blender-v3.0-release: Fix performance issues with pose library sidebar and many poses

Julian Eisel noreply at git.blender.org
Mon Nov 8 16:56:48 CET 2021


Commit: ab7214ca2ef93c0827d2dbb1ecbdebca184996bf
Author: Julian Eisel
Date:   Mon Nov 8 16:49:19 2021 +0100
Branches: blender-v3.0-release
https://developer.blender.org/rBab7214ca2ef93c0827d2dbb1ecbdebca184996bf

Fix performance issues with pose library sidebar and many poses

When the asset view in the sidebar of the pose library would contain
more than a few handful poses, interaction and animation playback
performance would be impacted considerably. This was because our icon
drawing scales image buffers using a rather slow method on the CPU.
This commit changes it so the asset icons are scaled using the GPU.

Note that this is a temporary change. I'd like all icon code to use
GPU-side scaling, see D13144. But such a change is too risky to do in
the release branch at this point, so this fix is specifically for the
3.0 release.

===================================================================

M	source/blender/editors/interface/interface_icons.c

===================================================================

diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e7991d46918..f849ec55e4f 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1482,6 +1482,78 @@ PreviewImage *UI_icon_to_preview(int icon_id)
   return NULL;
 }
 
+/**
+ * Version of #icon_draw_rect() that uses the GPU for scaling. This is only used for
+ * #ICON_TYPE_IMBUF because it's a backported fix for performance issues, see T92922. Only
+ * File/Asset Browser use #ICON_TYPE_IMBUF right now, which makes implications more predictable.
+ *
+ * TODO(Julian): This code is mostly duplicated. #icon_draw_rect() should be ported to use the GPU
+ *               instead (D13144).
+ */
+static void icon_draw_rect_fast(float x,
+                                float y,
+                                int w,
+                                int h,
+                                float UNUSED(aspect),
+                                int rw,
+                                int rh,
+                                uint *rect,
+                                float alpha,
+                                const float desaturate)
+{
+  int draw_w = w;
+  int draw_h = h;
+  int draw_x = x;
+  /* We need to round y, to avoid the icon jittering in some cases. */
+  int draw_y = round_fl_to_int(y);
+
+  /* sanity check */
+  if (w <= 0 || h <= 0 || w > 2000 || h > 2000) {
+    printf("%s: icons are %i x %i pixels?\n", __func__, w, h);
+    BLI_assert_msg(0, "invalid icon size");
+    return;
+  }
+  /* modulate color */
+  const float col[4] = {alpha, alpha, alpha, alpha};
+
+  float scale_x = 1.0f;
+  float scale_y = 1.0f;
+  /* rect contains image in 'rendersize', we only scale if needed */
+  if (rw != w || rh != h) {
+    /* preserve aspect ratio and center */
+    if (rw > rh) {
+      draw_w = w;
+      draw_h = (int)(((float)rh / (float)rw) * (float)w);
+      draw_y += (h - draw_h) / 2;
+    }
+    else if (rw < rh) {
+      draw_w = (int)(((float)rw / (float)rh) * (float)h);
+      draw_h = h;
+      draw_x += (w - draw_w) / 2;
+    }
+    scale_x = draw_w / (float)rw;
+    scale_y = draw_h / (float)rh;
+    /* If the image is squared, the `draw_*` initialization values are good. */
+  }
+
+  /* draw */
+  eGPUBuiltinShader shader;
+  if (desaturate != 0.0f) {
+    shader = GPU_SHADER_2D_IMAGE_DESATURATE_COLOR;
+  }
+  else {
+    shader = GPU_SHADER_2D_IMAGE_COLOR;
+  }
+  IMMDrawPixelsTexState state = immDrawPixelsTexSetup(shader);
+
+  if (shader == GPU_SHADER_2D_IMAGE_DESATURATE_COLOR) {
+    immUniform1f("factor", desaturate);
+  }
+
+  immDrawPixelsTexScaled(
+      &state, draw_x, draw_y, rw, rh, GPU_RGBA8, true, rect, scale_x, scale_y, 1.0f, 1.0f, col);
+}
+
 static void icon_draw_rect(float x,
                            float y,
                            int w,
@@ -1806,7 +1878,9 @@ static void icon_draw_size(float x,
     ImBuf *ibuf = icon->obj;
 
     GPU_blend(GPU_BLEND_ALPHA_PREMULT);
-    icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate);
+    /* These icons are only used by the File/Asset Browser currently. Without this `_fast()`
+     * version, there may be performance issues, see T92922. */
+    icon_draw_rect_fast(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate);
     GPU_blend(GPU_BLEND_ALPHA);
   }
   else if (di->type == ICON_TYPE_VECTOR) {



More information about the Bf-blender-cvs mailing list