WM: reuse visible region calculation

Avoids calculating the visible part of a region whenever
on-screen overlays are drawn.
This commit is contained in:
Campbell Barton 2019-08-16 05:41:43 +10:00
parent 266e7b67fd
commit 8f565f5a6f
18 changed files with 80 additions and 76 deletions

View 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);
}
}

View 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);
}

View 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];

View 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__ */

View 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);

View 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 */

View 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);

View 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 */

View 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);

View 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;

View 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)

View 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 */

View 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;

View 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);
}
}

View 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)) {

View 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;

View 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

View 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 {