]> git.sesse.net Git - casparcg/commitdiff
2.0.0.2: Ensure device -> host transfer has enough time to avoid blocking ogl thread.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 27 May 2011 20:52:24 +0000 (20:52 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Fri, 27 May 2011 20:52:24 +0000 (20:52 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@817 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/gpu/ogl_device.h
core/mixer/image/image_mixer.cpp
core/mixer/read_frame.cpp

index 7812165539c103a068df84754ed8f5454376eadb..3428f445227f7241ca9f7e7730cd994e72fcaa55 100644 (file)
@@ -57,15 +57,15 @@ class ogl_device
        }\r
        \r
        template<typename Func>\r
-       auto do_begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
+       auto do_begin_invoke(Func&& func, priority priority) -> boost::unique_future<decltype(func())> // noexcept\r
        {                       \r
-               return executor_.begin_invoke(std::forward<Func>(func));\r
+               return executor_.begin_invoke(std::forward<Func>(func), priority);\r
        }\r
        \r
        template<typename Func>\r
-       auto do_invoke(Func&& func) -> decltype(func())\r
+       auto do_invoke(Func&& func, priority priority) -> decltype(func())\r
        {\r
-               return executor_.invoke(std::forward<Func>(func));\r
+               return executor_.invoke(std::forward<Func>(func), priority);\r
        }\r
                \r
        safe_ptr<device_buffer> do_create_device_buffer(size_t width, size_t height, size_t stride);\r
@@ -73,15 +73,15 @@ class ogl_device
 public:                \r
        \r
        template<typename Func>\r
-       static auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
+       static auto begin_invoke(Func&& func, priority priority = normal_priority) -> boost::unique_future<decltype(func())> // noexcept\r
        {                       \r
-               return get_instance().do_begin_invoke(std::forward<Func>(func));\r
+               return get_instance().do_begin_invoke(std::forward<Func>(func), priority);\r
        }\r
        \r
        template<typename Func>\r
-       static auto invoke(Func&& func) -> decltype(func())\r
+       static auto invoke(Func&& func, priority priority = normal_priority) -> decltype(func())\r
        {\r
-               return get_instance().do_invoke(std::forward<Func>(func));\r
+               return get_instance().do_invoke(std::forward<Func>(func), priority);\r
        }\r
                \r
        static safe_ptr<device_buffer> create_device_buffer(size_t width, size_t height, size_t stride)\r
index 6be5505c72cbbed06719737cd7c2b1b948627708..5b59474c90e431c0b552335ad7d63125ee524a88 100644 (file)
@@ -61,6 +61,7 @@ struct image_mixer::implementation : boost::noncopyable
        \r
        image_kernel kernel_;\r
                        \r
+       safe_ptr<host_buffer>   read_buffer_;\r
        safe_ptr<device_buffer> draw_buffer_;\r
        safe_ptr<device_buffer> write_buffer_;\r
 \r
@@ -73,6 +74,7 @@ struct image_mixer::implementation : boost::noncopyable
 public:\r
        implementation(const core::video_format_desc& format_desc) \r
                : format_desc_(format_desc)\r
+               , read_buffer_(ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only))\r
                , draw_buffer_(ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4))\r
                , write_buffer_ (ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4))\r
                , local_key_buffer_(ogl_device::create_device_buffer(format_desc.width, format_desc.height, 1))\r
@@ -110,7 +112,13 @@ public:
 \r
        boost::unique_future<safe_ptr<const host_buffer>> render()\r
        {\r
-               auto result = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+               auto read_buffer = read_buffer_;\r
+\r
+               auto result = ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
+               {\r
+                       read_buffer->map(); // Might block.\r
+                       return read_buffer;\r
+               });\r
 \r
                auto render_queue = std::move(render_queue_);\r
 \r
@@ -148,18 +156,15 @@ public:
 \r
                        // Start transfer from device to host.\r
 \r
-                       draw_buffer_->write(*result);\r
+                       read_buffer_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+                       draw_buffer_->write(*read_buffer_);\r
 \r
                        std::swap(draw_buffer_, write_buffer_);\r
                });\r
 \r
                // While transferring do additional work which was queued during rendering.\r
                \r
-               return ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
-               {\r
-                       result->map(); // Might block.\r
-                       return result;\r
-               });\r
+               return std::move(result);\r
        }\r
        \r
        void draw(const render_item& item)\r
index 5c21b0601c73a5034731f6afa192ed476624d580..189980ce8775009aa44b26328383b15ff2e33b91 100644 (file)
@@ -34,6 +34,26 @@ public:
        implementation(boost::unique_future<safe_ptr<const 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
+\r
+       const boost::iterator_range<const uint8_t*> image_data()\r
+       {\r
+               try\r
+               {\r
+                       if(!image_data_.get()->data())\r
+                               return boost::iterator_range<const uint8_t*>();\r
+                       auto ptr = static_cast<const uint8_t*>(image_data_.get()->data());\r
+                       return boost::iterator_range<const uint8_t*>(ptr, ptr + image_data_.get()->size());\r
+               }\r
+               catch(...) // image_data_ future might store exception.\r
+               {\r
+                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       return boost::iterator_range<const uint8_t*>();\r
+               }\r
+       }\r
+       const boost::iterator_range<const int16_t*> audio_data() const\r
+       {\r
+               return boost::iterator_range<const int16_t*>(audio_data_.data(), audio_data_.data() + audio_data_.size());\r
+       }\r
 };\r
 \r
 read_frame::read_frame(boost::unique_future<safe_ptr<const host_buffer>>&& image_data, std::vector<int16_t>&& audio_data) \r
@@ -45,24 +65,7 @@ read_frame::read_frame(safe_ptr<const host_buffer>&& image_data, std::vector<int
        impl_.reset(new implementation(std::move(p.get_future()), std::move(audio_data)));\r
 }\r
 \r
-const boost::iterator_range<const uint8_t*> read_frame::image_data() const\r
-{\r
-       try\r
-       {\r
-               if(!impl_->image_data_.get()->data())\r
-                       return boost::iterator_range<const uint8_t*>();\r
-               auto ptr = static_cast<const uint8_t*>(impl_->image_data_.get()->data());\r
-               return boost::iterator_range<const uint8_t*>(ptr, ptr + impl_->image_data_.get()->size());\r
-       }\r
-       catch(...) // image_data_ future might store exception.\r
-       {\r
-               CASPAR_LOG_CURRENT_EXCEPTION();\r
-               return boost::iterator_range<const uint8_t*>();\r
-       }\r
-}\r
-const boost::iterator_range<const int16_t*> read_frame::audio_data() const\r
-{\r
-       return boost::iterator_range<const int16_t*>(impl_->audio_data_.data(), impl_->audio_data_.data() + impl_->audio_data_.size());\r
-}\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
 \r
 }}
\ No newline at end of file