\r
class image_renderer\r
{\r
- spl::shared_ptr<device> ogl_;\r
+ spl::shared_ptr<device> ogl_;\r
image_kernel kernel_;\r
std::pair<std::vector<layer>, boost::shared_future<boost::iterator_range<const uint8_t*>>> last_image_; \r
public:\r
else\r
{ \r
// Start host->device transfers.\r
-\r
- std::map<const host_buffer*, future_texture> buffer_map;\r
-\r
+ \r
BOOST_FOREACH(auto& layer, layers)\r
{\r
BOOST_FOREACH(auto& item, layer.items)\r
for(size_t n = 0; n < host_buffers.size(); ++n) \r
{\r
auto buffer = host_buffers[n];\r
- auto it = buffer_map.find(buffer.get());\r
- if(it == buffer_map.end())\r
- {\r
- auto plane = item.pix_desc.planes[n];\r
- auto future_texture = ogl_->copy_async(buffer, plane.width, plane.height, plane.channels);\r
- it = buffer_map.insert(std::make_pair(buffer.get(), std::move(future_texture))).first;\r
- }\r
- item.textures.push_back(it->second);\r
+ auto plane = item.pix_desc.planes[n];\r
+ auto future_texture = ogl_->copy_async(buffer, plane.width, plane.height, plane.channels); \r
+ item.textures.push_back(std::move(future_texture));\r
} \r
item.buffers.clear();\r
}\r
\r
struct image_mixer::impl : boost::noncopyable\r
{ \r
- spl::shared_ptr<device> ogl_;\r
+ spl::shared_ptr<device> ogl_;\r
image_renderer renderer_;\r
std::vector<core::image_transform> transform_stack_;\r
std::vector<layer> layers_; // layer/stream/items\r
\r
struct device::impl : public std::enable_shared_from_this<impl>\r
{\r
+ std::map<host_buffer*, spl::shared_ptr<device_buffer>> write_buffer_transfer_cache_;\r
+\r
std::unique_ptr<sf::Context> device_;\r
std::unique_ptr<sf::Context> host_alloc_device_;\r
\r
{\r
return executor_.invoke([&]() -> spl::shared_ptr<device_buffer>\r
{\r
- std::shared_ptr<device_buffer> buffer;\r
try\r
{\r
- buffer.reset(new device_buffer(width, height, stride));\r
+ return spl::make_shared<device_buffer>(width, height, stride);\r
}\r
catch(...)\r
{\r
CASPAR_LOG(error) << L"ogl: create_device_buffer failed!";\r
throw;\r
}\r
- return spl::make_shared_ptr(buffer);\r
});\r
}\r
\r
{\r
return host_alloc_executor_.invoke([=]() -> spl::shared_ptr<host_buffer>\r
{\r
- std::shared_ptr<host_buffer> buffer;\r
-\r
try\r
{\r
- buffer.reset(new host_buffer(size, usage));\r
+ auto buffer = spl::make_shared<host_buffer>(size, usage);\r
if(usage == host_buffer::usage::write_only)\r
buffer->map();\r
else\r
- buffer->unmap(); \r
+ buffer->unmap(); \r
+\r
+ return buffer;\r
}\r
catch(...)\r
{\r
CASPAR_LOG(error) << L"ogl: create_host_buffer failed!";\r
throw; \r
}\r
-\r
- return spl::make_shared_ptr(buffer);\r
});\r
}\r
\r
{\r
self->host_alloc_executor_.begin_invoke([=]() mutable\r
{ \r
- if(is_write)\r
- buffer->map();\r
+ if(is_write) \r
+ buffer->map(); \r
else\r
buffer->unmap();\r
\r
pool->push(buffer);\r
}, task_priority::high_priority); \r
+\r
+ self->executor_.begin_invoke([=]\r
+ {\r
+ write_buffer_transfer_cache_.erase(buffer.get()); \r
+ }, task_priority::high_priority); \r
});\r
}\r
\r
{\r
return executor_.begin_invoke([=]() -> spl::shared_ptr<device_buffer>\r
{\r
- auto result = create_device_buffer(width, height, stride);\r
- result->copy_from(*source);\r
- return result;\r
+ auto buffer_it = write_buffer_transfer_cache_.find(source.get());\r
+ if(buffer_it == write_buffer_transfer_cache_.end())\r
+ {\r
+ auto result = create_device_buffer(width, height, stride);\r
+ result->copy_from(*source);\r
+ buffer_it = write_buffer_transfer_cache_.insert(std::make_pair(source.get(), result)).first;\r
+ }\r
+ return buffer_it->second;\r
}, task_priority::high_priority);\r
}\r
};\r