*/\r
#include "../../stdafx.h"\r
\r
-#include "../gpu/host_buffer.h"\r
+#include "host_buffer.h"\r
\r
+#include "fence.h"\r
+#include "device_buffer.h"\r
+#include "ogl_device.h"\r
+\r
+#include <common/exception/exceptions.h>\r
#include <common/gl/gl_check.h>\r
\r
+#include <gl/glew.h>\r
+\r
+#include <tbb/atomic.h>\r
+\r
namespace caspar { namespace core {\r
+\r
+static tbb::atomic<int> g_w_total_count;\r
+static tbb::atomic<int> g_r_total_count;\r
\r
struct host_buffer::implementation : boost::noncopyable\r
{ \r
- GLuint pbo_;\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
+ fence fence_;\r
\r
public:\r
implementation(size_t size, usage_t usage) \r
if(!pbo_)\r
BOOST_THROW_EXCEPTION(caspar_exception() << msg_info("Failed to allocate buffer."));\r
\r
- //CASPAR_LOG(trace) << "[host_buffer] allocated size:" << size_ << " usage: " << (usage == write_only ? "write_only" : "read_only");\r
+ 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");\r
} \r
\r
~implementation()\r
{\r
- GL(glDeleteBuffers(1, &pbo_));\r
+ try\r
+ {\r
+ GL(glDeleteBuffers(1, &pbo_));\r
+ //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");\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ }\r
}\r
\r
void map()\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
\r
+ void wait(ogl_device& ogl)\r
+ {\r
+ fence_.wait(ogl);\r
+ }\r
+\r
void unmap()\r
{\r
if(!data_)\r
{\r
GL(glBindBuffer(target_, 0));\r
}\r
+\r
+ void begin_read(size_t width, size_t height, GLuint format)\r
+ {\r
+ unmap();\r
+ bind();\r
+ GL(glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, NULL));\r
+ unbind();\r
+ fence_.set();\r
+ }\r
+\r
+ bool ready() const\r
+ {\r
+ return fence_.ready();\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
-\r
+void host_buffer::begin_read(size_t width, size_t height, GLuint format){impl_->begin_read(width, height, format);}\r
size_t host_buffer::size() const { return impl_->size_; }\r
+bool host_buffer::ready() const{return impl_->ready();}\r
+void host_buffer::wait(ogl_device& ogl){impl_->wait(ogl);}\r
\r
}}
\ No newline at end of file