diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index c88f0194ad4..fc8f65b48b6 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -102,22 +102,36 @@ static bool stats_mesheval(const Mesh *mesh_eval, bool is_selected, SceneStats * int totvert, totedge, totface, totloop; - const SubsurfRuntimeData *subsurf_runtime_data = mesh_eval->runtime->subsurf_runtime_data; - + /* Get multires stats. */ if (const std::unique_ptr &subdiv_ccg = mesh_eval->runtime->subdiv_ccg) { BKE_subdiv_ccg_topology_counters(*subdiv_ccg, totvert, totedge, totface, totloop); } - else if (subsurf_runtime_data && subsurf_runtime_data->resolution != 0) { - totvert = subsurf_runtime_data->stats_totvert; - totedge = subsurf_runtime_data->stats_totedge; - totface = subsurf_runtime_data->stats_faces_num; - totloop = subsurf_runtime_data->stats_totloop; - } else { - totvert = mesh_eval->verts_num; - totedge = mesh_eval->edges_num; - totface = mesh_eval->faces_num; - totloop = mesh_eval->corners_num; + /* Get CPU subdivided mesh if it exists. */ + const SubsurfRuntimeData *subsurf_runtime_data = nullptr; + if (mesh_eval->runtime->mesh_eval) { + mesh_eval = mesh_eval->runtime->mesh_eval; + } + else { + subsurf_runtime_data = mesh_eval->runtime->subsurf_runtime_data; + } + + /* Get GPU subdivision stats if they exist. If there is no 3D viewport or the mesh is + * hidden it will not be subdivided, fall back to unsubdivided in that case. */ + if (subsurf_runtime_data && subsurf_runtime_data->has_gpu_subdiv && + subsurf_runtime_data->stats_totvert) + { + totvert = subsurf_runtime_data->stats_totvert; + totedge = subsurf_runtime_data->stats_totedge; + totface = subsurf_runtime_data->stats_faces_num; + totloop = subsurf_runtime_data->stats_totloop; + } + else { + totvert = mesh_eval->verts_num; + totedge = mesh_eval->edges_num; + totface = mesh_eval->faces_num; + totloop = mesh_eval->corners_num; + } } stats->totvert += totvert; diff --git a/source/blender/windowmanager/intern/wm_draw.cc b/source/blender/windowmanager/intern/wm_draw.cc index 31b3f3ed8b8..e68b44e2a36 100644 --- a/source/blender/windowmanager/intern/wm_draw.cc +++ b/source/blender/windowmanager/intern/wm_draw.cc @@ -15,6 +15,7 @@ #include "DNA_listBase.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" #include "DNA_windowmanager_types.h" @@ -928,100 +929,114 @@ GPUViewport *WM_draw_region_get_bound_viewport(ARegion *region) return viewport; } -static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) +static void wm_draw_area_offscreen(bContext *C, wmWindow *win, ScrArea *area, bool stereo) { - Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); - bScreen *screen = WM_window_get_active_screen(win); + Main *bmain = CTX_data_main(C); - /* Draw screen areas into their own frame buffer. */ - ED_screen_areas_iter (win, screen, area) { - CTX_wm_area_set(C, area); - GPU_debug_group_begin(wm_area_name(area)); + CTX_wm_area_set(C, area); + GPU_debug_group_begin(wm_area_name(area)); - /* Compute UI layouts for dynamically size regions. */ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->flag & RGN_FLAG_POLL_FAILED) { - continue; - } - /* 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). */ - const bool ignore_visibility = (region->flag & RGN_FLAG_DYNAMIC_SIZE) && - (region->flag & RGN_FLAG_TOO_SMALL) && - !(region->flag & RGN_FLAG_HIDDEN); - - if ((region->runtime->visible || ignore_visibility) && region->runtime->do_draw && - region->runtime->type && region->runtime->type->layout) - { - CTX_wm_region_set(C, region); - ED_region_do_layout(C, region); - CTX_wm_region_set(C, nullptr); - } + /* Compute UI layouts for dynamically size regions. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->flag & RGN_FLAG_POLL_FAILED) { + continue; } + /* 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). */ + const bool ignore_visibility = (region->flag & RGN_FLAG_DYNAMIC_SIZE) && + (region->flag & RGN_FLAG_TOO_SMALL) && + !(region->flag & RGN_FLAG_HIDDEN); - ED_area_update_region_sizes(wm, win, area); - - 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_scene(C), CTX_data_view_layer(C), area); - } - area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; - } - - /* Then do actual drawing of regions. */ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (!region->runtime->visible || !region->runtime->do_draw) { - continue; - } - + if ((region->runtime->visible || ignore_visibility) && region->runtime->do_draw && + region->runtime->type && region->runtime->type->layout) + { CTX_wm_region_set(C, region); - bool use_viewport = WM_region_use_viewport(area, region); + ED_region_do_layout(C, region); + CTX_wm_region_set(C, nullptr); + } + } - GPU_debug_group_begin(use_viewport ? "Viewport" : "ARegion"); + ED_area_update_region_sizes(wm, win, area); - if (stereo && wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID)) { - Scene *scene = WM_window_get_active_scene(win); - wm_draw_region_buffer_create(scene, region, true, use_viewport); + 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_scene(C), CTX_data_view_layer(C), area); + } + area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; + } - for (int view = 0; view < 2; view++) { - eStereoViews sview; - if (view == 0) { - sview = STEREO_LEFT_ID; - } - else { - sview = STEREO_RIGHT_ID; - wm_draw_region_stereo_set(bmain, area, region, sview); - } + /* Then do actual drawing of regions. */ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (!region->runtime->visible || !region->runtime->do_draw) { + continue; + } - wm_draw_region_bind(region, view); - ED_region_do_draw(C, region); - wm_draw_region_unbind(region); + CTX_wm_region_set(C, region); + bool use_viewport = WM_region_use_viewport(area, region); + + GPU_debug_group_begin(use_viewport ? "Viewport" : "ARegion"); + + if (stereo && wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID)) { + Scene *scene = WM_window_get_active_scene(win); + wm_draw_region_buffer_create(scene, region, true, use_viewport); + + for (int view = 0; view < 2; view++) { + eStereoViews sview; + if (view == 0) { + sview = STEREO_LEFT_ID; } - if (use_viewport) { - GPUViewport *viewport = region->runtime->draw_buffer->viewport; - GPU_viewport_stereo_composite(viewport, win->stereo3d_format); + else { + sview = STEREO_RIGHT_ID; + wm_draw_region_stereo_set(bmain, area, region, sview); } - } - else { - wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID); - Scene *scene = WM_window_get_active_scene(win); - wm_draw_region_buffer_create(scene, region, false, use_viewport); - wm_draw_region_bind(region, 0); + + wm_draw_region_bind(region, view); ED_region_do_draw(C, region); wm_draw_region_unbind(region); } - - GPU_debug_group_end(); - - region->runtime->do_draw = 0; - CTX_wm_region_set(C, nullptr); + if (use_viewport) { + GPUViewport *viewport = region->runtime->draw_buffer->viewport; + GPU_viewport_stereo_composite(viewport, win->stereo3d_format); + } + } + else { + wm_draw_region_stereo_set(bmain, area, region, STEREO_LEFT_ID); + Scene *scene = WM_window_get_active_scene(win); + wm_draw_region_buffer_create(scene, region, false, use_viewport); + wm_draw_region_bind(region, 0); + ED_region_do_draw(C, region); + wm_draw_region_unbind(region); } - CTX_wm_area_set(C, nullptr); - GPU_debug_group_end(); + + region->runtime->do_draw = 0; + CTX_wm_region_set(C, nullptr); + } + + CTX_wm_area_set(C, nullptr); + + GPU_debug_group_end(); +} + +static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) +{ + bScreen *screen = WM_window_get_active_screen(win); + + /* Draw screen areas into their own frame buffer. Status bar is drawn last, because mesh + * and memory usage statistics are affected by drawing of editors. */ + ED_screen_areas_iter (win, screen, area) { + if (area->spacetype != SPACE_STATUSBAR) { + wm_draw_area_offscreen(C, win, area, stereo); + } + } + ED_screen_areas_iter (win, screen, area) { + if (area->spacetype == SPACE_STATUSBAR) { + wm_draw_area_offscreen(C, win, area, stereo); + } } /* Draw menus into their own frame-buffer. */