namespace caspar { namespace core {\r
\r
GLubyte progressive_pattern[] = {\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff,\r
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff,\r
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
\r
GLubyte upper_pattern[] = {\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
\r
GLubyte lower_pattern[] = {\r
0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
0xff, 0xff, 0xff, 0xff};\r
-\r
+ \r
struct gpu_frame::implementation : boost::noncopyable\r
{\r
implementation(size_t width, size_t height) \r
- : pbo_(0), data_(nullptr), width_(width), height_(height), size_(width*height*4), \r
- reading_(false), texture_(0), alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive)\r
+ : pbo_(0), data_(nullptr), width_(width), height_(height), \r
+ size_(width*height*4), reading_(false), texture_(0), alpha_(1.0f), \r
+ x_(0.0f), y_(0.0f), mode_(video_mode::progressive)\r
{ \r
}\r
\r
GLuint pbo()\r
{ \r
if(pbo_ == 0)\r
- CASPAR_GL_CHECK(glGenBuffers(1, &pbo_));\r
+ GL(glGenBuffers(1, &pbo_));\r
return pbo_;\r
}\r
\r
{\r
if(texture_ == 0)\r
{\r
- CASPAR_GL_CHECK(glGenTextures(1, &texture_));\r
+ GL(glGenTextures(1, &texture_));\r
\r
- CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));\r
+ GL(glBindTexture(GL_TEXTURE_2D, texture_));\r
\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\r
+ GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));\r
+ GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));\r
+ GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));\r
+ GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\r
\r
- CASPAR_GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));\r
+ GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA, \r
+ GL_UNSIGNED_BYTE, NULL));\r
}\r
\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));\r
+ GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));\r
if(data_ != nullptr)\r
{\r
- CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));\r
+ GL(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));\r
data_ = nullptr;\r
}\r
- CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));\r
- CASPAR_GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));\r
+ GL(glBindTexture(GL_TEXTURE_2D, texture_));\r
+ GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, \r
+ GL_UNSIGNED_BYTE, NULL));\r
+ GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));\r
}\r
\r
bool write_unlock()\r
{\r
if(data_ != nullptr)\r
return false;\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));\r
- CASPAR_GL_CHECK(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW));\r
+ GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));\r
+ GL(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW));\r
void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));\r
+ GL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));\r
data_ = reinterpret_cast<unsigned char*>(ptr);\r
if(!data_)\r
- BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("glMapBuffer failed"));\r
+ BOOST_THROW_EXCEPTION(invalid_operation() \r
+ << msg_info("glMapBuffer failed"));\r
return true;\r
}\r
\r
void read_lock(GLenum mode)\r
{ \r
- CASPAR_GL_CHECK(glReadBuffer(mode));\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));\r
+ GL(glReadBuffer(mode));\r
+ GL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));\r
if(data_ != nullptr) \r
{ \r
- CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); \r
+ GL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER)); \r
data_ = nullptr;\r
}\r
- CASPAR_GL_CHECK(glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ)); \r
- CASPAR_GL_CHECK(glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));\r
+ GL(glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ)); \r
+ GL(glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));\r
+ GL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));\r
reading_ = true;\r
}\r
\r
{\r
if(data_ != nullptr || !reading_)\r
return false;\r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));\r
+ GL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));\r
void* ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); \r
- CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));\r
+ GL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));\r
data_ = reinterpret_cast<unsigned char*>(ptr);\r
if(!data_)\r
BOOST_THROW_EXCEPTION(std::bad_alloc());\r
else if(mode_ == video_mode::lower)\r
glPolygonStipple(lower_pattern);\r
\r
- CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));\r
+ GL(glBindTexture(GL_TEXTURE_2D, texture_));\r
glBegin(GL_QUADS);\r
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);\r
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);\r
{\r
audio_data_.clear();\r
alpha_ = 1.0f;\r
- x_ = 0.0f;\r
- y_ = 0.0f;\r
- mode_ = video_mode::progressive;\r
+ x_ = 0.0f;\r
+ y_ = 0.0f;\r
+ mode_ = video_mode::progressive;\r
}\r
\r
gpu_frame* self_;\r
video_mode mode_;\r
};\r
\r
-gpu_frame::gpu_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}\r
+gpu_frame::gpu_frame(size_t width, size_t height) \r
+ : impl_(new implementation(width, height)){}\r
void gpu_frame::write_lock(){impl_->write_lock();}\r
bool gpu_frame::write_unlock(){return impl_->write_unlock();} \r
void gpu_frame::read_lock(GLenum mode){impl_->read_lock(mode);}\r
size_t gpu_frame::size() const { return impl_->size_; }\r
size_t gpu_frame::width() const { return impl_->width_;}\r
size_t gpu_frame::height() const { return impl_->height_;}\r
-const std::vector<short>& gpu_frame::audio_data() const { return impl_->audio_data_; } \r
+const std::vector<short>& gpu_frame::audio_data() const{return impl_->audio_data_;} \r
std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }\r
void gpu_frame::reset(){impl_->reset();}\r
double gpu_frame::alpha() const{ return impl_->alpha_;}\r
\r
namespace caspar { namespace core {\r
\r
-class frame_buffer : boost::noncopyable\r
-{\r
-public:\r
- frame_buffer(size_t width, size_t height)\r
- {\r
- CASPAR_GL_CHECK(glGenTextures(1, &texture_)); \r
-\r
- CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));\r
-\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));\r
- CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));\r
- //CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));\r
- //CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\r
-\r
- CASPAR_GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));\r
-\r
- glGenFramebuffersEXT(1, &fbo_);\r
- \r
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);\r
- glBindTexture(GL_TEXTURE_2D, texture_);\r
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture_, 0);\r
- }\r
-\r
- ~frame_buffer()\r
- {\r
- glDeleteFramebuffersEXT(1, &fbo_);\r
- }\r
- \r
- GLuint handle() { return fbo_; }\r
- GLenum attachement() { return GL_COLOR_ATTACHMENT0_EXT; }\r
- \r
-private:\r
- GLuint texture_;\r
- GLuint fbo_;\r
-};\r
-typedef std::shared_ptr<frame_buffer> frame_buffer_ptr;\r
-\r
struct gpu_frame_processor::implementation : boost::noncopyable\r
{ \r
- implementation(const frame_format_desc& format_desc) : format_desc_(format_desc)\r
+ implementation(const frame_format_desc& format_desc) \r
+ : format_desc_(format_desc), index_(0)\r
{ \r
input_.set_capacity(2);\r
executor_.start();\r
{\r
ogl_context_.reset(new sf::Context());\r
ogl_context_->SetActive(true);\r
- CASPAR_GL_CHECK(glEnable(GL_POLYGON_STIPPLE));\r
- CASPAR_GL_CHECK(glEnable(GL_TEXTURE_2D));\r
- CASPAR_GL_CHECK(glEnable(GL_BLEND));\r
- CASPAR_GL_CHECK(glDisable(GL_DEPTH_TEST));\r
- CASPAR_GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); \r
- CASPAR_GL_CHECK(glClearColor(0.0, 0.0, 0.0, 0.0));\r
- CASPAR_GL_CHECK(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
- glLoadIdentity(); \r
+ GL(glEnable(GL_POLYGON_STIPPLE));\r
+ GL(glEnable(GL_TEXTURE_2D));\r
+ GL(glEnable(GL_BLEND));\r
+ GL(glDisable(GL_DEPTH_TEST));\r
+ GL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); \r
+ GL(glClearColor(0.0, 0.0, 0.0, 0.0));\r
+ GL(glViewport(0, 0, format_desc_.width, format_desc_.height));\r
+ glLoadIdentity(); \r
+ \r
+ // Create and bind a framebuffer\r
+ GL(glGenTextures(1, &render_texture_)); \r
+ GL(glBindTexture(GL_TEXTURE_2D, render_texture_)); \r
+ GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, format_desc_.width, \r
+ format_desc_.height, 0, GL_BGRA, \r
+ GL_UNSIGNED_BYTE, NULL));\r
+ GL(glGenFramebuffersEXT(1, &fbo_)); \r
+ GL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_));\r
+ GL(glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, \r
+ GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, \r
+ render_texture_, 0));\r
\r
- reading_.resize(2, std::make_shared<gpu_composite_frame>(format_desc_.width, format_desc_.height));\r
- writing_.resize(2, std::make_shared<gpu_composite_frame>(format_desc_.width, format_desc_.height));\r
- fbo_ = std::make_shared<frame_buffer>(format_desc_.width, format_desc_.height);\r
- output_frame_ = std::make_shared<gpu_frame>(format_desc_.width, format_desc_.height);\r
- index_ = 0;\r
+ writing_.resize(2, std::make_shared<gpu_composite_frame>());\r
+ output_frame_ = std::make_shared<gpu_frame>(format_desc_.width, \r
+ format_desc_.height);\r
});\r
+ // Fill pipeline\r
composite(std::vector<gpu_frame_ptr>());\r
composite(std::vector<gpu_frame_ptr>());\r
composite(std::vector<gpu_frame_ptr>());\r
\r
~implementation()\r
{\r
+ glDeleteFramebuffersEXT(1, &fbo_);\r
executor_.stop();\r
}\r
\r
{\r
boost::range::remove_erase(frames, nullptr);\r
boost::range::remove_erase(frames, gpu_frame::null());\r
- auto composite_frame = std::make_shared<gpu_composite_frame>(format_desc_.width, format_desc_.height);\r
- boost::range::for_each(frames, std::bind(&gpu_composite_frame::add, composite_frame, std::placeholders::_1));\r
- input_.push(composite_frame);\r
+ auto composite_frame = std::make_shared<gpu_composite_frame>();\r
+ boost::range::for_each(frames, std::bind(&gpu_composite_frame::add, \r
+ composite_frame, \r
+ std::placeholders::_1));\r
\r
+ input_.push(composite_frame);\r
executor_.begin_invoke([=]\r
{\r
try\r
{\r
- gpu_composite_frame_ptr frame;\r
+ gpu_frame_ptr frame;\r
input_.pop(frame);\r
\r
index_ = (index_ + 1) % 2;\r
int next_index = (index_ + 1) % 2;\r
\r
- // 2. Start asynchronous DMA transfer to video memory\r
- // Lock frames and give pointer ownership to OpenGL \r
- writing_[index_] = std::move(reading_[index_]); \r
+ // 1. Start asynchronous DMA transfer to video memory.\r
+ writing_[index_] = std::move(frame); \r
+ // Lock frame and give pointer ownership to OpenGL.\r
writing_[index_]->write_lock();\r
\r
- // 1. Copy to page-locked memory\r
- reading_[next_index] = std::move(frame);\r
- \r
- // 4. Output to external buffer\r
+ // 3. Output to external buffer.\r
if(output_frame_->read_unlock())\r
output_.push(output_frame_);\r
\r
- // 3. Draw to framebuffer and start asynchronous DMA transfer to page-locked memory \r
- // Clear framebuffer\r
+ // Clear framebuffer.\r
glClear(GL_COLOR_BUFFER_BIT); \r
+\r
+ // 2. Draw to framebuffer and start asynchronous DMA transfer \r
+ // to page-locked memory.\r
writing_[next_index]->draw();\r
\r
// Create an output frame\r
- output_frame_ = create_frame(format_desc_.width, format_desc_.height);\r
+ output_frame_ = create_output_frame();\r
\r
- // Read from framebuffer into page-locked memory\r
+ // Read from framebuffer into page-locked memory.\r
output_frame_->read_lock(GL_COLOR_ATTACHMENT0_EXT);\r
output_frame_->audio_data() = std::move(writing_[next_index]->audio_data());\r
\r
- // Return frames to pool\r
+ // Return frames to pool.\r
writing_[next_index] = nullptr;\r
}\r
catch(...)\r
}\r
}); \r
}\r
+\r
+ gpu_frame_ptr create_output_frame()\r
+ {\r
+ gpu_frame_ptr frame;\r
+ if(!reading_pool_.try_pop(frame))\r
+ frame = std::make_shared<gpu_frame>(format_desc_.width, \r
+ format_desc_.height);\r
+\r
+ return gpu_frame_ptr(frame.get(), [=](gpu_frame*)\r
+ {\r
+ frame->reset();\r
+ reading_pool_.push(frame);\r
+ });\r
+ }\r
\r
gpu_frame_ptr create_frame(size_t width, size_t height)\r
{\r
size_t key = width | (height << 16);\r
- auto& pool = reading_frame_pools_[key];\r
+ auto& pool = writing_pools_[key];\r
\r
gpu_frame_ptr frame;\r
if(!pool.try_pop(frame))\r
{\r
frame->write_unlock();\r
frame->reset();\r
- reading_frame_pools_[key].push(frame);\r
+ writing_pools_[key].push(frame);\r
};\r
\r
- return gpu_frame_ptr(frame.get(), [=](gpu_frame*)\r
+ return gpu_frame_ptr(frame.get(), [=](gpu_frame*) \r
{\r
executor_.begin_invoke(destructor);\r
});\r
output_.pop(frame);\r
}\r
\r
- tbb::concurrent_unordered_map<size_t, tbb::concurrent_bounded_queue<gpu_frame_ptr>> reading_frame_pools_;\r
-\r
- frame_buffer_ptr fbo_;\r
+ typedef tbb::concurrent_bounded_queue<gpu_frame_ptr> gpu_frame_queue;\r
+ tbb::concurrent_unordered_map<size_t, gpu_frame_queue> writing_pools_;\r
+ gpu_frame_queue reading_pool_; \r
\r
- tbb::concurrent_bounded_queue<gpu_composite_frame_ptr> input_;\r
- tbb::concurrent_bounded_queue<gpu_frame_ptr> output_; \r
+ gpu_frame_queue input_;\r
+ std::vector<gpu_frame_ptr> writing_;\r
+ gpu_frame_queue output_; \r
\r
size_t index_;\r
- std::vector<gpu_composite_frame_ptr> reading_;\r
- std::vector<gpu_composite_frame_ptr> writing_;\r
\r
gpu_frame_ptr output_frame_; \r
frame_format_desc format_desc_;\r
std::unique_ptr<sf::Context> ogl_context_;\r
\r
common::executor executor_;\r
+\r
+ GLuint render_texture_;\r
+ GLuint fbo_;\r
};\r
\r
gpu_frame_processor::gpu_frame_processor(const frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r