<Lib />\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
+ <ClInclude Include="mixer\gpu\fence.h" />\r
<ClInclude Include="mixer\gpu\shader.h" />\r
<ClInclude Include="mixer\image\blending_glsl.h" />\r
<ClInclude Include="video_channel.h" />\r
<ClInclude Include="StdAfx.h" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="mixer\gpu\fence.cpp">\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Develop|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../../StdAfx.h</PrecompiledHeaderFile>\r
+ </ClCompile>\r
<ClCompile Include="mixer\gpu\shader.cpp">\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">../../../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../../StdAfx.h</PrecompiledHeaderFile>\r
<ClInclude Include="mixer\gpu\shader.h">\r
<Filter>source\mixer\gpu</Filter>\r
</ClInclude>\r
+ <ClInclude Include="mixer\gpu\fence.h">\r
+ <Filter>source\mixer\gpu</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="producer\transition\transition_producer.cpp">\r
<ClCompile Include="mixer\gpu\shader.cpp">\r
<Filter>source\mixer\gpu</Filter>\r
</ClCompile>\r
+ <ClCompile Include="mixer\gpu\fence.cpp">\r
+ <Filter>source\mixer\gpu</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
#include "device_buffer.h"\r
\r
#include "host_buffer.h"\r
+#include "fence.h"\r
\r
#include <common/gl/gl_check.h>\r
\r
GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
target.unbind();\r
GL(glBindTexture(GL_TEXTURE_2D, 0));\r
- target.fence_set();\r
- glFlush();\r
+ target.fence();\r
}\r
\r
void attach(int index)\r
--- /dev/null
+#include "../../StdAfx.h"\r
+\r
+#include "fence.h"\r
+\r
+#include "ogl_device.h"\r
+\r
+#include <common/gl/gl_check.h>\r
+\r
+namespace caspar { namespace core {\r
+ \r
+fence::fence() : id_(0){}\r
+\r
+fence::~fence()\r
+{\r
+ if(id_)\r
+ glDeleteFencesNV(1, &id_);\r
+}\r
+\r
+void fence::set()\r
+{\r
+ if(id_)\r
+ glDeleteFencesNV(1, &id_);\r
+ \r
+ GL(glGenFencesNV(1, &id_));\r
+ GL(glSetFenceNV(id_, GL_ALL_COMPLETED_NV));\r
+}\r
+\r
+bool fence::ready() const\r
+{\r
+ return id_ ? GL2(glTestFenceNV(id_)) != GL_FALSE : true;\r
+}\r
+\r
+void fence::wait(ogl_device& ogl)\r
+{ \r
+ int delay = 0;\r
+ if(!ogl.invoke([this]{return ready();}, high_priority))\r
+ {\r
+ while(!ogl.invoke([this]{return ready();}, normal_priority))\r
+ {\r
+ delay += 3;\r
+ Sleep(3);\r
+ }\r
+ }\r
+\r
+ if(delay > 0)\r
+ CASPAR_LOG(warning) << L"[ogl_device] Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
+}\r
+\r
+}}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+namespace caspar { namespace core {\r
+ \r
+class ogl_device;\r
+\r
+class fence\r
+{\r
+ unsigned int id_;\r
+public:\r
+ fence();\r
+ ~fence();\r
+ void set();\r
+ bool ready() const;\r
+ void wait(ogl_device& ogl);\r
+};\r
+\r
+}}\r
*/\r
#include "../../stdafx.h"\r
\r
-#include "../gpu/host_buffer.h"\r
+#include "host_buffer.h"\r
+\r
+#include "fence.h"\r
+#include "ogl_device.h"\r
\r
#include <common/gl/gl_check.h>\r
\r
\r
struct host_buffer::implementation : boost::noncopyable\r
{ \r
- GLuint pbo_;\r
- GLuint fence_;\r
-\r
- const size_t size_;\r
-\r
- void* data_;\r
- GLenum usage_;\r
- GLenum target_;\r
+ GLuint pbo_;\r
+ const size_t size_;\r
+ void* data_;\r
+ GLenum usage_;\r
+ GLenum target_;\r
+ core::fence fence_;\r
\r
public:\r
implementation(size_t size, usage_t usage) \r
, pbo_(0)\r
, target_(usage == write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
, usage_(usage == write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
- , fence_(0)\r
{\r
GL(glGenBuffers(1, &pbo_));\r
GL(glBindBuffer(target_, pbo_));\r
{\r
try\r
{\r
- if(fence_)\r
- glDeleteFencesNV(1, &fence_);\r
-\r
GL(glDeleteBuffers(1, &pbo_));\r
}\r
catch(...)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target_ OpenGL Pixel Buffer Object."));\r
}\r
\r
+ void map2(ogl_device& ogl)\r
+ {\r
+ fence_.wait(ogl);\r
+ ogl.invoke(std::bind(&implementation::map, this), high_priority);\r
+ }\r
+\r
void unmap()\r
{\r
if(!data_)\r
{\r
GL(glBindBuffer(target_, 0));\r
}\r
- \r
- void fence_set()\r
- {\r
- if(fence_)\r
- glDeleteFencesNV(1, &fence_);\r
- \r
- GL(glGenFencesNV(1, &fence_));\r
- GL(glSetFenceNV(fence_, GL_ALL_COMPLETED_NV));\r
- }\r
\r
- bool fence_rdy() const\r
+ void fence()\r
{\r
- return GL2(glTestFenceNV(fence_)) != GL_FALSE;\r
+ fence_.set();\r
+ GL(glFlush());\r
}\r
};\r
\r
const void* host_buffer::data() const {return impl_->data_;}\r
void* host_buffer::data() {return impl_->data_;}\r
void host_buffer::map(){impl_->map();}\r
+void host_buffer::map(ogl_device& ogl){impl_->map2(ogl);}\r
void host_buffer::unmap(){impl_->unmap();}\r
void host_buffer::bind(){impl_->bind();}\r
void host_buffer::unbind(){impl_->unbind();}\r
-void host_buffer::fence_set(){impl_->fence_set();}\r
-bool host_buffer::fence_rdy() const{return impl_->fence_rdy();}\r
-\r
+void host_buffer::fence(){impl_->fence();}\r
size_t host_buffer::size() const { return impl_->size_; }\r
\r
}}
\ No newline at end of file
#include <common/memory/safe_ptr.h>\r
\r
namespace caspar { namespace core {\r
+\r
+class ogl_device;\r
\r
class host_buffer : boost::noncopyable\r
{\r
void unbind();\r
\r
void map();\r
+ void map(ogl_device& ogl);\r
void unmap();\r
\r
- void fence_set();\r
- bool fence_rdy() const;\r
+ void fence();\r
private:\r
friend class ogl_device;\r
host_buffer(size_t size, usage_t usage);\r
\r
#include "read_frame.h"\r
\r
+#include "gpu/fence.h"\r
#include "gpu/host_buffer.h" \r
#include "gpu/ogl_device.h"\r
\r
const boost::iterator_range<const uint8_t*> image_data()\r
{\r
if(!image_data_->data())\r
- {\r
- auto fence_check = [=]{return image_data_->fence_rdy();};\r
-\r
- int delay = 0;\r
- if(!ogl_.invoke(fence_check, high_priority))\r
- {\r
- while(!ogl_.invoke(fence_check, normal_priority))\r
- {\r
- delay += 3;\r
- Sleep(3);\r
- }\r
- }\r
-\r
- if(delay > 0)\r
- CASPAR_LOG(warning) << L" Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
-\r
- ogl_.invoke([=]\r
- {\r
- image_data_->map();\r
- }, high_priority);\r
- }\r
+ image_data_->map(ogl_);\r
\r
auto ptr = static_cast<const uint8_t*>(image_data_->data());\r
return boost::iterator_range<const uint8_t*>(ptr, ptr + image_data_->size());\r
safe_ptr<diagnostics::graph> diag_;\r
boost::timer frame_timer_;\r
boost::timer tick_timer_;\r
+ boost::timer output_timer_;\r
\r
public:\r
implementation(int index, const video_format_desc& format_desc, ogl_device& ogl) \r
{\r
diag_->add_guide("produce-time", 0.5f); \r
diag_->set_color("produce-time", diagnostics::color(1.0f, 0.0f, 0.0f));\r
- diag_->add_guide("mix-time", 0.5f); \r
diag_->set_color("mix-time", diagnostics::color(1.0f, 0.0f, 1.0f));\r
+ diag_->set_color("output-time", diagnostics::color(1.0f, 1.0f, 0.0f));\r
diag_->set_color("tick-time", diagnostics::color(0.1f, 0.7f, 0.8f)); \r
\r
CASPAR_LOG(info) << print() << " Successfully Initialized.";\r
diag_->update_value("mix-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5);\r
\r
// Consume\r
+ \r
+ output_timer_.restart();\r
\r
output_->execute(finished_frame);\r
\r
+ diag_->update_value("output-time", frame_timer_.elapsed()*context_.get_format_desc().fps*0.5);\r
+\r
+ \r
diag_->update_value("tick-time", tick_timer_.elapsed()*context_.get_format_desc().fps*0.5);\r
tick_timer_.restart();\r
\r
\r
AVFilterInOut* outputs = avfilter_inout_alloc();\r
AVFilterInOut* inputs = avfilter_inout_alloc();\r
-\r
+ \r
outputs->name = av_strdup("in");\r
outputs->filter_ctx = buffersrc_ctx_;\r
outputs->pad_idx = 0;\r
inputs->pad_idx = 0;\r
inputs->next = NULL;\r
\r
- int ret = avfilter_graph_parse(graph_.get(), filters_.c_str(), &inputs, &outputs, NULL);\r
-\r
+ THROW_ON_ERROR2(avfilter_graph_parse(graph_.get(), filters_.c_str(), &inputs, &outputs, NULL), "[filter]");\r
+ \r
avfilter_inout_free(&inputs);\r
avfilter_inout_free(&outputs);\r
- \r
- THROW_ON_ERROR(ret, "[filter]", "avfilter_graph_parse");\r
- \r
- THROW_ON_ERROR2(avfilter_graph_config(graph_.get(), NULL), "[filter]");\r
+\r
+ THROW_ON_ERROR2(avfilter_graph_config(graph_.get(), NULL), "[filter]"); \r
\r
for(size_t n = 0; n < graph_->filter_count; ++n)\r
{\r