]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Fixed leaking gpu-buffers.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 10 Jun 2011 14:01:03 +0000 (14:01 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 10 Jun 2011 14:01:03 +0000 (14:01 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@875 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

14 files changed:
common/concurrency/executor.h
common/exception/exceptions.h
common/gl/gl_check.cpp
core/consumer/output.cpp
core/mixer/gpu/device_buffer.cpp
core/mixer/gpu/host_buffer.cpp
core/mixer/gpu/ogl_device.cpp
core/mixer/gpu/ogl_device.h
core/mixer/image/image_mixer.cpp
core/mixer/mixer.cpp
core/mixer/read_frame.cpp
core/mixer/read_frame.h
core/mixer/write_frame.cpp
modules/bluefish/util/blue_velvet.cpp

index 45c452f261348e8922b6e346b8d757ec5c443115..87fd167bce85d4fb129cefbcc90dffa500b73417 100644 (file)
@@ -208,11 +208,7 @@ public:
                        {\r
                                try{task_adaptor.value();}\r
                                catch(boost::task_already_started&){}\r
-                               catch(...)\r
-                               {\r
-                                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-                                       throw;\r
-                               }\r
+                               catch(...){CASPAR_LOG_CURRENT_EXCEPTION();}\r
                        });\r
                }\r
                \r
@@ -273,7 +269,16 @@ private:
                win32_exception::install_handler();             \r
                detail::SetThreadName(GetCurrentThreadId(), name_.c_str());\r
                while(is_running_)\r
-                       execute();\r
+               {\r
+                       try\r
+                       {\r
+                               execute();\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       }\r
+               }\r
        }       \r
 };\r
 \r
index e9b99a33681e2b86d560c28a2829b2860ac692be..5fe033ba86aadaba1c94ba69ca20f142a12e6be5 100644 (file)
@@ -31,6 +31,7 @@ typedef boost::error_info<struct tag_arg_value_info, std::string>             arg_value_inf
 typedef boost::error_info<struct tag_msg_info, std::string>                            msg_info;\r
 typedef boost::error_info<struct tag_errorstr, std::string>                            errorstr;\r
 typedef boost::error_info<struct tag_source_info, std::string>                 source_info;\r
+typedef boost::error_info<struct tag_line_info, size_t>                                line_info;\r
 typedef boost::error_info<struct errinfo_nested_exception_, std::exception_ptr> errinfo_nested_exception;\r
 \r
 struct caspar_exception                        : virtual boost::exception, virtual std::exception \r
index caa0ef48211ba15c3df2281dcf2183d7ad645f66..659c7adc1c00a8d1f874aba19b692e6161fc6194 100644 (file)
 \r
 namespace caspar { namespace gl {      \r
 \r
-void SMFL_GLCheckError(const std::string& expr, const std::string& File, unsigned int Line)\r
+void SMFL_GLCheckError(const std::string& expr, const std::string& file, unsigned int line)\r
 {\r
        // Get the last error\r
        GLenum ErrorCode = glGetError();\r
 \r
        if (ErrorCode != GL_NO_ERROR)\r
        {\r
-               std::string Error = "unknown error";\r
-               std::string Desc  = "no description";\r
-\r
                // Decode the error code\r
                switch (ErrorCode)\r
                {\r
                        case GL_INVALID_ENUM :\r
                                BOOST_THROW_EXCEPTION(ogl_invalid_enum()\r
                                        << msg_info("an unacceptable value has been specified for an enumerated argument")\r
-                                       << errorstr("GL_INVALID_ENUM"));\r
+                                       << errorstr("GL_INVALID_ENUM")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_INVALID_VALUE :\r
                                BOOST_THROW_EXCEPTION(ogl_invalid_value()\r
                                        << msg_info("a numeric argument is out of range")\r
-                                       << errorstr("GL_INVALID_VALUE"));\r
+                                       << errorstr("GL_INVALID_VALUE")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_INVALID_OPERATION :\r
                                BOOST_THROW_EXCEPTION(ogl_invalid_operation()\r
                                        << msg_info("the specified operation is not allowed in the current state")\r
-                                       << errorstr("GL_INVALID_OPERATION"));\r
+                                       << errorstr("GL_INVALID_OPERATION")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_STACK_OVERFLOW :\r
                                BOOST_THROW_EXCEPTION(ogl_stack_overflow()\r
                                        << msg_info("this command would cause a stack overflow")\r
-                                       << errorstr("GL_STACK_OVERFLOW"));\r
+                                       << errorstr("GL_STACK_OVERFLOW")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_STACK_UNDERFLOW :\r
                                BOOST_THROW_EXCEPTION(ogl_stack_underflow()\r
                                        << msg_info("this command would cause a stack underflow")\r
-                                       << errorstr("GL_STACK_UNDERFLOW"));\r
+                                       << errorstr("GL_STACK_UNDERFLOW")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_OUT_OF_MEMORY :\r
                                BOOST_THROW_EXCEPTION(ogl_stack_underflow()\r
                                        << msg_info("there is not enough memory left to execute the command")\r
-                                       << errorstr("GL_OUT_OF_MEMORY"));\r
+                                       << errorstr("GL_OUT_OF_MEMORY")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
 \r
                        case GL_INVALID_FRAMEBUFFER_OPERATION_EXT :\r
                                BOOST_THROW_EXCEPTION(ogl_stack_underflow()\r
                                        << msg_info("the object bound to FRAMEBUFFER_BINDING_EXT is not \"framebuffer complete\"")\r
-                                       << errorstr("GL_INVALID_FRAMEBUFFER_OPERATION_EXT"));\r
+                                       << errorstr("GL_INVALID_FRAMEBUFFER_OPERATION_EXT")\r
+                                       << line_info(line)\r
+                                       << source_info(file));\r
                }\r
        }\r
 }\r
index 23661e09fdd5b05014e97077767d2056f7282dbb..2f779325ecf8a8e3fb05e901e765268864424626 100644 (file)
@@ -142,7 +142,7 @@ private:
                        auto key_data = channel_.ogl().create_host_buffer(frame->image_data().size(), host_buffer::write_only);                         \r
                        fast_memsfhl(key_data->data(), frame->image_data().begin(), frame->image_data().size(), 0x0F0F0F0F, 0x0B0B0B0B, 0x07070707, 0x03030303);\r
                        std::vector<int16_t> audio_data(frame->audio_data().begin(), frame->audio_data().end());\r
-                       return make_safe<read_frame>(std::move(key_data), std::move(audio_data));\r
+                       return make_safe<read_frame>(channel_.ogl(), std::move(key_data), std::move(audio_data));\r
                }\r
                \r
                return make_safe<read_frame>();\r
index 2dc0f9fc353a3fb6c8cde5a409e930829d035951..ccf9d470d6d178fce02bf24c99bac645c85aedd8 100644 (file)
@@ -55,7 +55,14 @@ public:
 \r
        ~implementation()\r
        {\r
-               GL(glDeleteTextures(1, &id_));\r
+               try\r
+               {\r
+                       GL(glDeleteTextures(1, &id_));\r
+               }\r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+               }\r
        }\r
        \r
        void bind()\r
index d9fe6933545dd28e1e3e9a9b418ba1899f3fa1cf..1c8a2841f0a88798c5eec5205ae7e4bb55915aa9 100644 (file)
@@ -57,7 +57,14 @@ public:
 \r
        ~implementation()\r
        {\r
-               GL(glDeleteBuffers(1, &pbo_));\r
+               try\r
+               {\r
+                       GL(glDeleteBuffers(1, &pbo_));\r
+               }\r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+               }\r
        }\r
 \r
        void map()\r
index 121b9e59a61cf77c97797b49ca28cc133b817cd4..b77411770c377ebf563dc8a749a34cb87721742e 100644 (file)
@@ -57,7 +57,7 @@ safe_ptr<device_buffer> ogl_device::create_device_buffer(size_t width, size_t he
 {\r
        CASPAR_VERIFY(stride > 0 && stride < 5);\r
        CASPAR_VERIFY(width > 0 && height > 0);\r
-       auto pool = &device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
+       auto pool = device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
        std::shared_ptr<device_buffer> buffer;\r
        if(!pool->try_pop(buffer))              \r
        {\r
@@ -72,17 +72,25 @@ safe_ptr<device_buffer> ogl_device::create_device_buffer(size_t width, size_t he
                                CASPAR_LOG(error) << L"ogl: create_device_buffer failed!";\r
                                throw;\r
                        }\r
+\r
                }, high_priority);      \r
        }\r
                        \r
-       return safe_ptr<device_buffer>(buffer.get(), [=](device_buffer*){pool->push(buffer);});\r
+       return safe_ptr<device_buffer>(buffer.get(), [=](device_buffer*)\r
+       {\r
+               executor_.begin_invoke([=]\r
+               {\r
+                       pool->push(buffer);\r
+\r
+               }, high_priority);\r
+       });\r
 }\r
        \r
 safe_ptr<host_buffer> ogl_device::create_host_buffer(size_t size, host_buffer::usage_t usage)\r
 {\r
        CASPAR_VERIFY(usage == host_buffer::write_only || usage == host_buffer::read_only);\r
        CASPAR_VERIFY(size > 0);\r
-       auto pool = &host_pools_[usage][size];\r
+       auto pool = host_pools_[usage][size];\r
        std::shared_ptr<host_buffer> buffer;\r
        if(!pool->try_pop(buffer))\r
        {\r
@@ -127,16 +135,22 @@ void ogl_device::yield()
 \r
 boost::unique_future<void> ogl_device::gc()\r
 {\r
-       //CASPAR_LOG(info) << " ogl: Running GC.";\r
-\r
-       //return begin_invoke([=]\r
-       //{             \r
-       //      BOOST_FOREACH(auto& pool, device_pools_)\r
-       //              pool.clear();\r
-       //      BOOST_FOREACH(auto& pool, host_pools_)\r
-       //              pool.clear();\r
-       //}, high_priority);\r
-       return begin_invoke([=]{});\r
+       CASPAR_LOG(info) << " ogl: Running GC.";\r
+\r
+       return begin_invoke([=]\r
+       {               \r
+               try\r
+               {\r
+                       BOOST_FOREACH(auto& pool, device_pools_)\r
+                               pool.clear();\r
+                       BOOST_FOREACH(auto& pool, host_pools_)\r
+                               pool.clear();\r
+               }\r
+               catch(...)\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+               }\r
+       }, high_priority);\r
 }\r
 \r
 std::wstring ogl_device::get_version()\r
index bd912a878e20d2f3bf017c0c3ca5ef833b8a9a7c..5d6e55a6d1811acf01d55a7f3f91b4244581b6b3 100644 (file)
@@ -41,8 +41,8 @@ class ogl_device : boost::noncopyable
 {      \r
        std::unique_ptr<sf::Context> context_;\r
        \r
-       std::array<tbb::concurrent_unordered_map<size_t, tbb::concurrent_bounded_queue<std::shared_ptr<device_buffer>>>, 4> device_pools_;\r
-       std::array<tbb::concurrent_unordered_map<size_t, tbb::concurrent_bounded_queue<std::shared_ptr<host_buffer>>>, 2> host_pools_;\r
+       std::array<tbb::concurrent_unordered_map<size_t, safe_ptr<tbb::concurrent_bounded_queue<std::shared_ptr<device_buffer>>>>, 4> device_pools_;\r
+       std::array<tbb::concurrent_unordered_map<size_t, safe_ptr<tbb::concurrent_bounded_queue<std::shared_ptr<host_buffer>>>>, 2> host_pools_;\r
        \r
        unsigned int fbo_;\r
 \r
index bb196fe286f434af14113a1ef5aba237ce7bbc36..7cbd325490354cae2768495aa2f5edc9938d54a5 100644 (file)
@@ -92,7 +92,7 @@ public:
                                CASPAR_LOG(warning) << "Missing OpenGL 3.0 support.";//BOOST_THROW_EXCEPTION(not_supported() << msg_info("Missing OpenGL 3.0 support."));\r
                });\r
        }\r
-       \r
+\r
        void begin(const core::basic_frame& frame)\r
        {\r
                transform_stack_.push(transform_stack_.top()*frame.get_image_transform());\r
index 2967b66c70ce41abc12679345ea2c4e7b00b9cf3..3e86515ba8e272768eab08498a19aa6b142afa1e 100644 (file)
@@ -113,7 +113,7 @@ public:
                        auto image = mix_image(frames);\r
                        auto audio = mix_audio(frames);\r
                        \r
-                       return make_safe<read_frame>(std::move(image), std::move(audio));\r
+                       return make_safe<read_frame>(channel_.ogl(), std::move(image), std::move(audio));\r
                }\r
                catch(...)\r
                {\r
index eea6d6ccaa7dd773cf7471431494686592e20e6c..0a6d2a2c3909d78117c7131eef512c1be462d68c 100644 (file)
@@ -22,6 +22,7 @@
 #include "read_frame.h"\r
 \r
 #include "gpu/host_buffer.h"   \r
+#include "gpu/ogl_device.h"\r
 \r
 namespace caspar { namespace core {\r
                                                                                                                                                                                                                                                                                                                        \r
@@ -29,13 +30,21 @@ struct read_frame::implementation : boost::noncopyable
 {\r
        std::shared_ptr<host_buffer> image_data_;\r
        std::vector<int16_t> audio_data_;\r
+       ogl_device& ogl_;\r
 \r
 public:\r
-       implementation(){}\r
-\r
-       implementation(safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
+       implementation(ogl_device& ogl, safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
                : image_data_(std::move(image_data))\r
-               , audio_data_(std::move(audio_data)){}  \r
+               , audio_data_(std::move(audio_data))\r
+               , ogl_(ogl){}   \r
+\r
+       ~implementation()\r
+       {\r
+               ogl_.invoke([this]\r
+               {\r
+                       image_data_.reset();\r
+               });\r
+       }\r
 \r
        const boost::iterator_range<const uint8_t*> image_data()\r
        {\r
@@ -51,11 +60,17 @@ public:
        }\r
 };\r
 \r
-read_frame::read_frame(safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
-       : impl_(new implementation(std::move(image_data), std::move(audio_data))){}\r
-read_frame::read_frame()\r
-       : impl_(new implementation()){}\r
-const boost::iterator_range<const uint8_t*> read_frame::image_data() const{return impl_->image_data();}\r
-const boost::iterator_range<const int16_t*> read_frame::audio_data() const{return impl_->audio_data();}\r
+read_frame::read_frame(ogl_device& ogl, safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data) \r
+       : impl_(new implementation(ogl, std::move(image_data), std::move(audio_data))){}\r
+read_frame::read_frame(){}\r
+const boost::iterator_range<const uint8_t*> read_frame::image_data() const\r
+{\r
+       return impl_ ? impl_->image_data() : boost::iterator_range<const uint8_t*>();\r
+}\r
+\r
+const boost::iterator_range<const int16_t*> read_frame::audio_data() const\r
+{\r
+       return impl_ ? impl_->audio_data() : boost::iterator_range<const int16_t*>();\r
+}\r
 \r
 }}
\ No newline at end of file
index a768cc0c209325a2e2065b1659368673ca11efa5..f25d766ede4a93c4c8fd0531767917ed574690e3 100644 (file)
@@ -37,7 +37,7 @@ class read_frame : boost::noncopyable
 {\r
 public:\r
        read_frame();\r
-       read_frame(safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data);\r
+       read_frame(ogl_device& ogl, safe_ptr<host_buffer>&& image_data, std::vector<int16_t>&& audio_data);\r
 \r
        virtual const boost::iterator_range<const uint8_t*> image_data() const;\r
        virtual const boost::iterator_range<const int16_t*> audio_data() const;\r
index 2d7a70775479bc36a4036e70d4e777469e3b719e..a9917c119dbbf954cb9638b0d669632b360534f1 100644 (file)
@@ -55,7 +55,16 @@ public:
                        {\r
                                return ogl_.create_device_buffer(plane.width, plane.height, plane.channels);\r
                        });\r
-               });\r
+               }, high_priority);\r
+       }\r
+\r
+       ~implementation()\r
+       {\r
+               ogl_.invoke([=]\r
+               {\r
+                       buffers_.clear();\r
+                       textures_.clear();\r
+               }, high_priority);\r
        }\r
        \r
        void accept(write_frame& self, core::frame_visitor& visitor)\r
index ca7eb42af0f1d90b9ff17439cb087f39b7cb96bb..1525d3d7722b26d1fb58dcff592f46bc5ebfb257 100644 (file)
@@ -141,7 +141,7 @@ EVideoMode get_video_mode(CBlueVelvet4& blue, const core::video_format_desc& for
                        vid_fmt = videoMode;                    \r
        }\r
        if(vid_fmt == VID_FMT_INVALID)\r
-               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed get videomode.") << arg_value_info(narrow(format_desc.name)));\r
+               BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("vide-omode not supported.") << arg_value_info(narrow(format_desc.name)));\r
 \r
        return vid_fmt;\r
 }\r