X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=core%2Fmixer%2Fgpu%2Fhost_buffer.cpp;h=aefcb9e5b5f6e8b8e80e900c06dcc42d059ba413;hb=af660bb0772edbc122286d1e1bc1ded9bc6b2794;hp=d9fe6933545dd28e1e3e9a9b418ba1899f3fa1cf;hpb=dfbde5d6d0fcff021c60c0240d94fece52481cf5;p=casparcg diff --git a/core/mixer/gpu/host_buffer.cpp b/core/mixer/gpu/host_buffer.cpp index d9fe69335..aefcb9e5b 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,12 +63,20 @@ 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(debug) << "[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() { - GL(glDeleteBuffers(1, &pbo_)); + try + { + GL(glDeleteBuffers(1, &pbo_)); + CASPAR_LOG(debug) << "[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(...) + { + CASPAR_LOG_CURRENT_EXCEPTION(); + } } void map() @@ -69,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_) @@ -95,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)){} @@ -104,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