});\r
}\r
\r
-safe_ptr<device_buffer> ogl_device::create_device_buffer(size_t width, size_t height, size_t stride)\r
+safe_ptr<device_buffer> ogl_device::do_create_device_buffer(size_t width, size_t height, size_t stride)\r
{\r
CASPAR_VERIFY(stride > 0 && stride < 5);\r
CASPAR_VERIFY(width > 0 && height > 0);\r
{\r
buffer = std::make_shared<device_buffer>(width, height, stride);\r
}); \r
+ executor_.begin_invoke([=]\r
+ {\r
+ auto buffer = std::make_shared<device_buffer>(width, height, stride);\r
+ pool->try_push(buffer);\r
+ }); \r
}\r
- \r
+ \r
return safe_ptr<device_buffer>(buffer.get(), [=](device_buffer*){pool->push(buffer);});\r
}\r
\r
-safe_ptr<host_buffer> ogl_device::create_host_buffer(size_t size, host_buffer::usage_t usage)\r
+safe_ptr<host_buffer> ogl_device::do_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
else\r
buffer->unmap();\r
}); \r
+ executor_.begin_invoke([=]\r
+ {\r
+ auto buffer = std::make_shared<host_buffer>(size, usage);\r
+ if(usage == host_buffer::write_only)\r
+ buffer->map();\r
+ else\r
+ buffer->unmap();\r
+ pool->try_push(buffer);\r
+ }); \r
}\r
-\r
+ \r
return safe_ptr<host_buffer>(buffer.get(), [=](host_buffer*)\r
{\r
executor_.begin_invoke([=]\r
});\r
}\r
\r
+std::wstring ogl_device::get_version()\r
+{ \r
+ return widen(invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VERSION)));})\r
+ + " " + invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));})); \r
+}\r
+\r
}}
\ No newline at end of file
executor executor_;\r
\r
ogl_device();\r
-public: \r
- virtual ~ogl_device();\r
+ ~ogl_device();\r
\r
- static safe_ptr<ogl_device> create()\r
+ static ogl_device& get_instance()\r
{\r
- static safe_ptr<ogl_device> instance(new ogl_device()); // Use the same ogl-device for all channels inorder to ensure that frames are always valid for all "context".\r
- return instance;\r
+ static ogl_device device;\r
+ return device;\r
}\r
-\r
+ \r
template<typename Func>\r
- auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
+ auto do_begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
{ \r
return executor_.begin_invoke(std::forward<Func>(func));\r
}\r
\r
template<typename Func>\r
- auto invoke(Func&& func) -> decltype(func())\r
+ auto do_invoke(Func&& func) -> decltype(func())\r
{\r
return executor_.invoke(std::forward<Func>(func));\r
}\r
\r
- safe_ptr<device_buffer> create_device_buffer(size_t width, size_t height, size_t stride);\r
- safe_ptr<host_buffer> create_host_buffer(size_t size, host_buffer::usage_t usage);\r
+ safe_ptr<device_buffer> do_create_device_buffer(size_t width, size_t height, size_t stride);\r
+ safe_ptr<host_buffer> do_create_host_buffer(size_t size, host_buffer::usage_t usage);\r
+public: \r
+ \r
+ template<typename Func>\r
+ static auto begin_invoke(Func&& func) -> boost::unique_future<decltype(func())> // noexcept\r
+ { \r
+ return get_instance().do_begin_invoke(std::forward<Func>(func));\r
+ }\r
+ \r
+ template<typename Func>\r
+ static auto invoke(Func&& func) -> decltype(func())\r
+ {\r
+ return get_instance().do_invoke(std::forward<Func>(func));\r
+ }\r
+ \r
+ static safe_ptr<device_buffer> create_device_buffer(size_t width, size_t height, size_t stride)\r
+ {\r
+ return get_instance().do_create_device_buffer(width, height, stride);\r
+ }\r
+\r
+ static safe_ptr<host_buffer> create_host_buffer(size_t size, host_buffer::usage_t usage)\r
+ {\r
+ return get_instance().do_create_host_buffer(size, usage);\r
+ }\r
+\r
+ static std::wstring get_version();\r
};\r
\r
}}
\ No newline at end of file
\r
image_kernel kernel_;\r
\r
- safe_ptr<ogl_device> context_;\r
std::shared_ptr<device_buffer> key_;\r
public:\r
implementation(const core::video_format_desc& format_desc) \r
: format_desc_(format_desc)\r
- , context_(ogl_device::create())\r
{\r
- context_->invoke([]\r
+ ogl_device::invoke([]\r
{\r
if(!GLEE_VERSION_3_0)\r
BOOST_THROW_EXCEPTION(not_supported() << msg_info("Missing OpenGL 3.0 support."));\r
});\r
\r
- context_->begin_invoke([=]\r
+ ogl_device::begin_invoke([=]\r
{\r
transform_stack_.push(core::image_transform());\r
transform_stack_.top().set_mode(core::video_mode::progressive);\r
GL(glEnable(GL_TEXTURE_2D));\r
GL(glDisable(GL_DEPTH_TEST)); \r
\r
- render_targets_[0] = context_->create_device_buffer(format_desc.width, format_desc.height, 4);\r
- render_targets_[1] = context_->create_device_buffer(format_desc.width, format_desc.height, 4);\r
+ render_targets_[0] = ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4);\r
+ render_targets_[1] = ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4);\r
\r
GL(glGenFramebuffers(1, &fbo_)); \r
GL(glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_));\r
GL(glReadBuffer(GL_COLOR_ATTACHMENT0_EXT));\r
\r
- reading_ = context_->create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+ reading_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
});\r
}\r
\r
auto buffers = gpu_frame->get_plane_buffers();\r
\r
auto transform = transform_stack_.top();\r
- context_->begin_invoke([=]\r
+ ogl_device::begin_invoke([=]\r
{\r
std::vector<safe_ptr<device_buffer>> device_buffers;\r
for(size_t n = 0; n < buffers.size(); ++n)\r
{\r
- auto texture = context_->create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels);\r
+ auto texture = ogl_device::create_device_buffer(desc.planes[n].width, desc.planes[n].height, desc.planes[n].channels);\r
texture->read(*buffers[n]);\r
device_buffers.push_back(texture);\r
}\r
\r
boost::unique_future<safe_ptr<const host_buffer>> begin_pass()\r
{\r
- return context_->begin_invoke([=]() -> safe_ptr<const host_buffer>\r
+ return ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
{\r
reading_->map();\r
render_targets_[0]->attach(0);\r
\r
void end_pass()\r
{\r
- context_->begin_invoke([=]\r
+ ogl_device::begin_invoke([=]\r
{\r
- reading_ = context_->create_host_buffer(format_desc_.size, host_buffer::read_only);\r
+ reading_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
render_targets_[0]->write(*reading_);\r
std::rotate(render_targets_.begin(), render_targets_.begin() + 1, render_targets_.end());\r
});\r
std::vector<safe_ptr<host_buffer>> buffers;\r
std::transform(format.planes.begin(), format.planes.end(), std::back_inserter(buffers), [&](const core::pixel_format_desc::plane& plane)\r
{\r
- return context_->create_host_buffer(plane.size, host_buffer::write_only);\r
+ return ogl_device::create_host_buffer(plane.size, host_buffer::write_only);\r
});\r
return buffers;\r
}\r
#include <common/os/windows/system_info.h>\r
#include <common/utility/assert.h>\r
\r
-#include <Glee.h>\r
-\r
#include <tbb/task_scheduler_observer.h>\r
#include <tbb/task_scheduler_init.h>\r
\r
CASPAR_LOG(info) << L"FFMPEG-avcodec " << caspar::get_avcodec_version();\r
CASPAR_LOG(info) << L"FFMPEG-swscale " << caspar::get_avformat_version();\r
CASPAR_LOG(info) << L"FFMPEG-avformat " << caspar::get_swscale_version();\r
- CASPAR_LOG(info) << L"OpenGL " << caspar::mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VERSION));})\r
- << L" " << caspar::mixer::ogl_device::create()->invoke([]{return reinterpret_cast<const char*>(glGetString(GL_VENDOR));}) << "\n\n";\r
+ CASPAR_LOG(info) << L"OpenGL " << caspar::mixer::ogl_device::get_version() << "\n\n";\r
}\r
\r
int main(int argc, wchar_t* argv[])\r