diff options
author | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
commit | 920a58d9b6d667894cf166cbbd25e4c2fbd238ea (patch) | |
tree | 7ca5a9da640753b5e070c439ac3bdd14dfad92cf /source/blender/windowmanager/intern/wm_draw.c | |
parent | c94b6209861ca7cc3985b53474feed7d94c0221a (diff) | |
parent | a1d55bdd530390e58c51abe9707b8d3b0ae3e861 (diff) |
Merge branch 'master' into wm-drag-drop-rewritewm-drag-drop-rewrite
Diffstat (limited to 'source/blender/windowmanager/intern/wm_draw.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 192 |
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 * |