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()
|
||||
{
|
||||
m_res_switching = false;
|
||||
m_device = NULL;
|
||||
m_resolution_changing = RES_CHANGE_NONE;
|
||||
m_device = NULL;
|
||||
file_manager->dropFileSystem();
|
||||
initDevice();
|
||||
} // IrrDriver
|
||||
@ -317,19 +317,22 @@ void IrrDriver::changeResolution(const int w, const int h, const bool fullscreen
|
||||
UserConfigParams::m_height = h;
|
||||
UserConfigParams::m_fullscreen = fullscreen;
|
||||
|
||||
doApplyResSettings();
|
||||
|
||||
new ConfirmResolutionDialog();
|
||||
}
|
||||
// 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_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
|
||||
m_device->getVideoDriver()->beginScene(true, true, video::SColor(255,100,101,140));
|
||||
// show black before resolution switch so we don't see OpenGL's buffer
|
||||
// garbage during switch
|
||||
m_device->getVideoDriver()->beginScene(true, true,
|
||||
video::SColor(255,100,101,140));
|
||||
m_device->getVideoDriver()->draw2DRectangle( SColor(255, 0, 0, 0),
|
||||
core::rect<s32>(0, 0,
|
||||
UserConfigParams::m_prev_width,
|
||||
@ -407,8 +410,17 @@ void IrrDriver::cancelResChange()
|
||||
UserConfigParams::m_width = UserConfigParams::m_prev_width;
|
||||
UserConfigParams::m_height = UserConfigParams::m_prev_height;
|
||||
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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -420,15 +432,15 @@ void IrrDriver::printRenderStats()
|
||||
{
|
||||
io::IAttributes * attr = m_scene_manager->getParameters();
|
||||
printf("[%ls], FPS:%3d Tri:%.03fm Cull %d/%d nodes (%d,%d,%d)\n",
|
||||
m_video_driver->getName(),
|
||||
m_video_driver->getFPS (),
|
||||
(f32) m_video_driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ),
|
||||
attr->getAttributeAsInt ( "culled" ),
|
||||
attr->getAttributeAsInt ( "calls" ),
|
||||
attr->getAttributeAsInt ( "drawn_solid" ),
|
||||
attr->getAttributeAsInt ( "drawn_transparent" ),
|
||||
attr->getAttributeAsInt ( "drawn_transparent_effect" )
|
||||
);
|
||||
m_video_driver->getName(),
|
||||
m_video_driver->getFPS (),
|
||||
(f32) m_video_driver->getPrimitiveCountDrawn( 0 ) * ( 1.f / 1000000.f ),
|
||||
attr->getAttributeAsInt ( "culled" ),
|
||||
attr->getAttributeAsInt ( "calls" ),
|
||||
attr->getAttributeAsInt ( "drawn_solid" ),
|
||||
attr->getAttributeAsInt ( "drawn_transparent" ),
|
||||
attr->getAttributeAsInt ( "drawn_transparent_effect" )
|
||||
);
|
||||
|
||||
} // printRenderStats
|
||||
|
||||
@ -818,16 +830,22 @@ void IrrDriver::displayFPS()
|
||||
*/
|
||||
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())
|
||||
{
|
||||
// FIXME: I have NO idea why, after performing resolution switch, the irrlicht device asks once to be deleted
|
||||
if (m_res_switching) m_res_switching = false;
|
||||
else main_loop->abort();
|
||||
}
|
||||
else if (m_res_switching)
|
||||
{
|
||||
m_res_switching = false;
|
||||
main_loop->abort();
|
||||
}
|
||||
|
||||
|
||||
World *world = World::getWorld();
|
||||
|
||||
|
@ -60,9 +60,13 @@ private:
|
||||
/** Irrlicht race font. */
|
||||
irr::gui::IGUIFont *m_race_font;
|
||||
|
||||
/** Flag set during resolution switching, so that the game doesn't think it needs
|
||||
* to exit because no frame is open */
|
||||
bool m_res_switching;
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
* acted upon in the next update). None means no change, yes means
|
||||
* 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;
|
||||
std::vector<VideoMode> m_modes;
|
||||
@ -74,7 +78,7 @@ private:
|
||||
bool m_pointer_shown;
|
||||
|
||||
/** Internal method that applies the resolution in user settings. */
|
||||
void doApplyResSettings();
|
||||
void applyResolutionSettings();
|
||||
|
||||
public:
|
||||
IrrDriver();
|
||||
@ -136,7 +140,7 @@ public:
|
||||
|
||||
/** Call to change resolution */
|
||||
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 showPointer();
|
||||
|
Loading…
Reference in New Issue
Block a user