WM: reuse visible region calculation
authorCampbell Barton <ideasman42@gmail.com>
Thu, 15 Aug 2019 19:41:43 +0000 (05:41 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 15 Aug 2019 20:44:25 +0000 (06:44 +1000)
Avoids calculating the visible part of a region whenever
on-screen overlays are drawn.

18 files changed:
source/blender/draw/engines/eevee/eevee_lookdev.c
source/blender/draw/intern/draw_manager.c
source/blender/draw/intern/draw_manager_profiling.c
source/blender/draw/intern/draw_manager_profiling.h
source/blender/editors/gpencil/annotate_draw.c
source/blender/editors/gpencil/annotate_paint.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_screen.h
source/blender/editors/interface/view2d_gizmo_navigate.c
source/blender/editors/screen/area.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_gizmo_navigate.c
source/blender/editors/transform/transform.c
source/blender/makesdna/DNA_screen_types.h

index e6e699bef1020b3c0a86e93bd20a5bb86e96596b..f52fcf31267a61176cafac54121ef59c82042d3f 100644 (file)
@@ -75,22 +75,21 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
 
   if (LOOK_DEV_OVERLAY_ENABLED(v3d)) {
     /* Viewport / Spheres size. */
-    rcti rect;
-    ED_region_visible_rect(draw_ctx->ar, &rect);
+    const rcti *rect = ED_region_visible_rect(draw_ctx->ar);
 
     /* Make the viewport width scale the lookdev spheres a bit.
      * Scale between 1000px and 2000px. */
     const float viewport_scale = clamp_f(
-        BLI_rcti_size_x(&rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f);
+        BLI_rcti_size_x(rect) / (2000.0f * U.dpi_fac), 0.5f, 1.0f);
     const int sphere_size = U.lookdev_sphere_size * U.dpi_fac * viewport_scale;
 
-    if (sphere_size != effects->sphere_size || rect.xmax != effects->anchor[0] ||
-        rect.ymin != effects->anchor[1]) {
+    if (sphere_size != effects->sphere_size || rect->xmax != effects->anchor[0] ||
+        rect->ymin != effects->anchor[1]) {
       /* If sphere size or anchor point moves, reset TAA to avoid ghosting issue.
        * This needs to happen early because we are changing taa_current_sample. */
       effects->sphere_size = sphere_size;
-      effects->anchor[0] = rect.xmax;
-      effects->anchor[1] = rect.ymin;
+      effects->anchor[0] = rect->xmax;
+      effects->anchor[1] = rect->ymin;
       EEVEE_temporal_sampling_reset(vedata);
     }
   }
index 1046e0422c1c279c3b8c76b8d0270315b99c2efe..a2bbb368caacf561d520761d0c7a7271f7933666 100644 (file)
@@ -1725,9 +1725,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
 
   if (G.debug_value > 20 && G.debug_value < 30) {
     GPU_depth_test(false);
-    rcti rect; /* local coordinate visible rect inside region, to accommodate overlapping ui */
-    ED_region_visible_rect(DST.draw_ctx.ar, &rect);
-    DRW_stats_draw(&rect);
+    /* local coordinate visible rect inside region, to accommodate overlapping ui */
+    const rcti *rect = ED_region_visible_rect(DST.draw_ctx.ar);
+    DRW_stats_draw(rect);
     GPU_depth_test(true);
   }
 
index 5e21e5e576ccb4b83ed1279eb8ee53a2041f3fa9..bab69cf7a575d0b2d9bf94d6fc917b708edb2386 100644 (file)
@@ -200,7 +200,7 @@ void DRW_stats_reset(void)
   }
 }
 
-static void draw_stat_5row(rcti *rect, int u, int v, const char *txt, const int size)
+static void draw_stat_5row(const rcti *rect, int u, int v, const char *txt, const int size)
 {
   BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit,
                          rect->ymax - (3 + v) * U.widget_unit,
@@ -209,13 +209,13 @@ static void draw_stat_5row(rcti *rect, int u, int v, const char *txt, const int
                          size);
 }
 
-static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
+static void draw_stat(const rcti *rect, int u, int v, const char *txt, const int size)
 {
   BLF_draw_default_ascii(
       rect->xmin + (1 + u) * U.widget_unit, rect->ymax - (3 + v) * U.widget_unit, 0.0f, txt, size);
 }
 
-void DRW_stats_draw(rcti *rect)
+void DRW_stats_draw(const rcti *rect)
 {
   char stat_string[64];
   int lvl_index[MAX_NESTED_TIMER];
index 7fe2280f9b21f6e60c7731759c1ae39f0dc219f5..3da6a4c8b1c6b1a77011e7bb8e2ba9db9b667ae5 100644 (file)
@@ -35,6 +35,6 @@ void DRW_stats_group_end(void);
 void DRW_stats_query_start(const char *name);
 void DRW_stats_query_end(void);
 
-void DRW_stats_draw(rcti *rect);
+void DRW_stats_draw(const rcti *rect);
 
 #endif /* __DRAW_MANAGER_PROFILING_H__ */
index dce6ed29c050ee0bb8e0b9071c59b099c6220535..697d06aa09886e9010bce0e3a51fc125072adca9 100644 (file)
@@ -936,7 +936,6 @@ static void annotation_draw_data_layers(
 /* draw a short status message in the top-right corner */
 static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar)
 {
-  rcti rect;
 
   /* Cannot draw any status text when drawing OpenGL Renders */
   if (G.f & G_FLAG_RENDER_VIEWPORT) {
@@ -944,7 +943,7 @@ static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar)
   }
 
   /* Get bounds of region - Necessary to avoid problems with region overlap */
-  ED_region_visible_rect(ar, &rect);
+  const rcti *rect = ED_region_visible_rect(ar);
 
   /* for now, this should only be used to indicate when we are in stroke editmode */
   if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
@@ -956,8 +955,8 @@ static void annotation_draw_status_text(const bGPdata *gpd, ARegion *ar)
     BLF_width_and_height(
         font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
 
-    int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
-    int yco = (rect.ymax - U.widget_unit);
+    int xco = (rect->xmax - U.widget_unit) - (int)printable_size[0];
+    int yco = (rect->ymax - U.widget_unit);
 
     /* text label */
     UI_FontThemeColor(font_id, TH_TEXT_HI);
index c9c4a67644e6fe3ccaa3c2cbea6e592ae004096c..07b61751b220abfa7eba01fff0a83981bec2277a 100644 (file)
@@ -2242,11 +2242,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
         }
       }
       else if (p->ar) {
-        rcti region_rect;
-
-        /* Perform bounds check using  */
-        ED_region_visible_rect(p->ar, &region_rect);
-        in_bounds = BLI_rcti_isect_pt_v(&region_rect, event->mval);
+        /* Perform bounds check. */
+        const rcti *region_rect = ED_region_visible_rect(p->ar);
+        in_bounds = BLI_rcti_isect_pt_v(region_rect, event->mval);
       }
       else {
         /* No region */
index 2b31af5ff1fae4e7bab35e146fac89d78a95075a..7c76f3aeab6bfe19e743e4090c6d60854d55db0e 100644 (file)
@@ -1173,15 +1173,14 @@ void ED_gp_draw_fill(tGPDdraw *tgpw)
 /* draw a short status message in the top-right corner */
 static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar)
 {
-  rcti rect;
 
   /* Cannot draw any status text when drawing OpenGL Renders */
   if (G.f & G_FLAG_RENDER_VIEWPORT) {
     return;
   }
 
-  /* Get bounds of region - Necessary to avoid problems with region overlap */
-  ED_region_visible_rect(ar, &rect);
+  /* Get bounds of region - Necessary to avoid problems with region overlap. */
+  const rcti *rect = ED_region_visible_rect(ar);
 
   /* for now, this should only be used to indicate when we are in stroke editmode */
   if (gpd->flag & GP_DATA_STROKE_EDITMODE) {
@@ -1193,8 +1192,8 @@ static void UNUSED_FUNCTION(gp_draw_status_text)(const bGPdata *gpd, ARegion *ar
     BLF_width_and_height(
         font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
 
-    int xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
-    int yco = (rect.ymax - U.widget_unit);
+    int xco = (rect->xmax - U.widget_unit) - (int)printable_size[0];
+    int yco = (rect->ymax - U.widget_unit);
 
     /* text label */
     UI_FontThemeColor(font_id, TH_TEXT_HI);
index 894fb6eced45e8daaa2d337b96aa1ddf54b63a0f..a5425d64c2e2f7e39b4c3e68b6e643387fe60c54 100644 (file)
@@ -3629,11 +3629,9 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
         }
       }
       else if (p->ar) {
-        rcti region_rect;
-
         /* Perform bounds check using  */
-        ED_region_visible_rect(p->ar, &region_rect);
-        in_bounds = BLI_rcti_isect_pt_v(&region_rect, event->mval);
+        const rcti *region_rect = ED_region_visible_rect(p->ar);
+        in_bounds = BLI_rcti_isect_pt_v(region_rect, event->mval);
       }
       else {
         /* No region */
index e67a3b003fce9a534dbd6b5c841be221f1d96771..c7ee7be49b5a0552363e5b3cb39790f509f746f7 100644 (file)
@@ -124,7 +124,8 @@ void ED_region_image_metadata_draw(
 void ED_region_image_metadata_panel_draw(struct ImBuf *ibuf, struct uiLayout *layout);
 void ED_region_grid_draw(struct ARegion *ar, float zoomx, float zoomy);
 float ED_region_blend_alpha(struct ARegion *ar);
-void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
+void ED_region_visible_rect_calc(struct ARegion *ar, struct rcti *rect);
+const rcti *ED_region_visible_rect(ARegion *ar);
 bool ED_region_is_overlap(int spacetype, int regiontype);
 
 int ED_region_snap_size_test(const struct ARegion *ar);
index 883f16c63f261dfc279a0993ab9751968e283ac8..9b15f2309a186ae1e9a20f22c92f214298f47fa6 100644 (file)
@@ -201,21 +201,20 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
   struct NavigateWidgetGroup *navgroup = gzgroup->customdata;
   ARegion *ar = CTX_wm_region(C);
 
-  rcti rect_visible;
-  ED_region_visible_rect(ar, &rect_visible);
+  const rcti *rect_visible = ED_region_visible_rect(ar);
 
-  if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) &&
-      (navgroup->state.rect_visible.ymax == rect_visible.ymax)) {
+  if ((navgroup->state.rect_visible.xmax == rect_visible->xmax) &&
+      (navgroup->state.rect_visible.ymax == rect_visible->ymax)) {
     return;
   }
 
-  navgroup->state.rect_visible = rect_visible;
+  navgroup->state.rect_visible = *rect_visible;
 
   const float icon_size = GIZMO_SIZE;
   const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
   const float co[2] = {
-      rect_visible.xmax - (icon_offset_mini * 0.75f),
-      rect_visible.ymax - (icon_offset_mini * 0.75f),
+      rect_visible->xmax - (icon_offset_mini * 0.75f),
+      rect_visible->ymax - (icon_offset_mini * 0.75f),
   };
 
   wmGizmo *gz;
index d0a3382ee50ebbc589e7e3baf81128c5378383c2..1775a0c55a2a008a1eb09488623ee37ef8e75512 100644 (file)
@@ -875,10 +875,9 @@ static void fullscreen_azone_initialize(ScrArea *sa, ARegion *ar)
   az->alpha = 0.0f;
 
   if (U.uiflag2 & USER_REGION_OVERLAP) {
-    rcti rect_visible;
-    ED_region_visible_rect(ar, &rect_visible);
-    az->x2 = ar->winrct.xmin + rect_visible.xmax;
-    az->y2 = ar->winrct.ymin + rect_visible.ymax;
+    const rcti *rect_visible = ED_region_visible_rect(ar);
+    az->x2 = ar->winrct.xmin + rect_visible->xmax;
+    az->y2 = ar->winrct.ymin + rect_visible->ymax;
   }
   else {
     az->x2 = ar->winrct.xmax;
@@ -1492,6 +1491,9 @@ static void region_rect_recursive(
   if (ar->winx != prev_winx || ar->winy != prev_winy) {
     ED_region_tag_redraw(ar);
   }
+
+  /* Clear, initialize on demand. */
+  memset(&ar->runtime.visible_rect, 0, sizeof(ar->runtime.visible_rect));
 }
 
 static void area_calc_totrct(ScrArea *sa, const rcti *window_rect)
@@ -2786,11 +2788,10 @@ void ED_region_info_draw_multiline(ARegion *ar,
   uiStyle *style = UI_style_get_dpi();
   int fontid = style->widget.uifont_id;
   int scissor[4];
-  rcti rect;
   int num_lines = 0;
 
   /* background box */
-  ED_region_visible_rect(ar, &rect);
+  rcti rect = *ED_region_visible_rect(ar);
 
   /* Box fill entire width or just around text. */
   if (!full_redraw) {
@@ -3268,7 +3269,7 @@ void ED_region_grid_draw(ARegion *ar, float zoomx, float zoomy)
 
 /* If the area has overlapping regions, it returns visible rect for Region *ar */
 /* rect gets returned in local region coordinates */
-void ED_region_visible_rect(ARegion *ar, rcti *rect)
+static void region_visible_rect_calc(ARegion *ar, rcti *rect)
 {
   ARegion *arn = ar;
 
@@ -3315,6 +3316,15 @@ void ED_region_visible_rect(ARegion *ar, rcti *rect)
   BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
 }
 
+const rcti *ED_region_visible_rect(ARegion *ar)
+{
+  rcti *rect = &ar->runtime.visible_rect;
+  if (rect->xmin == 0 && rect->ymin == 0 && rect->xmax == 0 && rect->ymax == 0) {
+    region_visible_rect_calc(ar, rect);
+  }
+  return rect;
+}
+
 /* Cache display helpers */
 
 void ED_region_cache_draw_background(const ARegion *ar)
index 97a3c7f24805c2033d36deb4a56e2da38a90bd38..9a2b0d95c20869a2b3a9103d2c24821fd0d6bf2d 100644 (file)
@@ -156,9 +156,8 @@ void ED_image_draw_info(Scene *scene,
   char str[256];
   int dx = 6;
   /* local coordinate visible rect inside region, to accommodate overlapping ui */
-  rcti rect;
-  ED_region_visible_rect(ar, &rect);
-  const int ymin = rect.ymin;
+  const rcti *rect = ED_region_visible_rect(ar);
+  const int ymin = rect->ymin;
   const int dy = ymin + 0.3f * UI_UNIT_Y;
 
   /* text colors */
index 17f808f727d617ec6ccd423fd9f309c85f0297f5..33e77d3623edfba8047e76d57f0c2de5b7f4f678 100644 (file)
@@ -501,11 +501,10 @@ static void image_main_region_set_view2d(SpaceImage *sima, ARegion *ar)
   int winy = BLI_rcti_size_y(&ar->winrct) + 1;
 
   /* For region overlap, move center so image doesn't overlap header. */
-  rcti visible_rect;
-  ED_region_visible_rect(ar, &visible_rect);
-  const int visible_winy = BLI_rcti_size_y(&visible_rect) + 1;
+  const rcti *visible_rect = ED_region_visible_rect(ar);
+  const int visible_winy = BLI_rcti_size_y(visible_rect) + 1;
   int visible_centerx = 0;
-  int visible_centery = visible_rect.ymin + (visible_winy - winy) / 2;
+  int visible_centery = visible_rect->ymin + (visible_winy - winy) / 2;
 
   ar->v2d.tot.xmin = 0;
   ar->v2d.tot.ymin = 0;
index 12b446c3f4ce3919e0af4f5f50190688c0d90e88..9aa9d14cbc82fa973ae38ba457040bc1ffd7e0bd 100644 (file)
@@ -675,10 +675,9 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *ar)
   WM_gizmomap_draw(ar->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
 
   if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
-    rcti rect;
-    ED_region_visible_rect(ar, &rect);
-    int xoffset = rect.xmin + U.widget_unit;
-    int yoffset = rect.ymax;
+    const rcti *rect = ED_region_visible_rect(ar);
+    int xoffset = rect->xmin + U.widget_unit;
+    int yoffset = rect->ymax;
     ED_scene_draw_fps(scene, xoffset, &yoffset);
   }
 }
index 8844428b1bfd084f77153ca28e427ff9782f2e89..6c534ee1b98a4932a0ad5b237b0893efb1b1f620 100644 (file)
@@ -1382,8 +1382,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar)
   ED_region_pixelspace(ar);
 
   /* local coordinate visible rect inside region, to accommodate overlapping ui */
-  rcti rect;
-  ED_region_visible_rect(ar, &rect);
+  const rcti *rect = ED_region_visible_rect(ar);
 
   view3d_draw_border(C, ar);
   view3d_draw_grease_pencil(C);
@@ -1399,14 +1398,14 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar)
         /* The gizmo handles it's own drawing. */
         break;
       case USER_MINI_AXIS_TYPE_MINIMAL:
-        draw_view_axis(rv3d, &rect);
+        draw_view_axis(rv3d, rect);
       case USER_MINI_AXIS_TYPE_NONE:
         break;
     }
   }
 
-  int xoffset = rect.xmin + U.widget_unit;
-  int yoffset = rect.ymax;
+  int xoffset = rect->xmin + U.widget_unit;
+  int yoffset = rect->ymax;
 
   if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 && (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) == 0) {
     if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {
index ad1a57eb71fe82e4ce5f2cf62d2b9e20f16d1ba9..3c911e266a9e70ff324e6a7c3ce2de020dc64f33 100644 (file)
@@ -246,18 +246,17 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
     copy_v3_v3(navgroup->gz_array[GZ_INDEX_ROTATE]->matrix_offset[i], rv3d->viewmat[i]);
   }
 
-  rcti rect_visible;
-  ED_region_visible_rect(ar, &rect_visible);
+  const rcti *rect_visible = ED_region_visible_rect(ar);
 
-  if ((navgroup->state.rect_visible.xmax == rect_visible.xmax) &&
-      (navgroup->state.rect_visible.ymax == rect_visible.ymax) &&
+  if ((navgroup->state.rect_visible.xmax == rect_visible->xmax) &&
+      (navgroup->state.rect_visible.ymax == rect_visible->ymax) &&
       (navgroup->state.rv3d.is_persp == rv3d->is_persp) &&
       (navgroup->state.rv3d.is_camera == (rv3d->persp == RV3D_CAMOB)) &&
       (navgroup->state.rv3d.viewlock == rv3d->viewlock)) {
     return;
   }
 
-  navgroup->state.rect_visible = rect_visible;
+  navgroup->state.rect_visible = *rect_visible;
   navgroup->state.rv3d.is_persp = rv3d->is_persp;
   navgroup->state.rv3d.is_camera = (rv3d->persp == RV3D_CAMOB);
   navgroup->state.rv3d.viewlock = rv3d->viewlock;
@@ -268,8 +267,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
   const float icon_offset = (icon_size * 0.52f) * GIZMO_OFFSET_FAC * UI_DPI_FAC;
   const float icon_offset_mini = icon_size * GIZMO_MINI_OFFSET_FAC * UI_DPI_FAC;
   const float co_rotate[2] = {
-      rect_visible.xmax - icon_offset,
-      rect_visible.ymax - icon_offset,
+      rect_visible->xmax - icon_offset,
+      rect_visible->ymax - icon_offset,
   };
 
   float icon_offset_from_axis = 0.0f;
@@ -286,8 +285,8 @@ static void WIDGETGROUP_navigate_draw_prepare(const bContext *C, wmGizmoGroup *g
   }
 
   const float co[2] = {
-      rect_visible.xmax - icon_offset_from_axis,
-      rect_visible.ymax - icon_offset_mini * 0.75f,
+      rect_visible->xmax - icon_offset_from_axis,
+      rect_visible->ymax - icon_offset_mini * 0.75f,
   };
 
   wmGizmo *gz;
index 98203a7e31627a6b6863f21a7a3af10aa39e5e1c..14995144c5c5c30559ba314d050272f864560053 100644 (file)
@@ -2009,19 +2009,18 @@ static void drawTransformView(const struct bContext *C, ARegion *ar, void *arg)
  * to warn that autokeying is enabled */
 static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
 {
-  rcti rect;
   const char *printable = IFACE_("Auto Keying On");
   float printable_size[2];
   int xco, yco;
 
-  ED_region_visible_rect(ar, &rect);
+  const rcti *rect = ED_region_visible_rect(ar);
 
   const int font_id = BLF_default();
   BLF_width_and_height(
       font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]);
 
-  xco = (rect.xmax - U.widget_unit) - (int)printable_size[0];
-  yco = (rect.ymax - U.widget_unit);
+  xco = (rect->xmax - U.widget_unit) - (int)printable_size[0];
+  yco = (rect->ymax - U.widget_unit);
 
   /* warning text (to clarify meaning of overlays)
    * - original color was red to match the icon, but that clashes badly with a less nasty border
index 0319993631cb65c318fd5034f56ea8d546dca974..aab71c15e44b2f0a2def03b749fbfdbeb1086440 100644 (file)
@@ -375,6 +375,13 @@ typedef struct ScrArea {
 typedef struct ARegion_Runtime {
   /* Panel category to use between 'layout' and 'draw'. */
   const char *category;
+
+  /**
+   * The visible part of the region, use with region overlap not to draw
+   * on top of the overlapping regions.
+   *
+   * Lazy initialize, zero'd when unset, relative to #ARegion.winrct x/y min. */
+  rcti visible_rect;
 } ARegion_Runtime;
 
 typedef struct ARegion {