#include "ogl_device.h"\r
\r
#include <common/utility/assert.h>\r
+#include <common/gl/gl_check.h>\r
\r
#include <Glee.h>\r
#include <SFML/Window.hpp>\r
\r
namespace caspar { namespace mixer {\r
\r
-ogl_device::ogl_device() : executor_(L"ogl_device")\r
+ogl_device::ogl_device() : executor_(L"ogl_device", true)\r
{\r
- executor_.start();\r
invoke([=]\r
{\r
context_.reset(new sf::Context());\r
context_->SetActive(true);\r
+ \r
+ if(!GLEE_VERSION_3_0)\r
+ BOOST_THROW_EXCEPTION(not_supported() << msg_info("Missing OpenGL 3.0 support."));\r
+\r
+ GL(glGenFramebuffers(1, &fbo_)); \r
+ GL(glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_));\r
+ GL(glReadBuffer(GL_COLOR_ATTACHMENT0_EXT));\r
});\r
}\r
\r
pool.clear();\r
BOOST_FOREACH(auto& pool, host_pools_)\r
pool.clear();\r
+ glDeleteFramebuffersEXT(1, &fbo_);\r
});\r
}\r
\r
namespace caspar { namespace mixer {\r
\r
struct image_mixer::implementation : boost::noncopyable\r
-{ \r
+{ \r
+ struct render_item\r
+ {\r
+ core::pixel_format_desc desc;\r
+ std::vector<safe_ptr<device_buffer>> textures;\r
+ core::image_transform transform;\r
+ };\r
+\r
const core::video_format_desc format_desc_;\r
\r
std::stack<core::image_transform> transform_stack_;\r
\r
- GLuint fbo_;\r
- std::array<std::shared_ptr<device_buffer>, 2> render_targets_;\r
- std::shared_ptr<device_buffer> key_target_;\r
bool is_key_;\r
\r
- std::shared_ptr<host_buffer> reading_;\r
+ safe_ptr<device_buffer> front_target_;\r
+ safe_ptr<device_buffer> back_target_;\r
+ safe_ptr<device_buffer> key_target_;\r
\r
- image_kernel kernel_;\r
+ safe_ptr<host_buffer> reading_;\r
\r
- struct render_item\r
- {\r
- core::pixel_format_desc desc;\r
- std::vector<safe_ptr<device_buffer>> textures;\r
- core::image_transform transform;\r
- };\r
- \r
+ image_kernel kernel_;\r
+ \r
std::vector<render_item> waiting_queue_;\r
std::vector<render_item> render_queue_;\r
\r
implementation(const core::video_format_desc& format_desc) \r
: format_desc_(format_desc)\r
, is_key_(false)\r
+ , back_target_(ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4))\r
+ , front_target_(ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4))\r
+ , key_target_(ogl_device::create_device_buffer(format_desc.width, format_desc.height, 4))\r
+ , reading_(ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only))\r
{\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
- ogl_device::begin_invoke([=]\r
- {\r
- transform_stack_.push(core::image_transform());\r
- transform_stack_.top().set_mode(core::video_mode::progressive);\r
-\r
- GL(glEnable(GL_TEXTURE_2D));\r
- GL(glDisable(GL_DEPTH_TEST)); \r
- \r
- key_target_ = ogl_device::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_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
- });\r
- }\r
-\r
- ~implementation()\r
- {\r
- glDeleteFramebuffersEXT(1, &fbo_);\r
+ transform_stack_.push(core::image_transform());\r
}\r
-\r
+ \r
void begin(const core::basic_frame& frame)\r
{\r
transform_stack_.push(transform_stack_.top()*frame.get_image_transform());\r
auto result = ogl_device::begin_invoke([=]() -> safe_ptr<const host_buffer>\r
{\r
reading_->map(); // Might block.\r
- return make_safe(reading_);\r
+ return reading_;\r
});\r
\r
ogl_device::begin_invoke([=]\r
key_target_->attach();\r
GL(glClear(GL_COLOR_BUFFER_BIT)); \r
\r
- render_targets_[0]->attach();\r
+ front_target_->attach();\r
GL(glClear(GL_COLOR_BUFFER_BIT));\r
\r
// Render items.\r
// Start read-back.\r
\r
reading_ = ogl_device::create_host_buffer(format_desc_.size, host_buffer::read_only);\r
- render_targets_[0]->attach();\r
- render_targets_[0]->write(*reading_);\r
- std::swap(render_targets_[0], render_targets_[1]);\r
+ front_target_->attach();\r
+ front_target_->write(*reading_);\r
+ std::swap(front_target_, back_target_);\r
});\r
\r
return std::move(result);\r
has_separate_key = true;\r
is_key_ = false;\r
\r
- render_targets_[0]->attach(); \r
+ front_target_->attach(); \r
GL(glActiveTexture(GL_TEXTURE0+3));\r
key_target_->bind();\r
} \r
{\r
if(_parameters[1] == L"IS_KEY")\r
{\r
- bool value = lexical_cast_or_default(_parameters.at(2), false);\r
- auto transform = [=](image_transform transform) -> image_transform\r
- {\r
- transform.set_is_key(value);\r
- return transform; \r
- };\r
-\r
- int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
- if(layer != std::numeric_limits<int>::min()) \r
- GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, 0);\r
- else\r
- GetChannel()->mixer()->apply_image_transform(transform, 0);\r
+ //bool value = lexical_cast_or_default(_parameters.at(2), false);\r
+ //auto transform = [=](image_transform transform) -> image_transform\r
+ //{\r
+ // transform.set_is_key(value);\r
+ // return transform; \r
+ //};\r
+\r
+ //int layer = GetLayerIndex(std::numeric_limits<int>::min());\r
+ //if(layer != std::numeric_limits<int>::min()) \r
+ // GetChannel()->mixer()->apply_image_transform(GetLayerIndex(), transform, 0);\r
+ //else\r
+ // GetChannel()->mixer()->apply_image_transform(transform, 0);\r
}\r
else if(_parameters[1] == L"OPACITY")\r
{\r