#include "../../common/concurrency/executor.h"\r
#include "../../common/utility/memory.h"\r
#include "../../common/gl/gl_check.h"\r
+#include "../../common/gl/frame_buffer_object.h"\r
\r
#include <Glee.h>\r
#include <SFML/Window.hpp>\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
+ glLoadIdentity(); \r
+\r
+ fbo_.create(format_desc_.width, format_desc_.height);\r
+ fbo_.bind_pixel_source();\r
+\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
+ for(int n = 0; n < 2; ++n)\r
+ composite(std::vector<gpu_frame_ptr>());\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
\r
~implementation()\r
{\r
- glDeleteFramebuffersEXT(1, &fbo_);\r
executor_.stop();\r
}\r
\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
+ writing_[index_]->begin_write();\r
\r
// 3. Output to external buffer.\r
- if(output_frame_->read_unlock())\r
+ if(output_frame_)\r
+ { \r
+ output_frame_->end_read();\r
output_.push(output_frame_);\r
- \r
+ }\r
+\r
// Clear framebuffer.\r
- glClear(GL_COLOR_BUFFER_BIT); \r
+ GL(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_output_frame();\r
+ auto temp_frame = create_output_frame();\r
\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
+ temp_frame->begin_read();\r
+ temp_frame->audio_data() = std::move(writing_[next_index]->audio_data());\r
+\r
+ output_frame_ = temp_frame;\r
\r
// Return frames to pool.\r
+ writing_[next_index]->end_write();\r
writing_[next_index] = nullptr;\r
}\r
catch(...)\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
+ frame.reset(new gpu_frame(format_desc_.width, format_desc_.height));\r
\r
return gpu_frame_ptr(frame.get(), [=](gpu_frame*)\r
{\r
gpu_frame_ptr frame;\r
if(!pool.try_pop(frame))\r
{\r
- frame = executor_.invoke([=]() -> gpu_frame_ptr\r
+ frame = executor_.invoke([&]\r
{\r
- auto frame = std::make_shared<gpu_frame>(width, height);\r
- frame->write_unlock();\r
- return frame;\r
+ return std::shared_ptr<gpu_frame>(new gpu_frame(width, height));\r
});\r
}\r
\r
auto destructor = [=]\r
{\r
- frame->write_unlock();\r
frame->reset();\r
writing_pools_[key].push(frame);\r
};\r
\r
common::executor executor_;\r
\r
- GLuint render_texture_;\r
- GLuint fbo_;\r
+ common::gl::frame_buffer_object fbo_;\r
};\r
\r
gpu_frame_processor::gpu_frame_processor(const frame_format_desc& format_desc) : impl_(new implementation(format_desc)){}\r