1 #include "../StdAfx.h"
\r
3 #include "pixel_buffer_object.h"
\r
5 #include "../../common/exception/exceptions.h"
\r
6 #include "../../common/gl/gl_check.h"
\r
7 #include "../../common/utility/memory.h"
\r
9 namespace caspar { namespace common { namespace gl {
\r
11 struct pixel_buffer_object::implementation : boost::noncopyable
\r
13 implementation(size_t width, size_t height)
\r
14 : width_(width), height_(height), size_(width*height*4), pbo_(0),
\r
15 texture_(0), writing_(false), reading_(false), mapped_(false){}
\r
20 glDeleteBuffers(1, &pbo_);
\r
23 void bind_pbo(GLenum mode)
\r
26 GL(glGenBuffers(1, &pbo_));
\r
27 GL(glBindBuffer(mode, pbo_));
\r
30 void unbind_pbo(GLenum mode)
\r
32 GL(glBindBuffer(mode, 0));
\r
39 GL(glGenTextures(1, &texture_));
\r
41 GL(glBindTexture(GL_TEXTURE_2D, texture_));
\r
43 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
\r
44 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
\r
45 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
\r
46 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
\r
48 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA,
\r
49 GL_UNSIGNED_BYTE, NULL));
\r
51 GL(glBindTexture(GL_TEXTURE_2D, texture_));
\r
56 bind_pbo(GL_PIXEL_UNPACK_BUFFER);
\r
58 GL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
\r
61 GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA,
\r
62 GL_UNSIGNED_BYTE, NULL));
\r
63 unbind_pbo(GL_PIXEL_UNPACK_BUFFER);
\r
70 BOOST_THROW_EXCEPTION(invalid_operation());
\r
72 bind_pbo(GL_PIXEL_UNPACK_BUFFER);
\r
73 GL(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW));
\r
74 auto data = static_cast<unsigned char*>(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
\r
75 unbind_pbo(GL_PIXEL_UNPACK_BUFFER);
\r
77 BOOST_THROW_EXCEPTION(invalid_operation()
\r
78 << msg_info("glMapBuffer failed"));
\r
86 bind_pbo(GL_PIXEL_PACK_BUFFER);
\r
88 GL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
\r
90 GL(glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ));
\r
91 GL(glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
92 unbind_pbo(GL_PIXEL_PACK_BUFFER);
\r
99 BOOST_THROW_EXCEPTION(invalid_operation());
\r
101 bind_pbo(GL_PIXEL_PACK_BUFFER);
\r
102 auto data = static_cast<unsigned char*>(glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY));
\r
103 unbind_pbo(GL_PIXEL_PACK_BUFFER);
\r
105 BOOST_THROW_EXCEPTION(std::bad_alloc());
\r
123 pixel_buffer_object::pixel_buffer_object(){}
\r
124 pixel_buffer_object::pixel_buffer_object(size_t width, size_t height)
\r
125 : impl_(new implementation(width, height)){}
\r
126 void pixel_buffer_object::create(size_t width, size_t height)
\r
128 impl_.reset(new implementation(width, height));
\r
130 void pixel_buffer_object::begin_write() { impl_->begin_write();}
\r
131 void* pixel_buffer_object::end_write() {return impl_->end_write();}
\r
132 void pixel_buffer_object::begin_read() { impl_->begin_read();}
\r
133 void* pixel_buffer_object::end_read(){return impl_->end_read();}
\r
134 void pixel_buffer_object::bind_texture() {impl_->bind_texture();}
\r
135 size_t pixel_buffer_object::width() const {return impl_->width_;}
\r
136 size_t pixel_buffer_object::heigth() const {return impl_->height_;}
\r
137 size_t pixel_buffer_object::size() const {return impl_->size_;}
\r
138 bool pixel_buffer_object::is_reading() const { return impl_->reading_;}
\r
139 bool pixel_buffer_object::is_writing() const { return impl_->writing_;}
\r