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
This commit is contained in:
rdb 2018-10-28 11:47:16 +01:00
parent da82087735
commit afc994b2fb
3 changed files with 19 additions and 18 deletions

View File

@ -753,7 +753,7 @@ render_frame() {
// frames, so we won't have to recompute it each frame. // frames, so we won't have to recompute it each frame.
int num_drs = win->get_num_active_display_regions(); int num_drs = win->get_num_active_display_regions();
for (int i = 0; i < num_drs; ++i) { 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) { if (dr != nullptr) {
NodePath camera_np = dr->get_camera(current_thread); NodePath camera_np = dr->get_camera(current_thread);
if (!camera_np.is_empty()) { if (!camera_np.is_empty()) {
@ -1359,7 +1359,7 @@ is_scene_root(const PandaNode *node) {
if (win->is_active() && win->get_gsg()->is_active()) { if (win->is_active() && win->get_gsg()->is_active()) {
int num_display_regions = win->get_num_active_display_regions(); int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) { 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) { if (dr != nullptr) {
NodePath camera = dr->get_camera(); NodePath camera = dr->get_camera();
if (camera.is_empty()) { 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(); int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; i++) { 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) { if (dr != nullptr) {
cull_and_draw_together(win, dr, current_thread); 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); PStatTimer timer(win->get_cull_window_pcollector(), current_thread);
int num_display_regions = win->get_num_active_display_regions(); int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) { 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) { if (dr != nullptr) {
PT(SceneSetup) scene_setup; PT(SceneSetup) scene_setup;
PT(CullResult) cull_result; 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(); int num_display_regions = win->get_num_active_display_regions();
for (int i = 0; i < num_display_regions; ++i) { 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) { if (dr != nullptr) {
do_draw(win, gsg, dr, current_thread); do_draw(win, gsg, dr, current_thread);
} }

View File

@ -697,9 +697,6 @@ void GraphicsOutput::
remove_all_display_regions() { remove_all_display_regions() {
LightMutexHolder holder(_lock); LightMutexHolder holder(_lock);
CDWriter cdata(_cycler, true);
cdata->_active_display_regions_stale = true;
TotalDisplayRegions::iterator dri; TotalDisplayRegions::iterator dri;
for (dri = _total_display_regions.begin(); for (dri = _total_display_regions.begin();
dri != _total_display_regions.end(); dri != _total_display_regions.end();
@ -713,6 +710,12 @@ remove_all_display_regions() {
} }
_total_display_regions.clear(); _total_display_regions.clear();
_total_display_regions.push_back(_overlay_display_region); _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:: int GraphicsOutput::
get_num_display_regions() const { get_num_display_regions() const {
determine_display_regions();
int result;
{
LightMutexHolder holder(_lock); LightMutexHolder holder(_lock);
result = _total_display_regions.size(); return _total_display_regions.size();
}
return result;
} }
/** /**
@ -1504,13 +1502,15 @@ do_remove_display_region(DisplayRegion *display_region) {
find(_total_display_regions.begin(), _total_display_regions.end(), drp); find(_total_display_regions.begin(), _total_display_regions.end(), drp);
if (dri != _total_display_regions.end()) { if (dri != _total_display_regions.end()) {
// Let's aggressively clean up the display region too. // Let's aggressively clean up the display region too.
CDWriter cdata(_cycler, true);
display_region->cleanup(); display_region->cleanup();
display_region->_window = nullptr; display_region->_window = nullptr;
_total_display_regions.erase(dri); _total_display_regions.erase(dri);
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
cdata->_active_display_regions_stale = true; cdata->_active_display_regions_stale = true;
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
return true; return true;
} }

View File

@ -394,6 +394,7 @@ protected:
typedef CycleDataLockedReader<CData> CDLockedReader; typedef CycleDataLockedReader<CData> CDLockedReader;
typedef CycleDataReader<CData> CDReader; typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter; typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageWriter<CData> CDStageWriter;
protected: protected:
int _creation_flags; int _creation_flags;