From b9d2b63125bfcdd3e027c0673c2cb58d69e26829 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Mon, 17 Sep 2012 00:55:29 +0200 Subject: 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. --- src/menu/gl_delayed_allocation.cpp | 94 ++++++++++++++++++++++++++++++++++++++ src/menu/gl_delayed_allocation.hpp | 65 ++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/menu/gl_delayed_allocation.cpp create mode 100644 src/menu/gl_delayed_allocation.hpp 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 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 initialized_lock(initialized_mutex); + if (initialized) { + { + boost::unique_lock 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 unique_lock(initialized_lock); + initialized = false; + } + else { + dispose_done.wait(initialized_lock); + } + } + } + + void GlDelayedAllocation::enable(void) + { + boost::upgrade_lock initialized_lock(initialized_mutex); + if (!initialized) { + this->gl_initialize(); + + boost::upgrade_to_unique_lock unique_lock(initialized_lock); + initialized = true; + } + } + + void GlDelayedAllocation::disable(void) + { + boost::upgrade_lock initialized_lock(initialized_mutex); + boost::upgrade_lock end_of_life_lock(end_of_life_mutex); + if (initialized && end_of_life) { + this->gl_cleanup(); + + { + boost::upgrade_to_unique_lock 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 +#include +#include + +#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 -- cgit v1.2.3