struct image_kernel::implementation : boost::noncopyable\r
{ \r
std::shared_ptr<shader> shader_;\r
- bool blend_modes_;\r
+ bool advanced_blend_modes_;\r
\r
void draw(ogl_device& ogl,\r
render_item&& item,\r
if(item.transform.get_opacity() < epsilon)\r
return;\r
\r
+ if(!std::all_of(item.textures.begin(), item.textures.end(), std::mem_fn(&device_buffer::ready)))\r
+ {\r
+ CASPAR_LOG(warning) << L"[image_mixer] Performance warning. Host to device transfer not complete, GPU will be stalled";\r
+ ogl.yield(); // Try to give it some more time.\r
+ } \r
+ \r
// Bind textures\r
\r
for(size_t n = 0; n < item.textures.size(); ++n)\r
// Setup shader\r
\r
if(!shader_)\r
- shader_ = get_image_shader(ogl, blend_modes_);\r
+ shader_ = get_image_shader(ogl, advanced_blend_modes_);\r
\r
ogl.use(*shader_);\r
\r
\r
// Setup blend_func\r
\r
- if(blend_modes_)\r
+ if(advanced_blend_modes_)\r
{\r
background->bind(6);\r
\r
shader_->set("background", texture_id::background);\r
shader_->set("blend_mode", item.transform.get_is_key() ? core::image_transform::blend_mode::normal : item.transform.get_blend_mode());\r
}\r
+ else\r
+ {\r
+ switch(item.transform.get_blend_mode())\r
+ {\r
+ case image_transform::blend_mode::add: \r
+ ogl.blend_func_separate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);\r
+ break;\r
+ case image_transform::blend_mode::replace: \r
+ ogl.blend_func_separate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);\r
+ break;\r
+ case image_transform::blend_mode::screen:\r
+ ogl.blend_func_separate(GL_ONE, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);\r
+ default:\r
+ ogl.blend_func_separate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);\r
+ break;\r
+ }\r
+ }\r
\r
// Setup image-adjustements\r
\r
\r
ogl.viewport(0, 0, background->width(), background->height());\r
\r
- GL(glColor4d(item.transform.get_gain(), item.transform.get_gain(), item.transform.get_gain(), item.transform.get_opacity()));\r
+ GL(glColor4d(item.transform.get_gain(), item.transform.get_gain(), item.transform.get_gain(), item.transform.get_is_key() ? 1.0 : item.transform.get_opacity()));\r
\r
auto m_p = item.transform.get_clip_translation();\r
auto m_s = item.transform.get_clip_scale();\r
item.textures.clear();\r
ogl.yield(); // Return resources to pool as early as possible.\r
\r
- if(!blend_modes_)\r
- glTextureBarrierNV(); // This allows us to use framebuffer (background) both as source and target while blending.\r
+ if(advanced_blend_modes_)\r
+ {\r
+ // http://www.opengl.org/registry/specs/NV/texture_barrier.txt\r
+ // This allows us to use framebuffer (background) both as source and target while blending.\r
+ glTextureBarrierNV(); \r
+ }\r
}\r
};\r
\r