X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fmixer%2Fimage%2Fimage_mixer.cpp;h=393c8a7140f6383df22c486dadb3951f72bc459d;hb=116e09a218cf056e4de868454b0fe26dc4db1413;hp=302d7af5e681f458c788391871cb0cf41abf5356;hpb=134faacd0105bffe3bd051d708f175010dd1e9b8;p=casparcg diff --git a/core/mixer/image/image_mixer.cpp b/core/mixer/image/image_mixer.cpp index 302d7af5e..393c8a714 100644 --- a/core/mixer/image/image_mixer.cpp +++ b/core/mixer/image/image_mixer.cpp @@ -145,37 +145,34 @@ private: return; std::shared_ptr local_key_buffer; + std::shared_ptr local_mix_buffer; if(layer.blend_mode != blend_mode::normal && layer.items.size() > 1) { auto layer_draw_buffer = create_device_buffer(4); BOOST_FOREACH(auto& item, layer.items) - draw_item(std::move(item), layer_draw_buffer, local_key_buffer, layer_key_buffer); - - draw_params draw_params; - draw_params.pix_desc.pix_fmt = pixel_format::bgra; - draw_params.pix_desc.planes = list_of(pixel_format_desc::plane(channel_.get_format_desc().width, channel_.get_format_desc().height, 4)); - draw_params.textures = list_of(layer_draw_buffer); - draw_params.transform = frame_transform(); - draw_params.blend_mode = layer.blend_mode; - draw_params.background = draw_buffer; - - kernel_.draw(channel_.ogl(), std::move(draw_params)); + draw_item(std::move(item), layer_draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer); + + draw_device_buffer(layer_draw_buffer, std::move(local_mix_buffer), blend_mode::normal); + draw_device_buffer(draw_buffer, std::move(layer_draw_buffer), layer.blend_mode); } else // fast path { BOOST_FOREACH(auto& item, layer.items) - draw_item(std::move(item), draw_buffer, local_key_buffer, layer_key_buffer); + draw_item(std::move(item), draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer); + + draw_device_buffer(draw_buffer, std::move(local_mix_buffer), blend_mode::normal); } - + std::swap(local_key_buffer, layer_key_buffer); } void draw_item(item&& item, safe_ptr& draw_buffer, + std::shared_ptr& layer_key_buffer, std::shared_ptr& local_key_buffer, - std::shared_ptr& layer_key_buffer) + std::shared_ptr& local_mix_buffer) { draw_params draw_params; draw_params.pix_desc = std::move(item.pix_desc); @@ -193,8 +190,22 @@ private: kernel_.draw(channel_.ogl(), std::move(draw_params)); } + else if(item.transform.is_mix) + { + local_mix_buffer = local_mix_buffer ? local_mix_buffer : create_device_buffer(4); + + draw_params.background = local_mix_buffer; + draw_params.local_key = std::move(local_key_buffer); + draw_params.layer_key = layer_key_buffer; + + draw_params.blend_mode = blend_mode::mix; + + kernel_.draw(channel_.ogl(), std::move(draw_params)); + } else { + draw_device_buffer(draw_buffer, std::move(local_mix_buffer), blend_mode::normal); + draw_params.background = draw_buffer; draw_params.local_key = std::move(local_key_buffer); draw_params.layer_key = layer_key_buffer; @@ -202,6 +213,22 @@ private: kernel_.draw(channel_.ogl(), std::move(draw_params)); } } + + void draw_device_buffer(safe_ptr& draw_buffer, std::shared_ptr&& source_buffer, blend_mode::type blend_mode = blend_mode::normal) + { + if(!source_buffer) + return; + + draw_params draw_params; + draw_params.pix_desc.pix_fmt = pixel_format::bgra; + draw_params.pix_desc.planes = list_of(pixel_format_desc::plane(source_buffer->width(), source_buffer->height(), 4)); + draw_params.textures = list_of(source_buffer); + draw_params.transform = frame_transform(); + draw_params.blend_mode = blend_mode; + draw_params.background = draw_buffer; + + kernel_.draw(channel_.ogl(), std::move(draw_params)); + } safe_ptr create_device_buffer(size_t stride) {