]> git.sesse.net Git - casparcg/blobdiff - core/frame/gpu_frame.cpp
2.0.0.2:
[casparcg] / core / frame / gpu_frame.cpp
index f66b3581536f3bd2a511db68cf24ad0cfed6702a..b659a5b3daf6552b9231c43a80d1e04e943325a4 100644 (file)
@@ -64,40 +64,55 @@ GLubyte lower_pattern[] = {
                                                                                                                                                                                                                                                                                                                \r
 struct gpu_frame::implementation : boost::noncopyable\r
 {\r
-       implementation(size_t width, size_t height) \r
-               : pbo_(width, height), data_(nullptr), width_(width), height_(height), \r
-                       size_(width*height*4), reading_(false), alpha_(1.0f), \r
-                       x_(0.0f), y_(0.0f), mode_(video_mode::progressive), \r
-                       texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false)\r
-       {       \r
+       implementation(size_t width, size_t height)\r
+               : reading_(false), alpha_(1.0f),        x_(0.0f), y_(0.0f), mode_(video_mode::progressive), \r
+                       texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false), pix_format_(pixel_format::bgra)\r
+       {                       \r
+               data_.resize(1, 0);\r
+               pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(width, height, GL_BGRA));\r
                if(width > 0 && height > 0)\r
                        end_write();\r
        }\r
+\r
+       implementation(const planar_frame_dimension& data_size)\r
+               : reading_(false), alpha_(1.0f),        x_(0.0f), y_(0.0f), mode_(video_mode::progressive), \r
+                       texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false), pix_format_(pixel_format::bgra)\r
+       {                       \r
+               data_.resize(data_size.size(), 0);\r
+               for(size_t n = 0; n < data_size.size() && data_size[n].first > 0 && data_size[n].second > 0; ++n)\r
+                       pbo_.push_back(std::make_shared<common::gl::pixel_buffer_object>(data_size[n].first, data_size[n].second, GL_LUMINANCE));\r
+               end_write();\r
+       }\r
        \r
        void begin_write()\r
        {\r
-               data_ = nullptr;\r
-               pbo_.begin_write();             \r
+               data_ = std::vector<unsigned char*>(4, 0);\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+                       pbo_[n]->begin_write();         \r
        }\r
 \r
        void end_write()\r
        {\r
-               data_ = static_cast<unsigned char*>(pbo_.end_write());\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+                       data_[n] = static_cast<unsigned char*>(pbo_[n]->end_write());\r
        }\r
        \r
        void begin_read()\r
        {       \r
-               data_ = nullptr;\r
-               pbo_.begin_read();\r
+               data_ = std::vector<unsigned char*>(4, 0);\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+                       pbo_[n]->begin_read();  \r
        }\r
 \r
        void end_read()\r
        {\r
-               data_ = static_cast<unsigned char*>(pbo_.end_read());\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+                       data_[n] = static_cast<unsigned char*>(pbo_[n]->end_read());\r
        }\r
 \r
-       void draw()\r
+       void draw(const gpu_frame_transform_ptr& transform)\r
        {\r
+               transform->set_pixel_format(pix_format_);\r
                glPushMatrix();\r
                glTranslated(x_*2.0, y_*2.0, 0.0);\r
                glColor4d(1.0, 1.0, 1.0, alpha_);\r
@@ -109,7 +124,11 @@ struct gpu_frame::implementation : boost::noncopyable
                else if(mode_ == video_mode::lower)\r
                        glPolygonStipple(lower_pattern);\r
 \r
-               pbo_.bind_texture();\r
+               for(size_t n = 0; n < pbo_.size(); ++n)\r
+               {\r
+                       glActiveTexture(GL_TEXTURE0+n);\r
+                       pbo_[n]->bind_texture();\r
+               }\r
                glBegin(GL_QUADS);\r
                        glTexCoord2d(texcoords_.left,   texcoords_.bottom); glVertex2d(-1.0, -1.0);\r
                        glTexCoord2d(texcoords_.right,  texcoords_.bottom); glVertex2d( 1.0, -1.0);\r
@@ -119,11 +138,11 @@ struct gpu_frame::implementation : boost::noncopyable
                glPopMatrix();\r
        }\r
                \r
-       unsigned char* data()\r
+       unsigned char* data(size_t index)\r
        {\r
-               if(data_ == nullptr)\r
+               if(pbo_.size() < index || data_[index] == nullptr)\r
                        BOOST_THROW_EXCEPTION(invalid_operation());\r
-               return data_;\r
+               return data_[index];\r
        }\r
 \r
        void reset()\r
@@ -136,12 +155,10 @@ struct gpu_frame::implementation : boost::noncopyable
                mode_      = video_mode::progressive;\r
        }\r
 \r
-       common::gl::pixel_buffer_object pbo_;\r
+       std::vector<common::gl::pixel_buffer_object_ptr> pbo_;\r
+       std::vector<unsigned char*> data_;\r
+\r
        gpu_frame* self_;\r
-       unsigned char* data_;\r
-       size_t width_;\r
-       size_t height_;\r
-       size_t size_;\r
 \r
        bool reading_;\r
        bool writing_;\r
@@ -154,20 +171,23 @@ struct gpu_frame::implementation : boost::noncopyable
        double y_;\r
        video_mode mode_;\r
        rectangle texcoords_;\r
+       pixel_format pix_format_;\r
 };\r
 \r
 gpu_frame::gpu_frame(size_t width, size_t height) \r
        : impl_(new implementation(width, height)){}\r
+gpu_frame::gpu_frame(const planar_frame_dimension& data_size)\r
+       : impl_(new implementation(data_size)){}\r
 void gpu_frame::begin_write(){impl_->begin_write();}\r
 void gpu_frame::end_write(){impl_->end_write();}       \r
 void gpu_frame::begin_read(){impl_->begin_read();}\r
 void gpu_frame::end_read(){impl_->end_read();}\r
-void gpu_frame::draw(){impl_->draw();}\r
-unsigned char* gpu_frame::data(){return impl_->data();}\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
+void gpu_frame::draw(const gpu_frame_transform_ptr& transform){impl_->draw(transform);}\r
+void gpu_frame::set_pixel_format(pixel_format format) {impl_->pix_format_ = format;}\r
+unsigned char* gpu_frame::data(size_t index){return impl_->data(index);}\r
+size_t gpu_frame::size(size_t index) const { return impl_->pbo_.at(index)->size(); }\r
+size_t gpu_frame::width(size_t index) const { return impl_->pbo_.at(index)->width();}\r
+size_t gpu_frame::height(size_t index) const { return impl_->pbo_.at(index)->height();}\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