Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_draw.c')
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c192
1 files changed, 106 insertions, 86 deletions
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 6e1c815dbca..730c5b3b0c2 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -73,19 +73,28 @@
# include "BKE_subsurf.h"
#endif
-/* ******************* paint cursor *************** */
+/* -------------------------------------------------------------------- */
+/** \name Draw Paint Cursor
+ * \{ */
-static void wm_paintcursor_draw(bContext *C, ScrArea *sa, ARegion *region)
+static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region)
{
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
bScreen *screen = WM_window_get_active_screen(win);
wmPaintCursor *pc;
+ /* Don't draw paint cursors with locked interface. Painting is not possible
+ * then, and cursor drawing can use scene data that another thread may be
+ * modifying. */
+ if (wm->is_interface_locked) {
+ return;
+ }
+
if (region->visible && region == screen->active_region) {
for (pc = wm->paintcursors.first; pc; pc = pc->next) {
- if ((pc->space_type != SPACE_TYPE_ANY) && (sa->spacetype != pc->space_type)) {
+ if ((pc->space_type != SPACE_TYPE_ANY) && (area->spacetype != pc->space_type)) {
continue;
}
@@ -116,8 +125,14 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *sa, ARegion *region)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal Utilities
+ * \{ */
+
static bool wm_draw_region_stereo_set(Main *bmain,
- ScrArea *sa,
+ ScrArea *area,
ARegion *region,
eStereoViews sview)
{
@@ -127,10 +142,10 @@ static bool wm_draw_region_stereo_set(Main *bmain,
return false;
}
- switch (sa->spacetype) {
+ switch (area->spacetype) {
case SPACE_IMAGE: {
if (region->regiontype == RGN_TYPE_WINDOW) {
- SpaceImage *sima = sa->spacedata.first;
+ SpaceImage *sima = area->spacedata.first;
sima->iuser.multiview_eye = sview;
return true;
}
@@ -138,7 +153,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
}
case SPACE_VIEW3D: {
if (region->regiontype == RGN_TYPE_WINDOW) {
- View3D *v3d = sa->spacedata.first;
+ View3D *v3d = area->spacedata.first;
if (v3d->camera && v3d->camera->type == OB_CAMERA) {
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
@@ -159,7 +174,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
}
case SPACE_NODE: {
if (region->regiontype == RGN_TYPE_WINDOW) {
- SpaceNode *snode = sa->spacedata.first;
+ SpaceNode *snode = area->spacedata.first;
if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
Image *ima = BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node");
ima->eye = sview;
@@ -169,7 +184,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
break;
}
case SPACE_SEQ: {
- SpaceSeq *sseq = sa->spacedata.first;
+ SpaceSeq *sseq = area->spacedata.first;
sseq->multiview_eye = sview;
if (region->regiontype == RGN_TYPE_PREVIEW) {
@@ -184,17 +199,15 @@ static bool wm_draw_region_stereo_set(Main *bmain,
return false;
}
-/* ********************* drawing ****************** */
-
-static void wm_area_mark_invalid_backbuf(ScrArea *sa)
+static void wm_area_mark_invalid_backbuf(ScrArea *area)
{
- if (sa->spacetype == SPACE_VIEW3D) {
- ((View3D *)sa->spacedata.first)->flag |= V3D_INVALID_BACKBUF;
+ if (area->spacetype == SPACE_VIEW3D) {
+ ((View3D *)area->spacedata.first)->flag |= V3D_INVALID_BACKBUF;
}
}
static void wm_region_test_gizmo_do_draw(bContext *C,
- ScrArea *sa,
+ ScrArea *area,
ARegion *region,
bool tag_redraw)
{
@@ -203,13 +216,12 @@ static void wm_region_test_gizmo_do_draw(bContext *C,
}
wmGizmoMap *gzmap = region->gizmo_map;
- for (wmGizmoGroup *gzgroup = WM_gizmomap_group_list(gzmap)->first; gzgroup;
- gzgroup = gzgroup->next) {
+ LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gzmap)) {
if (tag_redraw && (gzgroup->type->flag & WM_GIZMOGROUPTYPE_VR_REDRAWS)) {
- ScrArea *ctx_sa = CTX_wm_area(C);
- ARegion *ctx_ar = CTX_wm_region(C);
+ ScrArea *ctx_area = CTX_wm_area(C);
+ ARegion *ctx_region = CTX_wm_region(C);
- CTX_wm_area_set(C, sa);
+ CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
if (WM_gizmo_group_type_poll(C, gzgroup->type)) {
@@ -217,11 +229,11 @@ static void wm_region_test_gizmo_do_draw(bContext *C,
}
/* Reset. */
- CTX_wm_area_set(C, ctx_sa);
- CTX_wm_region_set(C, ctx_ar);
+ CTX_wm_area_set(C, ctx_area);
+ CTX_wm_region_set(C, ctx_region);
}
- for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
+ LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
if (gz->do_draw) {
if (tag_redraw) {
ED_region_tag_redraw_editor_overlays(region);
@@ -234,17 +246,17 @@ static void wm_region_test_gizmo_do_draw(bContext *C,
static void wm_region_test_render_do_draw(const Scene *scene,
struct Depsgraph *depsgraph,
- ScrArea *sa,
+ ScrArea *area,
ARegion *region)
{
/* tag region for redraw from render engine preview running inside of it */
- if (sa->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
+ if (area->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
GPUViewport *viewport = WM_draw_region_get_viewport(region);
if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
- View3D *v3d = sa->spacedata.first;
+ View3D *v3d = area->spacedata.first;
rcti border_rect;
/* do partial redraw when possible */
@@ -281,13 +293,18 @@ static bool wm_region_use_viewport_by_type(short space_type, short region_type)
return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW);
}
-static bool wm_region_use_viewport(ScrArea *sa, ARegion *region)
+bool WM_region_use_viewport(ScrArea *area, ARegion *region)
{
- return wm_region_use_viewport_by_type(sa->spacetype, region->regiontype);
+ return wm_region_use_viewport_by_type(area->spacetype, region->regiontype);
}
-/********************** draw all **************************/
-/* - reference method, draw all each time */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Window Drawing (Draw All)
+ *
+ * Reference method, draw all each time.
+ * \{ */
typedef struct WindowDrawCB {
struct WindowDrawCB *next, *prev;
@@ -312,7 +329,7 @@ void *WM_draw_cb_activate(wmWindow *win,
void WM_draw_cb_exit(wmWindow *win, void *handle)
{
- for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) {
+ LISTBASE_FOREACH (WindowDrawCB *, wdc, &win->drawcalls) {
if (wdc == (WindowDrawCB *)handle) {
BLI_remlink(&win->drawcalls, wdc);
MEM_freeN(wdc);
@@ -323,17 +340,21 @@ void WM_draw_cb_exit(wmWindow *win, void *handle)
static void wm_draw_callbacks(wmWindow *win)
{
- for (WindowDrawCB *wdc = win->drawcalls.first; wdc; wdc = wdc->next) {
+ LISTBASE_FOREACH (WindowDrawCB *, wdc, &win->drawcalls) {
wdc->draw(win, wdc->customdata);
}
}
-/************************* Region drawing. ********************************
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Region Drawing
*
- * Each region draws into its own framebuffer, which is then blit on the
+ * Each region draws into its own frame-buffer, which is then blit on the
* window draw buffer. This helps with fast redrawing if only some regions
* change. It also means we can share a single context for multiple windows,
- * so that for example VAOs can be shared between windows. */
+ * so that for example VAOs can be shared between windows.
+ * \{ */
static void wm_draw_region_buffer_free(ARegion *region)
{
@@ -553,13 +574,13 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
alpha = 1.0f;
}
- glUniform1i(GPU_shader_get_uniform_ensure(shader, "image"), 0);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_icon"),
+ glUniform1i(GPU_shader_get_uniform(shader, "image"), 0);
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_icon"),
rect_tex.xmin,
rect_tex.ymin,
rect_tex.xmax,
rect_tex.ymax);
- glUniform4f(GPU_shader_get_uniform_ensure(shader, "rect_geom"),
+ glUniform4f(GPU_shader_get_uniform(shader, "rect_geom"),
rect_geo.xmin,
rect_geo.ymin,
rect_geo.xmax,
@@ -604,12 +625,11 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
bScreen *screen = WM_window_get_active_screen(win);
/* Draw screen areas into own frame buffer. */
- ED_screen_areas_iter(win, screen, sa)
- {
- CTX_wm_area_set(C, sa);
+ ED_screen_areas_iter (win, screen, area) {
+ CTX_wm_area_set(C, area);
/* Compute UI layouts for dynamically size regions. */
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
/* Dynamic region may have been flagged as too small because their size on init is 0.
* ARegion.visible is false then, as expected. The layout should still be created then, so
* the region size can be updated (it may turn out to be not too small then). */
@@ -625,22 +645,22 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
}
}
- ED_area_update_region_sizes(wm, win, sa);
+ ED_area_update_region_sizes(wm, win, area);
- if (sa->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) {
- if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) {
- WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), sa);
+ if (area->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) {
+ if ((1 << area->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) {
+ WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), area);
}
- sa->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
+ area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE;
}
/* Then do actual drawing of regions. */
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->visible && region->do_draw) {
CTX_wm_region_set(C, region);
- bool use_viewport = wm_region_use_viewport(sa, region);
+ bool use_viewport = WM_region_use_viewport(area, region);
- if (stereo && wm_draw_region_stereo_set(bmain, sa, region, STEREO_LEFT_ID)) {
+ if (stereo && wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID)) {
wm_draw_region_buffer_create(region, true, use_viewport);
for (int view = 0; view < 2; view++) {
@@ -650,7 +670,7 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
}
else {
sview = STEREO_RIGHT_ID;
- wm_draw_region_stereo_set(bmain, sa, region, sview);
+ wm_draw_region_stereo_set(bmain, area, region, sview);
}
wm_draw_region_bind(region, view);
@@ -674,12 +694,12 @@ static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo)
}
}
- wm_area_mark_invalid_backbuf(sa);
+ wm_area_mark_invalid_backbuf(area);
CTX_wm_area_set(C, NULL);
}
/* Draw menus into their own framebuffer. */
- for (ARegion *region = screen->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
if (region->visible) {
CTX_wm_menu_set(C, region);
@@ -720,9 +740,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
#endif
/* Blit non-overlapping area regions. */
- ED_screen_areas_iter(win, screen, sa)
- {
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
+ ED_screen_areas_iter (win, screen, area) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->visible && region->overlap == false) {
/* Blit from offscreen buffer. */
wm_draw_region_blit(region, view);
@@ -732,15 +751,14 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
/* Draw paint cursors. */
if (wm->paintcursors.first) {
- ED_screen_areas_iter(win, screen, sa)
- {
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
+ ED_screen_areas_iter (win, screen, area) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->visible && region == screen->active_region) {
- CTX_wm_area_set(C, sa);
+ CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
/* make region ready for draw, scissor, pixelspace */
- wm_paintcursor_draw(C, sa, region);
+ wm_paintcursor_draw(C, area, region);
CTX_wm_region_set(C, NULL);
CTX_wm_area_set(C, NULL);
@@ -752,9 +770,8 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
}
/* Blend in overlapping area regions */
- ED_screen_areas_iter(win, screen, sa)
- {
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
+ ED_screen_areas_iter (win, screen, area) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
if (region->visible && region->overlap) {
wm_draw_region_blend(region, 0, true);
}
@@ -766,7 +783,7 @@ static void wm_draw_window_onscreen(bContext *C, wmWindow *win, int view)
wm_draw_callbacks(win);
/* Blend in floating regions (menus). */
- for (ARegion *region = screen->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
if (region->visible) {
wm_draw_region_blend(region, 0, true);
}
@@ -831,6 +848,7 @@ static void wm_draw_window(bContext *C, wmWindow *win)
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GPU_texture_opengl_bindcode(texture));
+ wmWindowViewport(win);
if (win->stereo3d_format->display_mode == S3D_DISPLAY_SIDEBYSIDE) {
wm_stereo3d_draw_sidebyside(win, view);
}
@@ -866,7 +884,11 @@ static void wm_draw_surface(bContext *C, wmSurface *surface)
wm_surface_clear_drawable();
}
-/****************** main update call **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Main Update Call
+ * \{ */
/* quick test to prevent changing window drawable */
static bool wm_draw_update_test_window(Main *bmain, bContext *C, wmWindow *win)
@@ -889,13 +911,12 @@ static bool wm_draw_update_test_window(Main *bmain, bContext *C, wmWindow *win)
}
}
- ED_screen_areas_iter(win, screen, sa)
- {
- for (region = sa->regionbase.first; region; region = region->next) {
- wm_region_test_gizmo_do_draw(C, sa, region, true);
- wm_region_test_render_do_draw(scene, depsgraph, sa, region);
+ ED_screen_areas_iter (win, screen, area) {
+ for (region = area->regionbase.first; region; region = region->next) {
+ wm_region_test_gizmo_do_draw(C, area, region, true);
+ wm_region_test_render_do_draw(scene, depsgraph, area, region);
#ifdef WITH_XR_OPENXR
- wm_region_test_xr_do_draw(wm, sa, region);
+ wm_region_test_xr_do_draw(wm, area, region);
#endif
if (region->visible && region->do_draw) {
@@ -937,10 +958,9 @@ static void wm_draw_update_clear_window(bContext *C, wmWindow *win)
{
bScreen *screen = WM_window_get_active_screen(win);
- ED_screen_areas_iter(win, screen, sa)
- {
- for (ARegion *region = sa->regionbase.first; region; region = region->next) {
- wm_region_test_gizmo_do_draw(C, sa, region, false);
+ ED_screen_areas_iter (win, screen, area) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ wm_region_test_gizmo_do_draw(C, area, region, false);
}
}
@@ -963,10 +983,6 @@ void wm_draw_update(bContext *C)
wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win;
-#ifdef WITH_OPENSUBDIV
- BKE_subsurf_free_unused_buffers();
-#endif
-
GPU_free_unused_buffers(bmain);
for (win = wm->windows.first; win; win = win->next) {
@@ -1012,16 +1028,18 @@ void wm_draw_region_clear(wmWindow *win, ARegion *UNUSED(region))
screen->do_draw = true;
}
-void WM_draw_region_free(ARegion *region)
+void WM_draw_region_free(ARegion *region, bool hide)
{
wm_draw_region_buffer_free(region);
- region->visible = 0;
+ if (hide) {
+ region->visible = 0;
+ }
}
-void wm_draw_region_test(bContext *C, ScrArea *sa, ARegion *region)
+void wm_draw_region_test(bContext *C, ScrArea *area, ARegion *region)
{
/* Function for redraw timer benchmark. */
- bool use_viewport = wm_region_use_viewport(sa, region);
+ bool use_viewport = WM_region_use_viewport(area, region);
wm_draw_region_buffer_create(region, false, use_viewport);
wm_draw_region_bind(region, 0);
ED_region_do_draw(C, region);
@@ -1033,15 +1051,17 @@ void WM_redraw_windows(bContext *C)
{
wmWindow *win_prev = CTX_wm_window(C);
ScrArea *area_prev = CTX_wm_area(C);
- ARegion *ar_prev = CTX_wm_region(C);
+ ARegion *region_prev = CTX_wm_region(C);
wm_draw_update(C);
CTX_wm_window_set(C, win_prev);
CTX_wm_area_set(C, area_prev);
- CTX_wm_region_set(C, ar_prev);
+ CTX_wm_region_set(C, region_prev);
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Region Viewport Drawing
*