]> git.sesse.net Git - casparcg/blob - core/frame/gpu_frame.cpp
2.0.0.2:
[casparcg] / core / frame / gpu_frame.cpp
1 #include "../StdAfx.h"\r
2 \r
3 #include "gpu_frame.h"\r
4 #include "../../common/utility/memory.h"\r
5 #include "../../common/gl/gl_check.h"\r
6 #include "../../common/gl/pixel_buffer_object.h"\r
7 \r
8 namespace caspar { namespace core {\r
9         \r
10 GLubyte progressive_pattern[] = {\r
11         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
12         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
13         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
14         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
15         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
16         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
17         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
18         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
19         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
20         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
21         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
22         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
23         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
24         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\r
25         0xff, 0xff, 0xFF, 0xff, 0xff, 0xff, 0xff, 0xff,\r
26         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
27         \r
28 GLubyte upper_pattern[] = {\r
29         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
30         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
31         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
32         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
33         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
34         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
35         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
36         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
37         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
38         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
39         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
40         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
41         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
42         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
43         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
44         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
45                 \r
46 GLubyte lower_pattern[] = {\r
47                                                         0x00, 0x00, 0x00, 0x00,\r
48         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
49         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
50         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
51         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
52         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
53         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
54         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
55         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
56         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
57         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
58         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
59         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
60         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
61         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
62         0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
63         0xff, 0xff, 0xff, 0xff};\r
64                                                                                                                                                                                                                                                                                                                 \r
65 struct gpu_frame::implementation : boost::noncopyable\r
66 {\r
67         implementation(size_t width, size_t height) \r
68                 : pbo_(width, height), data_(nullptr), width_(width), height_(height), \r
69                         size_(width*height*4), reading_(false), alpha_(1.0f), \r
70                         x_(0.0f), y_(0.0f), mode_(video_mode::progressive), \r
71                         texcoords_(0.0, 1.0, 1.0, 0.0), writing_(false), mapped_(false)\r
72         {       \r
73                 if(width > 0 && height > 0)\r
74                         end_write();\r
75         }\r
76         \r
77         void begin_write()\r
78         {\r
79                 data_ = nullptr;\r
80                 pbo_.begin_write();             \r
81         }\r
82 \r
83         void end_write()\r
84         {\r
85                 data_ = static_cast<unsigned char*>(pbo_.end_write());\r
86         }\r
87         \r
88         void begin_read()\r
89         {       \r
90                 data_ = nullptr;\r
91                 pbo_.begin_read();\r
92         }\r
93 \r
94         void end_read()\r
95         {\r
96                 data_ = static_cast<unsigned char*>(pbo_.end_read());\r
97         }\r
98 \r
99         void draw()\r
100         {\r
101                 glPushMatrix();\r
102                 glTranslated(x_*2.0, y_*2.0, 0.0);\r
103                 glColor4d(1.0, 1.0, 1.0, alpha_);\r
104 \r
105                 if(mode_ == video_mode::progressive)\r
106                         glPolygonStipple(progressive_pattern);\r
107                 else if(mode_ == video_mode::upper)\r
108                         glPolygonStipple(upper_pattern);\r
109                 else if(mode_ == video_mode::lower)\r
110                         glPolygonStipple(lower_pattern);\r
111 \r
112                 pbo_.bind_texture();\r
113                 glBegin(GL_QUADS);\r
114                         glTexCoord2d(texcoords_.left,   texcoords_.bottom); glVertex2d(-1.0, -1.0);\r
115                         glTexCoord2d(texcoords_.right,  texcoords_.bottom); glVertex2d( 1.0, -1.0);\r
116                         glTexCoord2d(texcoords_.right,  texcoords_.top);        glVertex2d( 1.0,  1.0);\r
117                         glTexCoord2d(texcoords_.left,   texcoords_.top);        glVertex2d(-1.0,  1.0);\r
118                 glEnd();\r
119                 glPopMatrix();\r
120         }\r
121                 \r
122         unsigned char* data()\r
123         {\r
124                 if(data_ == nullptr)\r
125                         BOOST_THROW_EXCEPTION(invalid_operation());\r
126                 return data_;\r
127         }\r
128 \r
129         void reset()\r
130         {\r
131                 audio_data_.clear();\r
132                 alpha_     = 1.0f;\r
133                 x_         = 0.0f;\r
134                 y_         = 0.0f;\r
135                 texcoords_ = rectangle(0.0, 1.0, 1.0, 0.0);\r
136                 mode_      = video_mode::progressive;\r
137         }\r
138 \r
139         common::gl::pixel_buffer_object pbo_;\r
140         gpu_frame* self_;\r
141         unsigned char* data_;\r
142         size_t width_;\r
143         size_t height_;\r
144         size_t size_;\r
145 \r
146         bool reading_;\r
147         bool writing_;\r
148         bool mapped_;\r
149 \r
150         std::vector<short> audio_data_;\r
151 \r
152         double alpha_;\r
153         double x_;\r
154         double y_;\r
155         video_mode mode_;\r
156         rectangle texcoords_;\r
157 };\r
158 \r
159 gpu_frame::gpu_frame(size_t width, size_t height) \r
160         : impl_(new implementation(width, height)){}\r
161 void gpu_frame::begin_write(){impl_->begin_write();}\r
162 void gpu_frame::end_write(){impl_->end_write();}        \r
163 void gpu_frame::begin_read(){impl_->begin_read();}\r
164 void gpu_frame::end_read(){impl_->end_read();}\r
165 void gpu_frame::draw(){impl_->draw();}\r
166 unsigned char* gpu_frame::data(){return impl_->data();}\r
167 size_t gpu_frame::size() const { return impl_->size_; }\r
168 size_t gpu_frame::width() const { return impl_->width_;}\r
169 size_t gpu_frame::height() const { return impl_->height_;}\r
170 const std::vector<short>& gpu_frame::audio_data() const{return impl_->audio_data_;}     \r
171 std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }\r
172 void gpu_frame::reset(){impl_->reset();}\r
173 double gpu_frame::alpha() const{ return impl_->alpha_;}\r
174 void gpu_frame::alpha(double value){ impl_->alpha_ = value;}\r
175 double gpu_frame::x() const { return impl_->x_;}\r
176 double gpu_frame::y() const { return impl_->y_;}\r
177 void gpu_frame::translate(double x, double y) { impl_->x_ += x; impl_->y_ += y; }\r
178 void gpu_frame::texcoords(const rectangle& texcoords){impl_->texcoords_ = texcoords;}\r
179 void gpu_frame::mode(video_mode mode){ impl_->mode_ = mode;}\r
180 video_mode gpu_frame::mode() const{ return impl_->mode_;}\r
181 }}