}\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
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
\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
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
\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
\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
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
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