Fixed unnecessary creation of an irrlicht NULL device (one in file_manager,

one was created just to get the list of modes, before the actual device
is then created). This fixes a minor memory leak (the 2nd NULL device was not
freed), encapsulates all device creation into irr_driver (and not in 
file_manager).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9967 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-10-12 11:28:35 +00:00
parent aec6cf2b9a
commit a93d05d046
6 changed files with 114 additions and 131 deletions

View File

@ -62,17 +62,22 @@ const int MIN_SUPPORTED_HEIGHT = 600;
const int MIN_SUPPORTED_WIDTH = 800;
// ----------------------------------------------------------------------------
/** The constructor creates the irrlicht device. It first creates a NULL
* device. This is necessary to handle the Chicken/egg problem with irrlicht:
* access to the file system is given from the device, but we can't create the
* device before reading the user_config file (for resolution, fullscreen).
* So we create a dummy device here to begin with, which is then later (once
* the real device exists) changed in initDevice().
*/
IrrDriver::IrrDriver()
{
m_resolution_changing = RES_CHANGE_NONE;
m_device = NULL;
file_manager->dropFileSystem();
initDevice();
m_device = createDevice(video::EDT_NULL);
} // IrrDriver
// ----------------------------------------------------------------------------
/** Destructor - removes the irrlicht device.
*/
IrrDriver::~IrrDriver()
{
m_post_processing.shut();
@ -82,43 +87,44 @@ IrrDriver::~IrrDriver()
} // ~IrrDriver
// ----------------------------------------------------------------------------
/** Gets a list of supported video modes from the irrlicht device. This data
* is stored in m_modes.
*/
void IrrDriver::createListOfVideoModes()
{
video::IVideoModeList* modes = m_device->getVideoModeList();
const int count = modes->getVideoModeCount();
for(int i=0; i<count; i++)
{
// only consider 32-bit resolutions for now
if (modes->getVideoModeDepth(i) >= 24)
{
const int w = modes->getVideoModeResolution(i).Width;
const int h = modes->getVideoModeResolution(i).Height;
if (h < MIN_SUPPORTED_HEIGHT || w < MIN_SUPPORTED_WIDTH)
continue;
VideoMode mode(w, h);
m_modes.push_back( mode );
} // if depth >=24
} // for i < video modes count
} // createListOfVideoModes
// ----------------------------------------------------------------------------
/** This creates the actualy OpenGL device. This is called
*/
void IrrDriver::initDevice()
{
// If --no-graphics option was used, just create a device with NULL renderer
if (ProfileWorld::isNoGraphics())
// If --no-graphics option was used, the null device can still be used.
if (!ProfileWorld::isNoGraphics())
{
m_device = createDevice(video::EDT_NULL);
}
else
{
static bool firstTime = true;
// ---- the first time, get a list of available video modes
if (firstTime)
{
m_device = createDevice(video::EDT_NULL);
video::IVideoModeList* modes = m_device->getVideoModeList();
const int count = modes->getVideoModeCount();
for(int i=0; i<count; i++)
{
// only consider 32-bit resolutions for now
if (modes->getVideoModeDepth(i) >= 24)
{
const int w = modes->getVideoModeResolution(i).Width;
const int h = modes->getVideoModeResolution(i).Height;
if (h < MIN_SUPPORTED_HEIGHT || w < MIN_SUPPORTED_WIDTH)
continue;
VideoMode mode;
mode.width = w;
mode.height = h;
m_modes.push_back( mode );
}
}
// This code is only executed once. No need to reload the video
// modes every time the resolution changes.
if(m_modes.size()==0)
{
createListOfVideoModes();
// The debug name is only set if irrlicht is compiled in debug
// mode. So we use this to print a warning to the user.
if(m_device->getDebugName())
@ -127,78 +133,61 @@ void IrrDriver::initDevice()
printf("!!!!! This can have a significant performance impact !!!!!\n");
}
m_device->closeDevice();
// In some circumstances it would happen that a WM_QUIT message
// (apparently sent for this NULL device) is later received by
// the actual window, causing it to immediately quit.
// Following advise on the irrlicht forums I added the following
// two calles - the first one didn't make a difference (but
// certainly can't hurt), but the second one apparenlty solved
// the problem for now.
m_device->clearSystemMessages();
m_device->run();
firstTime = false;
} // end if firstTime
m_device->closeDevice();
m_video_driver = NULL;
m_gui_env = NULL;
m_scene_manager = NULL;
// In some circumstances it would happen that a WM_QUIT message
// (apparently sent for this NULL device) is later received by
// the actual window, causing it to immediately quit.
// Following advise on the irrlicht forums I added the following
// two calles - the first one didn't make a difference (but
// certainly can't hurt), but the second one apparenlty solved
// the problem for now.
m_device->clearSystemMessages();
m_device->run();
m_device->drop();
m_device = NULL;
int num_drivers = 5;
int numDrivers = 5;
// Test if user has chosen a driver or if we should try all to find a woring
// one.
if( UserConfigParams::m_renderer != 0 )
{
numDrivers = 1;
}
// Test if user has chosen a driver or if we should try all to find
// a working one.
if( UserConfigParams::m_renderer != 0 ) num_drivers = 1;
// ---- open device
// Try different drivers: start with opengl, then DirectX
for(int driver_type=0; driver_type<numDrivers; driver_type++)
for(int driver_type=0; driver_type<num_drivers; driver_type++)
{
video::E_DRIVER_TYPE type;
// Test if user has chosen a driver or if we should try all to find a
// woring one.
if( UserConfigParams::m_renderer != 0 )
{
// Get the correct type.
type = getEngineDriverType( UserConfigParams::m_renderer );
} else
{
// Get the correct type.
type = getEngineDriverType( driver_type );
}
type = getEngineDriverType(
UserConfigParams::m_renderer ? UserConfigParams::m_renderer
: driver_type );
// Try 32 and, upon failure, 24 then 16 bit per pixels
for (int bits=32; bits>15; bits -=8)
{
printf("[IrrDriver] Trying to create device with %i bits\n", bits);
/*
m_device = createDevice(type,
core::dimension2d<u32>(UserConfigParams::m_width,
UserConfigParams::m_height ),
bits, //bits per pixel
UserConfigParams::m_fullscreen,
false, // stencil buffers
false, // vsync
this // event receiver
);
*/
if(UserConfigParams::logMisc())
printf("[IrrDriver] Trying to create device with "
"%i bits\n", bits);
SIrrlichtCreationParameters params;
params.DriverType = type;
params.WindowSize = core::dimension2d<u32>(UserConfigParams::m_width,
UserConfigParams::m_height);
params.Bits = bits;
params.Stencilbuffer = false;
params.Bits = bits;
params.EventReceiver = this;
params.Fullscreen = UserConfigParams::m_fullscreen;
params.Fullscreen = UserConfigParams::m_fullscreen;
params.Vsync = UserConfigParams::m_vsync;
params.WindowSize =
core::dimension2du(UserConfigParams::m_width,
UserConfigParams::m_height);
if (UserConfigParams::m_fullscreen_antialiasing)
params.AntiAlias = 8;
params.Vsync = UserConfigParams::m_vsync;
m_device = createDeviceEx(params);
if(m_device) break;
@ -210,12 +199,12 @@ void IrrDriver::initDevice()
// size is the problem
if(!m_device)
{
UserConfigParams::m_width = 800;
UserConfigParams::m_width = 800;
UserConfigParams::m_height = 600;
m_device = createDevice(video::EDT_OPENGL,
core::dimension2d<u32>(UserConfigParams::m_width,
UserConfigParams::m_height ),
core::dimension2du(UserConfigParams::m_width,
UserConfigParams::m_height ),
32, //bits per pixel
UserConfigParams::m_fullscreen,
false, // stencil buffers
@ -259,7 +248,7 @@ void IrrDriver::initDevice()
}
// Stores the new file system pointer.
file_manager->setDevice(m_device);
file_manager->reInit();
// Initialize material2D
video::SMaterial& material2D = m_video_driver->getMaterial2D();
@ -410,18 +399,12 @@ void IrrDriver::applyResolutionSettings()
delete material_manager;
material_manager = NULL;
m_device->drop();
m_device = NULL;
m_video_driver = NULL;
m_gui_env = NULL;
m_scene_manager = NULL;
// ---- Reinit
// FIXME: this load sequence is (mostly) duplicated from main.cpp!! That'
// s just error prone
// FIXME: this load sequence is (mostly) duplicated from main.cpp!!
// That's just error prone
// (we're sure to update main.cpp at some point and forget this one...)
// initDevice will drop the current device.
initDevice();
// Re-init GUI engine
@ -462,7 +445,7 @@ void IrrDriver::applyResolutionSettings()
GUIEngine::reshowCurrentScreen();
} // changeResolution
} // applyResolutionSettings
// ----------------------------------------------------------------------------

View File

@ -50,11 +50,6 @@ class Camera;
class Kart;
class PerCameraNode;
struct VideoMode
{
int width, height;
};
/**
* \brief class that creates the irrLicht device and offers higher-level
* ways to manage the 3D scene
@ -85,6 +80,19 @@ private:
RES_CHANGE_CANCEL} m_resolution_changing;
void setAllMaterialFlags(scene::IMesh *mesh) const;
public:
/** A simple class to store video resolutions. */
class VideoMode
{
private:
int m_width;
int m_height;
public:
VideoMode(int w, int h) {m_width=w; m_height=h; }
int getWidth() const {return m_width; }
int getHeight() const {return m_height; }
}; // VideoMode
private:
std::vector<VideoMode> m_modes;
void setupViewports();
@ -95,6 +103,8 @@ private:
/** Internal method that applies the resolution in user settings. */
void applyResolutionSettings();
void createListOfVideoModes();
public:
IrrDriver();

View File

@ -124,13 +124,12 @@ FileManager::FileManager(char *argv[])
getcwd(buffer, 256);
#endif
m_device = createDevice(video::EDT_NULL);
#ifdef __APPLE__
chdir( buffer );
#endif
m_file_system = m_device->getFileSystem();
// CHECKME HIKER: is this grabbed???
m_file_system = irr_driver->getDevice()->getFileSystem();
m_is_full_path = false;
irr::io::path exe_path;
@ -171,28 +170,21 @@ FileManager::FileManager(char *argv[])
checkAndCreateAddonsDir();
} // FileManager
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/** Remove the dummy file system (which is called from IrrDriver before
* creating the actual device.
*/
void FileManager::dropFileSystem()
{
m_device->drop();
m_device = NULL;
} // dropFileSystem
//-----------------------------------------------------------------------------
/** This function is used to re-initialise the file-manager after reading in
* the user configuration data.
*/
void FileManager::setDevice(IrrlichtDevice *device)
void FileManager::reInit()
{
m_device = device;
//std::cout << "^^^^^^^^ GRABBING m_device (FileManager) ^^^^^^^^\n";
m_device->grab(); // To make sure that the device still exists while
// file_manager has a pointer to the file system.
m_file_system = m_device->getFileSystem();
m_file_system = irr_driver->getDevice()->getFileSystem();
TrackManager::addTrackSearchDir(m_root_dir+"/data/tracks");
KartPropertiesManager::addKartSearchDir(m_root_dir+"/data/karts");
pushTextureSearchPath(m_root_dir+"/data/textures/");
@ -264,7 +256,6 @@ FileManager::~FileManager()
popTextureSearchPath();
// m_file_system is ref-counted, so no delete/drop necessary.
m_file_system = NULL;
m_device->drop();
} // ~FileManager
//-----------------------------------------------------------------------------

View File

@ -45,10 +45,6 @@ class FileManager : public NoCopy
private:
/** Handle to irrlicht's file systems. */
io::IFileSystem *m_file_system;
/** Pointer to the irrlicht device. This is necessary before reInit is
* called to store the NULL device initially created. See Constructor
* for details. */
IrrlichtDevice *m_device;
bool m_is_full_path;
/** Directory where user config files are stored. */
@ -75,7 +71,7 @@ private:
public:
FileManager(char *argv[]);
~FileManager();
void setDevice(IrrlichtDevice *device);
void reInit();
void dropFileSystem();
io::IXMLReader *createXMLReader(const std::string &filename);
XMLNode *createXMLTree(const std::string &filename);

View File

@ -854,6 +854,7 @@ int handleCmdLine(int argc, char **argv)
*/
void initUserConfig(char *argv[])
{
irr_driver = new IrrDriver();
file_manager = new FileManager(argv);
user_config = new UserConfig(); // needs file_manager
const bool config_ok = user_config->loadConfig();
@ -886,7 +887,8 @@ void initRest()
{
stk_config->load(file_manager->getDataFile("stk_config.xml"));
irr_driver = new IrrDriver();
// Now create the actual non-null device in the irrlicht driver
irr_driver->initDevice();
// Init GUI
IrrlichtDevice* device = irr_driver->getDevice();

View File

@ -121,7 +121,8 @@ void OptionsScreenVideo::init()
{
res->clearItems();
const std::vector<VideoMode>& modes = irr_driver->getVideoModes();
const std::vector<IrrDriver::VideoMode>& modes =
irr_driver->getVideoModes();
const int amount = modes.size();
bool found_config_res = false;
@ -134,8 +135,8 @@ void OptionsScreenVideo::init()
for (int n=0; n<amount; n++)
{
const int w = modes[n].width;
const int h = modes[n].height;
const int w = modes[n].getWidth();
const int h = modes[n].getHeight();
const float ratio = (float)w / h;
if (w == UserConfigParams::m_width && h == UserConfigParams::m_height)