diff options
author | Alexander Sulfrian <alexander@sulfrian.net> | 2012-09-17 00:55:29 +0200 |
---|---|---|
committer | Alexander Sulfrian <alexander@sulfrian.net> | 2013-01-13 22:41:06 +0100 |
commit | b9d2b63125bfcdd3e027c0673c2cb58d69e26829 (patch) | |
tree | 3a81f9f65ea62709ff08f868d5ae1bb2ac516e4d /src | |
parent | 28d74542ba2f5073641e834c1ebb3eb937f2adcb (diff) | |
download | usdx-b9d2b63125bfcdd3e027c0673c2cb58d69e26829.tar.gz usdx-b9d2b63125bfcdd3e027c0673c2cb58d69e26829.tar.xz usdx-b9d2b63125bfcdd3e027c0673c2cb58d69e26829.zip |
menu/gl_delayed_allocation: add helper for opengl allocation
opengl allocation could not be done in the constructor of the opengl
objects. The opengl calls only have effect when called form the opengl
thread, but the objects could be constructed from other threads. The
analogous applies to the destruction. This helper handles the
allocation on first use from the opengl thread and frees the resources
while calling dispose before real destruction (see Disposable). If
dispose is called from the opengl thread, it frees the resources
immediately, but if dispose is called from another thread it
waits (blocks) until the next use from the opengl thread is complete.
Diffstat (limited to 'src')
-rw-r--r-- | src/menu/gl_delayed_allocation.cpp | 94 | ||||
-rw-r--r-- | src/menu/gl_delayed_allocation.hpp | 65 |
2 files changed, 159 insertions, 0 deletions
diff --git a/src/menu/gl_delayed_allocation.cpp b/src/menu/gl_delayed_allocation.cpp new file mode 100644 index 00000000..f30b15d5 --- /dev/null +++ b/src/menu/gl_delayed_allocation.cpp @@ -0,0 +1,94 @@ +/* + * UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "gl_delayed_allocation.hpp" +#include "application.hpp" + +namespace usdx +{ + log4cpp::Category& GlDelayedAllocation::log = + log4cpp::Category::getInstance("usdx.menu.gl_delayed_allocation"); + + GlDelayedAllocation::GlDelayedAllocation() + : initialized(false), end_of_life(false) + { + } + + GlDelayedAllocation::~GlDelayedAllocation() + { + boost::shared_lock<boost::shared_mutex> lock(initialized_mutex); + if (initialized) { + log << log4cpp::Priority::ERROR << "You forgot to call dispose, " + << "before destroying an object with GlDelayedAllocation"; + } + } + + void GlDelayedAllocation::do_dispose(void) + { + boost::upgrade_lock<boost::shared_mutex> initialized_lock(initialized_mutex); + if (initialized) { + { + boost::unique_lock<boost::shared_mutex> end_of_life_lock(end_of_life_mutex); + end_of_life = true; + } + + if (Application::is_gl_thread()) { + this->gl_cleanup(); + + boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(initialized_lock); + initialized = false; + } + else { + dispose_done.wait(initialized_lock); + } + } + } + + void GlDelayedAllocation::enable(void) + { + boost::upgrade_lock<boost::shared_mutex> initialized_lock(initialized_mutex); + if (!initialized) { + this->gl_initialize(); + + boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(initialized_lock); + initialized = true; + } + } + + void GlDelayedAllocation::disable(void) + { + boost::upgrade_lock<boost::shared_mutex> initialized_lock(initialized_mutex); + boost::upgrade_lock<boost::shared_mutex> end_of_life_lock(end_of_life_mutex); + if (initialized && end_of_life) { + this->gl_cleanup(); + + { + boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(initialized_lock); + initialized = false; + } + + dispose_done.notify_all(); + } + } +}; diff --git a/src/menu/gl_delayed_allocation.hpp b/src/menu/gl_delayed_allocation.hpp new file mode 100644 index 00000000..92fe3600 --- /dev/null +++ b/src/menu/gl_delayed_allocation.hpp @@ -0,0 +1,65 @@ +/* + * UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef GL_DELAYED_ALLOCATION_HPP +#define GL_DELAYED_ALLOCATION_HPP + +#include <log4cpp/Category.hh> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/condition.hpp> + +#include "utils/disposable.hpp" +#include "utils/activatable.hpp" +#include "drawable.hpp" + +namespace usdx +{ + class GlDelayedAllocation : public Activatable, public Disposable + { + private: + static log4cpp::Category& log; + + bool initialized; + bool end_of_life; + + boost::shared_mutex initialized_mutex; + boost::shared_mutex end_of_life_mutex; + boost::condition dispose_done; + + protected: + virtual void gl_initialize(void) = 0; + virtual void gl_cleanup(void) = 0; + + virtual void do_dispose(void); + + public: + GlDelayedAllocation(); + virtual ~GlDelayedAllocation(); + + virtual void enable(void); + virtual void disable(void); + }; +}; + +#endif |