[Bf-blender-cvs] [60d873bd221] master: GPU: Panel Drag Widget Drawing Performance

Jeroen Bakker noreply at git.blender.org
Mon Apr 6 16:52:27 CEST 2020


Commit: 60d873bd22121a089101fe6058e0e6aba0467234
Author: Jeroen Bakker
Date:   Mon Apr 6 16:31:22 2020 +0200
Branches: master
https://developer.blender.org/rB60d873bd22121a089101fe6058e0e6aba0467234

GPU: Panel Drag Widget Drawing Performance

The 10g Intel/Win driver doesn't work well with our emulated
intermediate mode. This patch alters the drawing of the drag widget of
the panels to reduce unneeded drawing.

The previous method would draw 16 boxes per widget. This new way would
cache this drawing in a GPU batch and just move the matrix around.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7345

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

M	source/blender/editors/interface/interface_panel.c
M	source/blender/gpu/GPU_batch_presets.h
M	source/blender/gpu/intern/gpu_batch_presets.c

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

diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index b3854cfc4ae..da0e8f34417 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -56,7 +56,9 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "GPU_batch_presets.h"
 #include "GPU_immediate.h"
+#include "GPU_matrix.h"
 #include "GPU_state.h"
 
 #include "interface_intern.h"
@@ -544,59 +546,6 @@ static void ui_draw_panel_scalewidget(uint pos, const rcti *rect)
   GPU_blend(false);
 }
 
-static void immRectf_tris_color_ex(
-    uint pos, float x1, float y1, float x2, float y2, uint col, const float color[3])
-{
-  immAttr4fv(col, color);
-  immVertex2f(pos, x1, y1);
-  immAttr4fv(col, color);
-  immVertex2f(pos, x2, y1);
-  immAttr4fv(col, color);
-  immVertex2f(pos, x2, y2);
-
-  immAttr4fv(col, color);
-  immVertex2f(pos, x1, y1);
-  immAttr4fv(col, color);
-  immVertex2f(pos, x2, y2);
-  immAttr4fv(col, color);
-  immVertex2f(pos, x1, y2);
-}
-
-static void ui_draw_panel_dragwidget(uint pos, uint col, const rctf *rect)
-{
-  float col_high[4], col_dark[4];
-  const int col_tint = 84;
-
-  const int px = (int)U.pixelsize;
-  const int px_zoom = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 22.0f), 1);
-
-  const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
-  const int box_size = max_ii(round_fl_to_int((BLI_rctf_size_y(rect) / 8.0f) - px), px);
-
-  const int x_min = rect->xmin;
-  const int y_min = rect->ymin;
-  const int y_ofs = max_ii(round_fl_to_int(BLI_rctf_size_y(rect) / 2.5f), px);
-  const int x_ofs = y_ofs;
-  int i_x, i_y;
-
-  UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high);
-  UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
-
-  /* draw multiple boxes */
-  immBegin(GPU_PRIM_TRIS, 4 * 2 * (6 * 2));
-  for (i_x = 0; i_x < 4; i_x++) {
-    for (i_y = 0; i_y < 2; i_y++) {
-      const int x_co = (x_min + x_ofs) + (i_x * (box_size + box_margin));
-      const int y_co = (y_min + y_ofs) + (i_y * (box_size + box_margin));
-
-      immRectf_tris_color_ex(
-          pos, x_co - box_size, y_co - px_zoom, x_co, (y_co + box_size) - px_zoom, col, col_dark);
-      immRectf_tris_color_ex(pos, x_co - box_size, y_co, x_co, y_co + box_size, col, col_high);
-    }
-  }
-  immEnd();
-}
-
 /* For button layout next to label. */
 void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y)
 {
@@ -755,24 +704,27 @@ void ui_draw_aligned_panel(uiStyle *style,
     ui_draw_aligned_panel_header(style, block, &titlerect, 'h', show_background);
 
     if (show_drag) {
-      uint col;
-      GPUVertFormat *format = immVertexFormat();
-      pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-      col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
-
       /* itemrect smaller */
+      const float scale = 0.7;
       itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X);
       itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
       itemrect.ymin = headrect.ymin;
       itemrect.ymax = headrect.ymax;
+      BLI_rctf_scale(&itemrect, scale);
 
-      BLI_rctf_scale(&itemrect, 0.7f);
-      immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-      ui_draw_panel_dragwidget(pos, col, &itemrect);
-      immUnbindProgram();
+      GPU_matrix_push();
+      GPU_matrix_translate_2f(itemrect.xmin, itemrect.ymin);
+
+      const int col_tint = 84;
+      float col_high[4], col_dark[4];
+      UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high);
+      UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark);
 
-      /* Restore format for the following draws. */
-      pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+      GPUBatch *batch = GPU_batch_preset_panel_drag_widget(
+          U.pixelsize, col_high, col_dark, BLI_rcti_size_y(&headrect) * scale);
+      GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_FLAT_COLOR);
+      GPU_batch_draw(batch);
+      GPU_matrix_pop();
     }
   }
 
diff --git a/source/blender/gpu/GPU_batch_presets.h b/source/blender/gpu/GPU_batch_presets.h
index ba8ad3c4990..eb803333d98 100644
--- a/source/blender/gpu/GPU_batch_presets.h
+++ b/source/blender/gpu/GPU_batch_presets.h
@@ -39,6 +39,10 @@ extern "C" {
 /* Replacement for gluSphere */
 struct GPUBatch *GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT;
 struct GPUBatch *GPU_batch_preset_sphere_wire(int lod) ATTR_WARN_UNUSED_RESULT;
+struct GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
+                                                    const float col_high[4],
+                                                    const float col_dark[4],
+                                                    const float width) ATTR_WARN_UNUSED_RESULT;
 
 void gpu_batch_presets_init(void);
 void gpu_batch_presets_register(struct GPUBatch *preset_batch);
diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c
index e322b9fb9b8..e488880bf0a 100644
--- a/source/blender/gpu/intern/gpu_batch_presets.c
+++ b/source/blender/gpu/intern/gpu_batch_presets.c
@@ -27,7 +27,10 @@
 #include "BLI_utildefines.h"
 #include "MEM_guardedalloc.h"
 
+#include "DNA_userdef_types.h"
+
 #include "UI_interface.h"
+#include "UI_resources.h"
 
 #include "GPU_batch.h"
 #include "GPU_batch_presets.h" /* own include */
@@ -53,6 +56,23 @@ static struct {
   ThreadMutex mutex;
 } g_presets_3d = {{0}};
 
+static struct {
+  struct {
+    GPUBatch *panel_drag_widget;
+  } batch;
+
+  float panel_drag_widget_pixelsize;
+  float panel_drag_widget_width;
+  float panel_drag_widget_col_high[4];
+  float panel_drag_widget_col_dark[4];
+
+  GPUVertFormat format;
+
+  struct {
+    uint pos, col;
+  } attr_id;
+} g_presets_2d = {{0}};
+
 static ListBase presets_list = {NULL, NULL};
 
 /* -------------------------------------------------------------------- */
@@ -71,6 +91,18 @@ static GPUVertFormat *preset_3d_format(void)
   return &g_presets_3d.format;
 }
 
+static GPUVertFormat *preset_2d_format(void)
+{
+  if (g_presets_2d.format.attr_len == 0) {
+    GPUVertFormat *format = &g_presets_2d.format;
+    g_presets_2d.attr_id.pos = GPU_vertformat_attr_add(
+        format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+    g_presets_2d.attr_id.col = GPU_vertformat_attr_add(
+        format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+  }
+  return &g_presets_2d.format;
+}
+
 static void batch_sphere_lat_lon_vert(GPUVertBufRaw *pos_step,
                                       GPUVertBufRaw *nor_step,
                                       float lat,
@@ -193,6 +225,108 @@ static GPUBatch *batch_sphere_wire(int lat_res, int lon_res)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Panel Drag Widget
+ * \{ */
+static void gpu_batch_preset_rectf_tris_color_ex(GPUVertBufRaw *pos_step,
+                                                 float x1,
+                                                 float y1,
+                                                 float x2,
+                                                 float y2,
+                                                 GPUVertBufRaw *col_step,
+                                                 const float color[4])
+{
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y1});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y1});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y2});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y1});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x2, y2});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+
+  copy_v2_v2(GPU_vertbuf_raw_step(pos_step), (const float[2]){x1, y2});
+  copy_v4_v4(GPU_vertbuf_raw_step(col_step), color);
+}
+
+static GPUBatch *gpu_batch_preset_panel_drag_widget(float pixelsize,
+                                                    const float col_high[4],
+                                                    const float col_dark[4],
+                                                    const float width)
+{
+  GPUVertBuf *vbo = GPU_vertbuf_create_with_format(preset_2d_format());
+  const uint vbo_len = 4 * 2 * (6 * 2);
+  GPU_vertbuf_data_alloc(vbo, vbo_len);
+
+  GPUVertBufRaw pos_step, col_step;
+  GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.pos, &pos_step);
+  GPU_vertbuf_attr_get_raw_data(vbo, g_presets_2d.attr_id.col, &col_step);
+
+  const int px = (int)pixelsize;
+  const int px_zoom = max_ii(round_fl_to_int(width / 22.0f), 1);
+
+  const int box_margin = max_ii(round_fl_to_int((float)(px_zoom * 2.0f)), px);
+  const int box_size = max_ii(round_fl_to_int((width / 8.0f) - px), px);
+
+  const int y_ofs = max_ii(round_fl_to_int(width / 2.5f), px);
+  const int x_ofs = y_ofs;
+  int i_x, i_y;
+
+  for (i_x = 0; i_x < 4; i_x++) {
+    for (i_y = 0; i_y < 2; i_y++) {
+      const int x_co = (x_ofs) + (i_x * (box_size + box_margin));
+      const int y_co = (y_ofs) + (i_y * (box_size + box_margin));
+
+      gpu_batch_preset_rectf_tris_color_ex(&pos_step,
+                                           x_co - box_size,
+                                           y_co - px_zoom,
+                                           x_co,
+                                           (y_co + box_size) - px_zoom,
+                                           &col_step,
+                                           col_dark);
+      gpu_batch_preset_rectf_tris_color_ex(
+          &pos_step, x_co - box_size, y_co, x_co, y_co + box_size, &col_step, col_high);
+    }
+  }
+  return GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
+}
+
+GPUBatch *GPU_batch_preset_panel_drag_widget(const float pixelsize,
+                                             const float col_high[4],
+                                             c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list