X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fmixer%2Fgpu%2Fhost_buffer.cpp;h=9e129ecbb06f71fe1fec49227cc8dfba2941090e;hb=c1d2ab3326d82e78c0fa8e1f2f4a5622076a49ae;hp=1c8a2841f0a88798c5eec5205ae7e4bb55915aa9;hpb=789c03c2b410cd7964d544da198f389a3113fb7c;p=casparcg diff --git a/core/mixer/gpu/host_buffer.cpp b/core/mixer/gpu/host_buffer.cpp index 1c8a2841f..9e129ecbb 100644 --- a/core/mixer/gpu/host_buffer.cpp +++ b/core/mixer/gpu/host_buffer.cpp @@ -19,21 +19,32 @@ */ #include "../../stdafx.h" -#include "../gpu/host_buffer.h" +#include "host_buffer.h" +#include "fence.h" +#include "device_buffer.h" +#include "ogl_device.h" + +#include #include +#include + +#include + namespace caspar { namespace core { + +static tbb::atomic g_w_total_count; +static tbb::atomic g_r_total_count; struct host_buffer::implementation : boost::noncopyable { - GLuint pbo_; - - const size_t size_; - - void* data_; - GLenum usage_; - GLenum target_; + GLuint pbo_; + const size_t size_; + void* data_; + GLenum usage_; + GLenum target_; + fence fence_; public: implementation(size_t size, usage_t usage) @@ -52,7 +63,7 @@ public: if(!pbo_) BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to allocate buffer.")); - //CASPAR_LOG(trace) << "[host_buffer] allocated size:" << size_ << " usage: " << (usage == write_only ? "write_only" : "read_only"); + CASPAR_LOG(trace) << "[host_buffer] [" << ++(usage_ == write_only ? g_w_total_count : g_r_total_count) << L"] allocated size:" << size_ << " usage: " << (usage == write_only ? "write_only" : "read_only"); } ~implementation() @@ -60,6 +71,7 @@ public: try { GL(glDeleteBuffers(1, &pbo_)); + CASPAR_LOG(trace) << "[host_buffer] [" << --(usage_ == write_only ? g_w_total_count : g_r_total_count) << L"] deallocated size:" << size_ << " usage: " << (usage_ == write_only ? "write_only" : "read_only"); } catch(...) { @@ -76,12 +88,17 @@ public: GL(glBufferData(target_, size_, NULL, usage_)); // Notify OpenGL that we don't care about previous data. GL(glBindBuffer(target_, pbo_)); - data_ = glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY); + data_ = GL2(glMapBuffer(target_, usage_ == GL_STREAM_DRAW ? GL_WRITE_ONLY : GL_READ_ONLY)); GL(glBindBuffer(target_, 0)); if(!data_) BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target_ OpenGL Pixel Buffer Object.")); } + void wait(ogl_device& ogl) + { + fence_.wait(ogl); + } + void unmap() { if(!data_) @@ -102,6 +119,20 @@ public: { GL(glBindBuffer(target_, 0)); } + + void begin_read(size_t width, size_t height, GLuint format) + { + unmap(); + bind(); + GL(glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, NULL)); + unbind(); + fence_.set(); + } + + bool ready() const + { + return fence_.ready(); + } }; host_buffer::host_buffer(size_t size, usage_t usage) : impl_(new implementation(size, usage)){} @@ -111,7 +142,9 @@ void host_buffer::map(){impl_->map();} void host_buffer::unmap(){impl_->unmap();} void host_buffer::bind(){impl_->bind();} void host_buffer::unbind(){impl_->unbind();} - +void host_buffer::begin_read(size_t width, size_t height, GLuint format){impl_->begin_read(width, height, format);} size_t host_buffer::size() const { return impl_->size_; } +bool host_buffer::ready() const{return impl_->ready();} +void host_buffer::wait(ogl_device& ogl){impl_->wait(ogl);} }} \ No newline at end of file