struct host_buffer::implementation : boost::noncopyable\r
{ \r
GLuint pbo_;\r
+ GLuint fence_;\r
\r
const size_t size_;\r
\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
GL(glBufferData(target_, size_, NULL, usage_)); // Notify OpenGL that we don't care about previous data.\r
\r
GL(glBindBuffer(target_, pbo_));\r
- data_ = glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY); \r
+ data_ = GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY)); \r
GL(glBindBuffer(target_, 0)); \r
if(!data_)\r
BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target_ OpenGL Pixel Buffer Object."));\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
+ {\r
+ return GL2(glTestFenceNV(fence_)) != GL_FALSE;\r
+ }\r
};\r
\r
host_buffer::host_buffer(size_t size, usage_t usage) : impl_(new implementation(size, usage)){}\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
size_t host_buffer::size() const { return impl_->size_; }\r
\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
return impl_ ? impl_->audio_data() : boost::iterator_range<const int16_t*>();\r
}\r
\r
+size_t read_frame::image_size() const{return impl_->image_data_->size();}\r
+\r
//#include <tbb/scalable_allocator.h>\r
//#include <tbb/parallel_for.h>\r
//#include <tbb/enumerable_thread_specific.h>\r