From afc994b2fb6ed6258be8529e8e9ecd43d11948f7 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 28 Oct 2018 11:47:16 +0100 Subject: [PATCH] display: fix crash when removing DisplayRegion in pipelined render Maybe not a perfect solution; we should consider keeping the DisplayRegions around until they have gone through the entire pipeline. Fixes #427 --- panda/src/display/graphicsEngine.cxx | 10 +++++----- panda/src/display/graphicsOutput.cxx | 26 +++++++++++++------------- panda/src/display/graphicsOutput.h | 1 + 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 57a592f05d..496a05e273 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -753,7 +753,7 @@ render_frame() { // frames, so we won't have to recompute it each frame. int num_drs = win->get_num_active_display_regions(); for (int i = 0; i < num_drs; ++i) { - DisplayRegion *dr = win->get_active_display_region(i); + PT(DisplayRegion) dr = win->get_active_display_region(i); if (dr != nullptr) { NodePath camera_np = dr->get_camera(current_thread); if (!camera_np.is_empty()) { @@ -1359,7 +1359,7 @@ is_scene_root(const PandaNode *node) { if (win->is_active() && win->get_gsg()->is_active()) { int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; i++) { - DisplayRegion *dr = win->get_active_display_region(i); + PT(DisplayRegion) dr = win->get_active_display_region(i); if (dr != nullptr) { NodePath camera = dr->get_camera(); if (camera.is_empty()) { @@ -1435,7 +1435,7 @@ cull_and_draw_together(GraphicsEngine::Windows wlist, int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; i++) { - DisplayRegion *dr = win->get_active_display_region(i); + PT(DisplayRegion) dr = win->get_active_display_region(i); if (dr != nullptr) { cull_and_draw_together(win, dr, current_thread); } @@ -1539,7 +1539,7 @@ cull_to_bins(GraphicsEngine::Windows wlist, Thread *current_thread) { PStatTimer timer(win->get_cull_window_pcollector(), current_thread); int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; ++i) { - DisplayRegion *dr = win->get_active_display_region(i); + PT(DisplayRegion) dr = win->get_active_display_region(i); if (dr != nullptr) { PT(SceneSetup) scene_setup; PT(CullResult) cull_result; @@ -1659,7 +1659,7 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { } int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; ++i) { - DisplayRegion *dr = win->get_active_display_region(i); + PT(DisplayRegion) dr = win->get_active_display_region(i); if (dr != nullptr) { do_draw(win, gsg, dr, current_thread); } diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index 7c6cef51cb..c8237059b8 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -697,9 +697,6 @@ void GraphicsOutput:: remove_all_display_regions() { LightMutexHolder holder(_lock); - CDWriter cdata(_cycler, true); - cdata->_active_display_regions_stale = true; - TotalDisplayRegions::iterator dri; for (dri = _total_display_regions.begin(); dri != _total_display_regions.end(); @@ -713,6 +710,12 @@ remove_all_display_regions() { } _total_display_regions.clear(); _total_display_regions.push_back(_overlay_display_region); + + OPEN_ITERATE_ALL_STAGES(_cycler) { + CDStageWriter cdata(_cycler, pipeline_stage); + cdata->_active_display_regions_stale = true; + } + CLOSE_ITERATE_ALL_STAGES(_cycler); } /** @@ -740,13 +743,8 @@ set_overlay_display_region(DisplayRegion *display_region) { */ int GraphicsOutput:: get_num_display_regions() const { - determine_display_regions(); - int result; - { - LightMutexHolder holder(_lock); - result = _total_display_regions.size(); - } - return result; + LightMutexHolder holder(_lock); + return _total_display_regions.size(); } /** @@ -1504,13 +1502,15 @@ do_remove_display_region(DisplayRegion *display_region) { find(_total_display_regions.begin(), _total_display_regions.end(), drp); if (dri != _total_display_regions.end()) { // Let's aggressively clean up the display region too. - CDWriter cdata(_cycler, true); display_region->cleanup(); display_region->_window = nullptr; _total_display_regions.erase(dri); - cdata->_active_display_regions_stale = true; - + OPEN_ITERATE_ALL_STAGES(_cycler) { + CDStageWriter cdata(_cycler, pipeline_stage); + cdata->_active_display_regions_stale = true; + } + CLOSE_ITERATE_ALL_STAGES(_cycler); return true; } diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index acd41e8289..f426b41bee 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -394,6 +394,7 @@ protected: typedef CycleDataLockedReader CDLockedReader; typedef CycleDataReader CDReader; typedef CycleDataWriter CDWriter; + typedef CycleDataStageWriter CDStageWriter; protected: int _creation_flags;