* Fix CPU subdivided meshes not being counted * Fix wrong check for GPU subdivision * Draw status bar last so stats reflect latest 3D viewport drawing Pull Request: https://projects.blender.org/blender/blender/pulls/137959
This commit is contained in:
committed by
Brecht Van Lommel
parent
84210efde8
commit
3ee7750fe1
@@ -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<SubdivCCG> &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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user