Fixed resolution changing on linux: previously the resolution was
changed (and the old window/device deleted) while the old device was still actively delivering events, so deleting caused a crash. Now changing the resolution is only setting a flag, and the resolution change will be applied during the next update, i.e. while the device is not busy anymore. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@6707 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
fa80d310c5
commit
daf2bc5e7e
@ -52,8 +52,8 @@ const int MIN_SUPPORTED_WIDTH = 800;
|
|||||||
|
|
||||||
IrrDriver::IrrDriver()
|
IrrDriver::IrrDriver()
|
||||||
{
|
{
|
||||||
m_res_switching = false;
|
m_resolution_changing = RES_CHANGE_NONE;
|
||||||
m_device = NULL;
|
m_device = NULL;
|
||||||
file_manager->dropFileSystem();
|
file_manager->dropFileSystem();
|
||||||
initDevice();
|
initDevice();
|
||||||
} // IrrDriver
|
} // IrrDriver
|
||||||
@ -317,19 +317,22 @@ void IrrDriver::changeResolution(const int w, const int h, const bool fullscreen
|
|||||||
UserConfigParams::m_height = h;
|
UserConfigParams::m_height = h;
|
||||||
UserConfigParams::m_fullscreen = fullscreen;
|
UserConfigParams::m_fullscreen = fullscreen;
|
||||||
|
|
||||||
doApplyResSettings();
|
// Setting this flag will trigger a call to applyResolutionSetting()
|
||||||
|
// in the next update call. This avoids the problem that changeResolution
|
||||||
new ConfirmResolutionDialog();
|
// is actually called from the gui, i.e. the event loop, i.e. while the
|
||||||
}
|
// old device is active - so we can't delete this device (which we must
|
||||||
|
// do in applyResolutionSettings
|
||||||
|
m_resolution_changing = RES_CHANGE_YES;
|
||||||
|
} // changeResolution
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void IrrDriver::doApplyResSettings()
|
void IrrDriver::applyResolutionSettings()
|
||||||
{
|
{
|
||||||
m_res_switching = true;
|
// show black before resolution switch so we don't see OpenGL's buffer
|
||||||
|
// garbage during switch
|
||||||
// show black before resolution switch so we don't see OpenGL's buffer garbage during switch
|
m_device->getVideoDriver()->beginScene(true, true,
|
||||||
m_device->getVideoDriver()->beginScene(true, true, video::SColor(255,100,101,140));
|
video::SColor(255,100,101,140));
|
||||||
m_device->getVideoDriver()->draw2DRectangle( SColor(255, 0, 0, 0),
|
m_device->getVideoDriver()->draw2DRectangle( SColor(255, 0, 0, 0),
|
||||||
core::rect<s32>(0, 0,
|
core::rect<s32>(0, 0,
|
||||||
UserConfigParams::m_prev_width,
|
UserConfigParams::m_prev_width,
|
||||||
@ -407,8 +410,17 @@ void IrrDriver::cancelResChange()
|
|||||||
UserConfigParams::m_width = UserConfigParams::m_prev_width;
|
UserConfigParams::m_width = UserConfigParams::m_prev_width;
|
||||||
UserConfigParams::m_height = UserConfigParams::m_prev_height;
|
UserConfigParams::m_height = UserConfigParams::m_prev_height;
|
||||||
UserConfigParams::m_fullscreen = UserConfigParams::m_prev_fullscreen;
|
UserConfigParams::m_fullscreen = UserConfigParams::m_prev_fullscreen;
|
||||||
|
|
||||||
doApplyResSettings();
|
// This will trigger calling applyResolutionSettings in update(). This is
|
||||||
|
// necessary to avoid that the old screen is deleted, while it is
|
||||||
|
// still active (i.e. sending out events which triggered the change
|
||||||
|
// of resolution // Setting this flag will trigger a call to applyResolutionSetting()
|
||||||
|
// in the next update call. This avoids the problem that changeResolution
|
||||||
|
// is actually called from the gui, i.e. the event loop, i.e. while the
|
||||||
|
// old device is active - so we can't delete this device (which we must
|
||||||
|
// do in applyResolutionSettings)
|
||||||
|
m_resolution_changing=RES_CHANGE_CANCEL;
|
||||||
|
|
||||||
} // cancelResChange
|
} // cancelResChange
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -420,15 +432,15 @@ void IrrDriver::printRenderStats()
|
|||||||
{
|
{
|
||||||
io::IAttributes * attr = m_scene_manager->getParameters();
|
io::IAttributes * attr = m_scene_manager->getParameters();
|
||||||
printf("[%ls], FPS:%3d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)\n",
|
printf("[%ls], FPS:%3d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)\n",
|
||||||
m_video_driver->getName(),
|
m_video_driver->getName(),
|
||||||
m_video_driver->getFPS (),
|
m_video_driver->getFPS (),
|
||||||
(f32) m_video_driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ),
|
(f32) m_video_driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ),
|
||||||
attr->getAttributeAsInt ( "culled" ),
|
attr->getAttributeAsInt ( "culled" ),
|
||||||
attr->getAttributeAsInt ( "calls" ),
|
attr->getAttributeAsInt ( "calls" ),
|
||||||
attr->getAttributeAsInt ( "drawn_solid" ),
|
attr->getAttributeAsInt ( "drawn_solid" ),
|
||||||
attr->getAttributeAsInt ( "drawn_transparent" ),
|
attr->getAttributeAsInt ( "drawn_transparent" ),
|
||||||
attr->getAttributeAsInt ( "drawn_transparent_effect" )
|
attr->getAttributeAsInt ( "drawn_transparent_effect" )
|
||||||
);
|
);
|
||||||
|
|
||||||
} // printRenderStats
|
} // printRenderStats
|
||||||
|
|
||||||
@ -818,16 +830,22 @@ void IrrDriver::displayFPS()
|
|||||||
*/
|
*/
|
||||||
void IrrDriver::update(float dt)
|
void IrrDriver::update(float dt)
|
||||||
{
|
{
|
||||||
|
// If the resolution should be switched, do it now. This will delete the
|
||||||
|
// old device and create a new one.
|
||||||
|
if (m_resolution_changing!=RES_CHANGE_NONE)
|
||||||
|
{
|
||||||
|
applyResolutionSettings();
|
||||||
|
if(m_resolution_changing==RES_CHANGE_YES)
|
||||||
|
new ConfirmResolutionDialog();
|
||||||
|
m_resolution_changing = RES_CHANGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!m_device->run())
|
if (!m_device->run())
|
||||||
{
|
{
|
||||||
// FIXME: I have NO idea why, after performing resolution switch, the irrlicht device asks once to be deleted
|
main_loop->abort();
|
||||||
if (m_res_switching) m_res_switching = false;
|
|
||||||
else main_loop->abort();
|
|
||||||
}
|
|
||||||
else if (m_res_switching)
|
|
||||||
{
|
|
||||||
m_res_switching = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
World *world = World::getWorld();
|
World *world = World::getWorld();
|
||||||
|
|
||||||
|
@ -60,9 +60,13 @@ private:
|
|||||||
/** Irrlicht race font. */
|
/** Irrlicht race font. */
|
||||||
irr::gui::IGUIFont *m_race_font;
|
irr::gui::IGUIFont *m_race_font;
|
||||||
|
|
||||||
/** Flag set during resolution switching, so that the game doesn't think it needs
|
/** Flag to indicate if a resolution change is pending (which will be
|
||||||
* to exit because no frame is open */
|
* acted upon in the next update). None means no change, yes means
|
||||||
bool m_res_switching;
|
* change to new resolution and trigger confirmation dialog.
|
||||||
|
* Cancel indicates a change of the resolution (back to the original
|
||||||
|
* one), but no confirmation dialog. */
|
||||||
|
enum {RES_CHANGE_NONE, RES_CHANGE_YES,
|
||||||
|
RES_CHANGE_CANCEL} m_resolution_changing;
|
||||||
|
|
||||||
void setAllMaterialFlags(scene::IAnimatedMesh *mesh) const;
|
void setAllMaterialFlags(scene::IAnimatedMesh *mesh) const;
|
||||||
std::vector<VideoMode> m_modes;
|
std::vector<VideoMode> m_modes;
|
||||||
@ -74,7 +78,7 @@ private:
|
|||||||
bool m_pointer_shown;
|
bool m_pointer_shown;
|
||||||
|
|
||||||
/** Internal method that applies the resolution in user settings. */
|
/** Internal method that applies the resolution in user settings. */
|
||||||
void doApplyResSettings();
|
void applyResolutionSettings();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IrrDriver();
|
IrrDriver();
|
||||||
@ -136,7 +140,7 @@ public:
|
|||||||
|
|
||||||
/** Call to change resolution */
|
/** Call to change resolution */
|
||||||
void changeResolution(const int w, const int h, const bool fullscreen);
|
void changeResolution(const int w, const int h, const bool fullscreen);
|
||||||
/** Call this to roll back to the previous resolution if a resolution switch attempt goes bad */
|
/** Call this to roll back to the previous resolution if a resolution switch attempt goes bad */
|
||||||
void cancelResChange();
|
void cancelResChange();
|
||||||
|
|
||||||
void showPointer();
|
void showPointer();
|
||||||
|
Loading…
Reference in New Issue
Block a user