[Bf-blender-cvs] [ad80dc1c89c] master: Cleanup: replace the visible gizmo linked list with an array

Campbell Barton noreply at git.blender.org
Thu May 23 08:37:27 CEST 2019


Commit: ad80dc1c89c61c2f091e41269ab195ccaa1e048f
Author: Campbell Barton
Date:   Thu May 23 16:33:21 2019 +1000
Branches: master
https://developer.blender.org/rBad80dc1c89c61c2f091e41269ab195ccaa1e048f

Cleanup: replace the visible gizmo linked list with an array

Avoids an allocation per gizmo & simplifies limiting the lookup
past the first intersecting 2D gizmo found.

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

M	source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c

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

diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index 5aecab122a2..9f0793fc742 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -31,6 +31,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_buffer.h"
 #include "BLI_listbase.h"
 #include "BLI_string.h"
 #include "BLI_math.h"
@@ -191,14 +192,15 @@ wmGizmo *wm_gizmogroup_find_intersected_gizmo(const wmGizmoGroup *gzgroup,
  * Adds all gizmos of \a gzgroup that can be selected to the head of \a listbase.
  * Added items need freeing!
  */
-void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, ListBase *listbase)
+void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup,
+                                                BLI_Buffer *visible_gizmos)
 {
   for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
     if ((gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
       if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) &&
            (gz->type->draw_select || gz->type->test_select)) ||
           ((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select)) {
-        BLI_addhead(listbase, BLI_genericNodeN(gz));
+        BLI_buffer_append(visible_gizmos, wmGizmo *, gz);
       }
     }
   }
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
index 1a0babdccb5..3a4f303fda8 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h
@@ -21,6 +21,7 @@
 #ifndef __WM_GIZMO_INTERN_H__
 #define __WM_GIZMO_INTERN_H__
 
+struct BLI_Buffer;
 struct GHashIterator;
 struct GizmoGeomInfo;
 struct wmGizmoMap;
@@ -65,7 +66,7 @@ struct wmGizmo *wm_gizmogroup_find_intersected_gizmo(const struct wmGizmoGroup *
                                                      const struct wmEvent *event,
                                                      int *r_part);
 void wm_gizmogroup_intersectable_gizmos_to_list(const struct wmGizmoGroup *gzgroup,
-                                                struct ListBase *listbase);
+                                                struct BLI_Buffer *visible_gizmos);
 bool wm_gizmogroup_is_visible_in_drawstep(const struct wmGizmoGroup *gzgroup,
                                           const eWM_GizmoFlagMapDrawStep drawstep);
 
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 9f36af8b616..1f29ffd5669 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -23,12 +23,12 @@
 
 #include <string.h>
 
+#include "BLI_buffer.h"
 #include "BLI_listbase.h"
 #include "BLI_math.h"
 #include "BLI_math_bits.h"
 #include "BLI_rect.h"
 #include "BLI_ghash.h"
-#include "BLI_array.h"
 
 #include "BKE_context.h"
 #include "BKE_global.h"
@@ -470,24 +470,19 @@ void WM_gizmomap_draw(wmGizmoMap *gzmap,
   BLI_assert(BLI_listbase_is_empty(&draw_gizmos));
 }
 
-static void gizmo_draw_select_3D_loop(const bContext *C,
-                                      ListBase *visible_gizmos,
-                                      const wmGizmo *gz_stop,
+static void gizmo_draw_select_3d_loop(const bContext *C,
+                                      wmGizmo **visible_gizmos,
+                                      const int visible_gizmos_len,
                                       bool *r_use_select_bias)
 {
-  int select_id = 0;
-  wmGizmo *gz;
 
   /* TODO(campbell): this depends on depth buffer being written to,
    * currently broken for the 3D view. */
   bool is_depth_prev = false;
   bool is_depth_skip_prev = false;
 
-  for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) {
-    gz = link->data;
-    if (gz == gz_stop) {
-      break;
-    }
+  for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
+    wmGizmo *gz = visible_gizmos[select_id];
     if (gz->type->draw_select == NULL) {
       continue;
     }
@@ -531,11 +526,11 @@ static void gizmo_draw_select_3D_loop(const bContext *C,
   }
 }
 
-static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
+static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
+                                            const int visible_gizmos_len,
                                             const bContext *C,
                                             const int co[2],
-                                            const int hotspot,
-                                            const wmGizmo *gz_stop)
+                                            const int hotspot)
 {
   ScrArea *sa = CTX_wm_area(C);
   ARegion *ar = CTX_wm_region(C);
@@ -554,13 +549,13 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
 
   GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
   /* do the drawing */
-  gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
+  gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
 
   hits = GPU_select_end();
 
   if (hits > 0) {
     GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
-    gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
+    gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
     GPU_select_end();
   }
 
@@ -568,11 +563,6 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
       CTX_wm_window(C), CTX_data_depsgraph(C), CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
 
   if (use_select_bias && (hits > 1)) {
-    wmGizmo **gizmo_table = NULL;
-    BLI_array_staticdeclare(gizmo_table, 1024);
-    for (LinkData *link = visible_gizmos->first; link; link = link->next) {
-      BLI_array_append(gizmo_table, link->data);
-    }
     float co_direction[3];
     float co_screen[3] = {co[0], co[1], 0.0f};
     ED_view3d_win_to_vector(ar, (float[2]){UNPACK2(co)}, co_direction);
@@ -590,7 +580,7 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
 
     for (int i = 0; i < hits; i++, buf_iter += 4) {
       BLI_assert(buf_iter[3] != -1);
-      wmGizmo *gz = gizmo_table[buf_iter[3] >> 8];
+      wmGizmo *gz = visible_gizmos[buf_iter[3] >> 8];
       float co_3d[3];
       co_screen[2] = int_as_float(buf_iter[1]);
       GPU_matrix_unproject_model_inverted(co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d);
@@ -605,7 +595,6 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
         hit_found = buf_iter[3];
       }
     }
-    BLI_array_free(gizmo_table);
     return hit_found;
   }
   else {
@@ -619,10 +608,12 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
  */
 static wmGizmo *gizmo_find_intersected_3d(bContext *C,
                                           const int co[2],
-                                          ListBase *visible_gizmos,
+                                          wmGizmo **visible_gizmos,
+                                          const int visible_gizmos_len,
                                           int *r_part)
 {
   wmGizmo *result = NULL;
+  int visible_gizmos_len_trim = visible_gizmos_len;
   int hit = -1;
 
   *r_part = 0;
@@ -633,14 +624,15 @@ static wmGizmo *gizmo_find_intersected_3d(bContext *C,
   /* Search for 3D gizmo's that use the 2D callback for checking intersections. */
   bool has_3d = false;
   {
-    int select_id = 0;
-    for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) {
-      wmGizmo *gz = link->data;
+    for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
+      wmGizmo *gz = visible_gizmos[select_id];
       /* With both defined, favor the 3D, incase the gizmo can be used in 2D or 3D views. */
       if (gz->type->test_select && (gz->type->draw_select == NULL)) {
         if ((*r_part = gz->type->test_select(C, gz, co)) != -1) {
           hit = select_id;
           result = gz;
+          /* Don't search past this when checking intersections. */
+          visible_gizmos_len_trim = select_id;
           break;
         }
       }
@@ -659,23 +651,19 @@ static wmGizmo *gizmo_find_intersected_3d(bContext *C,
         10 * U.pixelsize,
     };
     for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) {
-      hit = gizmo_find_intersected_3d_intern(visible_gizmos, C, co, hotspot_radii[i], result);
+      hit = gizmo_find_intersected_3d_intern(
+          visible_gizmos, visible_gizmos_len_trim, C, co, hotspot_radii[i]);
       if (hit != -1) {
         break;
       }
     }
 
     if (hit != -1) {
-      LinkData *link = BLI_findlink(visible_gizmos, hit >> 8);
-      if (link != NULL) {
-        *r_part = hit & 255;
-        result = link->data;
-      }
-      else {
-        /* All gizmos should use selection ID they're given as part of the callback,
-         * if they don't it will attempt tp lookup non-existing index. */
-        BLI_assert(0);
-      }
+      const int select_id = hit >> 8;
+      const int select_part = hit & 0xff;
+      BLI_assert(select_id < visible_gizmos_len);
+      *r_part = select_part;
+      result = visible_gizmos[select_id];
     }
   }
 
@@ -692,7 +680,7 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap,
                                     int *r_part)
 {
   wmGizmo *gz = NULL;
-  ListBase visible_3d_gizmos = {NULL};
+  BLI_buffer_declare_static(wmGizmo *, visible_3d_gizmos, BLI_BUFFER_NOP, 128);
   bool do_step[WM_GIZMOMAP_DRAWSTEP_MAX];
 
   for (int i = 0; i < ARRAY_SIZE(do_step); i++) {
@@ -735,13 +723,14 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap,
     }
   }
 
-  if (!BLI_listbase_is_empty(&visible_3d_gizmos)) {
+  if (visible_3d_gizmos.count) {
     /* 2D gizmos get priority. */
     if (gz == NULL) {
-      gz = gizmo_find_intersected_3d(C, event->mval, &visible_3d_gizmos, r_part);
+      gz = gizmo_find_intersected_3d(
+          C, event->mval, 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list