size_t rest = count & 2047;\r
count &= ~2047;\r
\r
+ tbb::affinity_partitioner ap;\r
tbb::parallel_for(tbb::blocked_range<size_t>(0, count/128), [&](const tbb::blocked_range<size_t>& r)\r
{ \r
fast_memcpy_aligned_impl(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128); \r
- });\r
+ }, ap);\r
\r
return fast_memcpy_small_aligned(dest8+count, source8+count, rest);\r
}\r
size_t rest = count & 2047;\r
count &= ~2047;\r
\r
+ tbb::affinity_partitioner ap;\r
tbb::parallel_for(tbb::blocked_range<size_t>(0, count/128), [&](const tbb::blocked_range<size_t>& r)\r
{ \r
fast_memcpy_unaligned_impl(reinterpret_cast<char*>(dest) + r.begin()*128, reinterpret_cast<const char*>(source) + r.begin()*128, r.size()*128); \r
- });\r
+ }, ap);\r
\r
return fast_memcpy_small_unaligned(dest8+count, source8+count, rest);\r
}\r
\r
//++pool->usage_count;\r
\r
+ auto self = shared_from_this();\r
return safe_ptr<host_buffer>(buffer.get(), [=](host_buffer*) mutable\r
{\r
- executor_.begin_invoke([=]() mutable\r
+ self->executor_.begin_invoke([=]() mutable\r
{ \r
if(usage == host_buffer::write_only)\r
buffer->map();\r
});\r
}\r
\r
+safe_ptr<ogl_device> ogl_device::create()\r
+{\r
+ return safe_ptr<ogl_device>(new ogl_device());\r
+}\r
+\r
//template<typename T>\r
//void flush_pool(buffer_pool<T>& pool)\r
//{ \r
}\r
};\r
\r
-class ogl_device : boost::noncopyable\r
+class ogl_device : public std::enable_shared_from_this<ogl_device>, boost::noncopyable\r
{ \r
std::unordered_map<GLenum, bool> caps_;\r
std::array<size_t, 4> viewport_;\r
\r
executor executor_;\r
\r
-public: \r
ogl_device();\r
+public: \r
+ static safe_ptr<ogl_device> create();\r
~ogl_device();\r
\r
// Not thread-safe, must be called inside of context\r
\r
class image_renderer\r
{\r
- ogl_device& ogl_;\r
+ safe_ptr<ogl_device> ogl_;\r
const video_format_desc format_desc_;\r
image_kernel kernel_; \r
std::shared_ptr<device_buffer> transferring_buffer_;\r
public:\r
- image_renderer(ogl_device& ogl, const video_format_desc& format_desc)\r
+ image_renderer(const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc)\r
: ogl_(ogl)\r
, format_desc_(format_desc)\r
{\r
boost::unique_future<safe_ptr<host_buffer>> operator()(std::vector<layer>&& layers)\r
{ \r
auto layers2 = make_move_on_copy(std::move(layers));\r
- return ogl_.begin_invoke([=]\r
+ return ogl_->begin_invoke([=]\r
{\r
return do_render(std::move(layers2.value));\r
});\r
draw(std::move(layers), draw_buffer);\r
}\r
\r
- auto host_buffer = ogl_.create_host_buffer(format_desc_.size, host_buffer::read_only);\r
- ogl_.attach(*draw_buffer);\r
+ auto host_buffer = ogl_->create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+ ogl_->attach(*draw_buffer);\r
host_buffer->begin_read(draw_buffer->width(), draw_buffer->height(), format(draw_buffer->stride()));\r
\r
transferring_buffer_ = std::move(draw_buffer);\r
\r
- ogl_.flush(); // NOTE: This is important, otherwise fences will deadlock.\r
+ ogl_->flush(); // NOTE: This is important, otherwise fences will deadlock.\r
\r
return host_buffer;\r
}\r
draw_params.local_key = nullptr;\r
draw_params.layer_key = nullptr;\r
\r
- kernel_.draw(ogl_, std::move(draw_params));\r
+ kernel_.draw(*ogl_, std::move(draw_params));\r
}\r
else if(item.transform.is_mix)\r
{\r
\r
draw_params.keyer = keyer::additive;\r
\r
- kernel_.draw(ogl_, std::move(draw_params));\r
+ kernel_.draw(*ogl_, std::move(draw_params));\r
}\r
else\r
{\r
draw_params.local_key = std::move(local_key_buffer);\r
draw_params.layer_key = layer_key_buffer;\r
\r
- kernel_.draw(ogl_, std::move(draw_params));\r
+ kernel_.draw(*ogl_, std::move(draw_params));\r
} \r
}\r
\r
draw_params.blend_mode = blend_mode;\r
draw_params.background = draw_buffer;\r
\r
- kernel_.draw(ogl_, std::move(draw_params));\r
+ kernel_.draw(*ogl_, std::move(draw_params));\r
}\r
\r
safe_ptr<device_buffer> create_mixer_buffer(size_t stride)\r
{\r
- auto buffer = ogl_.create_device_buffer(format_desc_.width, format_desc_.height, stride);\r
- ogl_.clear(*buffer);\r
+ auto buffer = ogl_->create_device_buffer(format_desc_.width, format_desc_.height, stride);\r
+ ogl_->clear(*buffer);\r
return buffer;\r
}\r
};\r
\r
struct image_mixer::implementation : boost::noncopyable\r
{ \r
- ogl_device& ogl_;\r
+ safe_ptr<ogl_device> ogl_;\r
image_renderer renderer_;\r
std::vector<frame_transform> transform_stack_;\r
std::vector<layer> layers_; // layer/stream/items\r
public:\r
- implementation(ogl_device& ogl, const video_format_desc& format_desc) \r
+ implementation(const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc) \r
: ogl_(ogl)\r
, renderer_(ogl, format_desc)\r
, transform_stack_(1) \r
}\r
};\r
\r
-image_mixer::image_mixer(ogl_device& ogl, const video_format_desc& format_desc) : impl_(new implementation(ogl, format_desc)){}\r
+image_mixer::image_mixer(const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc) : impl_(new implementation(ogl, format_desc)){}\r
void image_mixer::begin(basic_frame& frame){impl_->begin(frame);}\r
void image_mixer::visit(write_frame& frame){impl_->visit(frame);}\r
void image_mixer::end(){impl_->end();}\r
class image_mixer : public core::frame_visitor, boost::noncopyable\r
{\r
public:\r
- image_mixer(ogl_device& ogl, const video_format_desc& format_desc);\r
+ image_mixer(const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc);\r
\r
virtual void begin(core::basic_frame& frame);\r
virtual void visit(core::write_frame& frame);\r
\r
struct read_frame::implementation : boost::noncopyable\r
{\r
- ogl_device& ogl_;\r
+ safe_ptr<ogl_device> ogl_;\r
size_t size_;\r
safe_ptr<host_buffer> image_data_;\r
tbb::mutex mutex_;\r
audio_buffer audio_data_;\r
\r
public:\r
- implementation(ogl_device& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data) \r
+ implementation(const safe_ptr<ogl_device>& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data) \r
: ogl_(ogl)\r
, size_(size)\r
, image_data_(std::move(image_data))\r
\r
if(!image_data_->data())\r
{\r
- image_data_.get()->wait(ogl_);\r
- ogl_.invoke([=]{image_data_.get()->map();}, high_priority);\r
+ image_data_.get()->wait(*ogl_);\r
+ ogl_->invoke([=]{image_data_.get()->map();}, high_priority);\r
}\r
}\r
\r
}\r
};\r
\r
-read_frame::read_frame(ogl_device& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data) \r
+read_frame::read_frame(const safe_ptr<ogl_device>& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data) \r
: impl_(new implementation(ogl, size, 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()\r
{\r
public:\r
read_frame();\r
- read_frame(ogl_device& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data);\r
+ read_frame(const safe_ptr<ogl_device>& ogl, size_t size, safe_ptr<host_buffer>&& image_data, audio_buffer&& audio_data);\r
\r
virtual const boost::iterator_range<const uint8_t*> image_data();\r
virtual const boost::iterator_range<const int32_t*> audio_data();\r
\r
struct write_frame::implementation\r
{ \r
- ogl_device* ogl_;\r
+ std::shared_ptr<ogl_device> ogl_;\r
std::vector<std::shared_ptr<host_buffer>> buffers_;\r
std::vector<safe_ptr<device_buffer>> textures_;\r
audio_buffer audio_data_;\r
{\r
}\r
\r
- implementation(ogl_device& ogl, const void* tag, const core::pixel_format_desc& desc) \r
- : ogl_(&ogl)\r
+ implementation(const safe_ptr<ogl_device>& ogl, const void* tag, const core::pixel_format_desc& desc) \r
+ : ogl_(ogl)\r
, desc_(desc)\r
, tag_(tag)\r
, mode_(core::field_mode::progressive)\r
};\r
\r
write_frame::write_frame(const void* tag) : impl_(new implementation(tag)){}\r
-write_frame::write_frame(ogl_device& ogl, const void* tag, const core::pixel_format_desc& desc) \r
+write_frame::write_frame(const safe_ptr<ogl_device>& ogl, const void* tag, const core::pixel_format_desc& desc) \r
: impl_(new implementation(ogl, tag, desc)){}\r
write_frame::write_frame(const write_frame& other) : impl_(new implementation(*other.impl_)){}\r
write_frame::write_frame(write_frame&& other) : impl_(std::move(other.impl_)){}\r
{\r
public: \r
explicit write_frame(const void* tag);\r
- explicit write_frame(ogl_device& ogl, const void* tag, const core::pixel_format_desc& desc);\r
+ explicit write_frame(const safe_ptr<ogl_device>& ogl, const void* tag, const core::pixel_format_desc& desc);\r
\r
write_frame(const write_frame& other);\r
write_frame(write_frame&& other);\r
boost::timer output_timer_;\r
\r
public:\r
- implementation(int index, const video_format_desc& format_desc, ogl_device& ogl) \r
+ implementation(int index, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) \r
: context_(index, ogl, format_desc)\r
, output_(new caspar::core::output(context_, [this]{restart();}))\r
, mixer_(new caspar::core::mixer(context_))\r
void restart()\r
{\r
stage_->clear();\r
- context_.ogl().gc().wait();\r
+ context_.ogl()->gc().wait();\r
\r
mixer_ = nullptr;\r
mixer_.reset(new caspar::core::mixer(context_));\r
context_.execution().begin_invoke([=]\r
{\r
stage_->clear();\r
- context_.ogl().gc().wait();\r
+ context_.ogl()->gc().wait();\r
context_.set_format_desc(format_desc);\r
});\r
}\r
};\r
\r
-video_channel::video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl) : impl_(new implementation(index, format_desc, ogl)){}\r
+video_channel::video_channel(int index, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl) : impl_(new implementation(index, format_desc, ogl)){}\r
video_channel::video_channel(video_channel&& other) : impl_(std::move(other.impl_)){}\r
safe_ptr<stage> video_channel::stage() { return impl_->stage_;} \r
safe_ptr<mixer> video_channel::mixer() { return make_safe_ptr(impl_->mixer_);} \r
class video_channel : boost::noncopyable\r
{\r
public:\r
- explicit video_channel(int index, const video_format_desc& format_desc, ogl_device& ogl);\r
+ explicit video_channel(int index, const video_format_desc& format_desc, const safe_ptr<ogl_device>& ogl);\r
video_channel(video_channel&& other);\r
\r
safe_ptr<stage> stage();\r
const int index_;\r
video_format_desc format_desc_;\r
executor execution_;\r
- ogl_device& ogl_;\r
+ safe_ptr<ogl_device> ogl_;\r
\r
- implementation(int index, ogl_device& ogl, const video_format_desc& format_desc)\r
+ implementation(int index, const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc)\r
: index_(index)\r
, format_desc_(format_desc)\r
, execution_(print() + L"/execution")\r
}\r
};\r
\r
-video_channel_context::video_channel_context(int index, ogl_device& ogl, const video_format_desc& format_desc) \r
+video_channel_context::video_channel_context(int index, const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc) \r
: impl_(new implementation(index, ogl, format_desc))\r
{\r
}\r
}\r
\r
executor& video_channel_context::execution() {return impl_->execution_;}\r
-ogl_device& video_channel_context::ogl() { return impl_->ogl_;}\r
+safe_ptr<ogl_device> video_channel_context::ogl() { return impl_->ogl_;}\r
\r
std::wstring video_channel_context::print() const\r
{\r
{\r
\r
public:\r
- video_channel_context(int index, ogl_device& ogl, const video_format_desc& format_desc);\r
-\r
- const int index() const;\r
- video_format_desc get_format_desc();\r
- void set_format_desc(const video_format_desc& format_desc);\r
- executor& execution();\r
- ogl_device& ogl();\r
- std::wstring print() const;\r
+ video_channel_context(int index, const safe_ptr<ogl_device>& ogl, const video_format_desc& format_desc);\r
+\r
+ const int index() const;\r
+ video_format_desc get_format_desc();\r
+ void set_format_desc(const video_format_desc& format_desc);\r
+ executor& execution();\r
+ safe_ptr<ogl_device> ogl();\r
+ std::wstring print() const;\r
private:\r
struct implementation;\r
std::shared_ptr<implementation> impl_;\r
{ \r
try\r
{\r
- diagnostics::show_graphs(boost::lexical_cast<bool>(_parameters.at(0)));\r
+ diagnostics::show_graphs(true);\r
\r
SetReplyString(TEXT("202 DIAG OK\r\n"));\r
\r
</producers>\r
<channels>\r
<channel>\r
- <video-mode>PAL</video-mode>\r
+ <video-mode>720p5000</video-mode>\r
<consumers>\r
<screen></screen>\r
</consumers>\r
\r
struct server::implementation : boost::noncopyable\r
{\r
- ogl_device ogl_;\r
+ safe_ptr<ogl_device> ogl_;\r
std::vector<safe_ptr<IO::AsyncEventServer>> async_servers_; \r
std::vector<safe_ptr<video_channel>> channels_;\r
\r
- implementation() \r
+ implementation() \r
+ : ogl_(ogl_device::create())\r
{ \r
ffmpeg::init();\r
CASPAR_LOG(info) << L"Initialized ffmpeg module.";\r