aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2012-09-17 00:55:29 +0200
committerAlexander Sulfrian <alexander@sulfrian.net>2013-01-13 22:41:06 +0100
commitb9d2b63125bfcdd3e027c0673c2cb58d69e26829 (patch)
tree3a81f9f65ea62709ff08f868d5ae1bb2ac516e4d
parent28d74542ba2f5073641e834c1ebb3eb937f2adcb (diff)
downloadusdx-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.
-rw-r--r--src/menu/gl_delayed_allocation.cpp94
-rw-r--r--src/menu/gl_delayed_allocation.hpp65
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