+ BOOST_FOREACH(auto& item, layer)\r
+ {\r
+ item.blend_mode = blend_mode::normal; // Disable blending and just merge.\r
+ draw_item(std::move(item), *layer_draw_buffer, local_key_buffer, layer_key_buffer); \r
+ }\r
+ \r
+ render_item item;\r
+ item.pix_desc.pix_fmt = pixel_format::bgra;\r
+ item.pix_desc.planes = list_of(pixel_format_desc::plane(channel_.get_format_desc().width, channel_.get_format_desc().height, 4));\r
+ item.textures = list_of(layer_draw_buffer);\r
+ item.transform = frame_transform();\r
+ item.blend_mode = layer_blend_mode;\r
+\r
+ kernel_.draw(channel_.ogl(), std::move(item), *draw_buffer, nullptr, nullptr);\r
+ }\r
+ else // fast path\r
+ {\r
+ BOOST_FOREACH(auto& item, layer) \r
+ draw_item(std::move(item), *draw_buffer, local_key_buffer, layer_key_buffer); \r
+ } \r
+\r
+ CASPAR_ASSERT(local_key_buffer.first == 0 || local_key_buffer.first == core::field_mode::progressive);\r
+\r
+ std::swap(local_key_buffer.second, layer_key_buffer);\r
+ }\r
+\r
+ void draw_item(render_item&& item, \r
+ device_buffer& draw_buffer, \r
+ std::pair<int, std::shared_ptr<device_buffer>>& local_key_buffer, \r
+ std::shared_ptr<device_buffer>& layer_key_buffer)\r
+ { \r
+ if(item.transform.is_key)\r
+ {\r
+ if(!local_key_buffer.second)\r
+ {\r
+ local_key_buffer.first = 0;\r
+ local_key_buffer.second = create_device_buffer(1);\r
+ }\r
+ \r
+ local_key_buffer.first |= item.transform.field_mode; // Add field to flag.\r
+ kernel_.draw(channel_.ogl(), std::move(item), *local_key_buffer.second, nullptr, nullptr);\r
+ }\r
+ else\r
+ {\r
+ kernel_.draw(channel_.ogl(), std::move(item), draw_buffer, local_key_buffer.second, layer_key_buffer);\r
+ local_key_buffer.first ^= item.transform.field_mode; // Remove field from flag.\r
+ \r
+ if(local_key_buffer.first == 0) // If all fields from key has been used, reset it\r
+ {\r
+ local_key_buffer.first = 0;\r
+ local_key_buffer.second.reset();\r
+ }\r
+ }\r
+ }\r
+\r
+ bool has_overlapping_items(const layer& layer)\r
+ { \r
+ auto upper_count = boost::range::count_if(layer, [&](const render_item& item)\r
+ {\r
+ return !item.transform.is_key && (item.transform.field_mode & field_mode::upper);\r
+ });\r
+\r
+ auto lower_count = boost::range::count_if(layer, [&](const render_item& item)\r
+ {\r
+ return !item.transform.is_key && (item.transform.field_mode & field_mode::lower);\r
+ });\r
+\r
+ return upper_count > 1 || lower_count > 1;\r
+ } \r