1 #include "../StdAfx.h"
\r
3 #include "gpu_frame.h"
\r
4 #include "../../common/utility/memory.h"
\r
5 #include "../../common/gl/utility.h"
\r
9 GLubyte progressive_pattern[] = {
\r
10 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
\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
27 GLubyte upper_pattern[] = {
\r
28 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
\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
45 GLubyte lower_pattern[] = {
\r
46 0x00, 0x00, 0x00, 0x00,
\r
47 0xff, 0xff, 0xff, 0xff, 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};
\r
64 struct gpu_frame::implementation
\r
66 implementation(size_t width, size_t height)
\r
67 : pbo_(0), data_(nullptr), width_(width), height_(height), size_(width*height*4),
\r
68 reading_(false), texture_(0), alpha_(1.0f), x_(0.0f), y_(0.0f), mode_(video_mode::progressive)
\r
75 glDeleteBuffers(1, &pbo_);
\r
77 glDeleteTextures(1, &texture_);
\r
83 CASPAR_GL_CHECK(glGenBuffers(1, &pbo_));
\r
91 CASPAR_GL_CHECK(glGenTextures(1, &texture_));
\r
93 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
95 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
\r
96 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
\r
97 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
\r
98 CASPAR_GL_CHECK(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
\r
100 CASPAR_GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_, height_, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
103 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));
\r
104 if(data_ != nullptr)
\r
106 CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
\r
109 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
110 CASPAR_GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
111 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
\r
114 bool write_unlock()
\r
116 if(data_ != nullptr)
\r
118 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo()));
\r
119 CASPAR_GL_CHECK(glBufferData(GL_PIXEL_UNPACK_BUFFER, size_, NULL, GL_STREAM_DRAW));
\r
120 void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
\r
121 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
\r
122 data_ = reinterpret_cast<unsigned char*>(ptr);
\r
124 BOOST_THROW_EXCEPTION(std::bad_alloc());
\r
128 void read_lock(GLenum mode)
\r
130 CASPAR_GL_CHECK(glReadBuffer(mode));
\r
131 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));
\r
132 if(data_ != nullptr)
\r
134 CASPAR_GL_CHECK(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
\r
137 CASPAR_GL_CHECK(glBufferData(GL_PIXEL_PACK_BUFFER, size_, NULL, GL_STREAM_READ));
\r
138 CASPAR_GL_CHECK(glReadPixels(0, 0, width_, height_, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
\r
139 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
\r
145 if(data_ != nullptr || !reading_)
\r
147 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo()));
\r
148 void* ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
\r
149 CASPAR_GL_CHECK(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
\r
150 data_ = reinterpret_cast<unsigned char*>(ptr);
\r
152 BOOST_THROW_EXCEPTION(std::bad_alloc());
\r
160 glTranslatef(x_*2.0f, y_*2.0f, 0.0f);
\r
161 glColor4f(1.0f, 1.0f, 1.0f, alpha_);
\r
163 if(mode_ == video_mode::progressive)
\r
164 glPolygonStipple(progressive_pattern);
\r
165 else if(mode_ == video_mode::upper)
\r
166 glPolygonStipple(upper_pattern);
\r
167 else if(mode_ == video_mode::lower)
\r
168 glPolygonStipple(lower_pattern);
\r
170 CASPAR_GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_));
\r
172 glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
\r
173 glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
\r
174 glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
\r
175 glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
\r
180 unsigned char* data()
\r
182 if(data_ == nullptr)
\r
183 BOOST_THROW_EXCEPTION(invalid_operation());
\r
189 audio_data_.clear();
\r
193 mode_ = video_mode::progressive;
\r
199 unsigned char* data_;
\r
204 std::vector<short> audio_data_;
\r
212 gpu_frame::gpu_frame(size_t width, size_t height) : impl_(new implementation(width, height)){}
\r
213 void gpu_frame::write_lock(){impl_->write_lock();}
\r
214 bool gpu_frame::write_unlock(){return impl_->write_unlock();}
\r
215 void gpu_frame::read_lock(GLenum mode){impl_->read_lock(mode);}
\r
216 bool gpu_frame::read_unlock(){return impl_->read_unlock();}
\r
217 void gpu_frame::draw(){impl_->draw();}
\r
218 unsigned char* gpu_frame::data(){return impl_->data();}
\r
219 size_t gpu_frame::size() const { return impl_->size_; }
\r
220 size_t gpu_frame::width() const { return impl_->width_;}
\r
221 size_t gpu_frame::height() const { return impl_->height_;}
\r
222 const std::vector<short>& gpu_frame::audio_data() const { return impl_->audio_data_; }
\r
223 std::vector<short>& gpu_frame::audio_data() { return impl_->audio_data_; }
\r
224 void gpu_frame::reset(){impl_->reset();}
\r
225 float gpu_frame::alpha() const{ return impl_->alpha_;}
\r
226 void gpu_frame::alpha(float value){ impl_->alpha_ = value;}
\r
227 float gpu_frame::x() const { return impl_->x_;}
\r
228 float gpu_frame::y() const { return impl_->y_;}
\r
229 void gpu_frame::translate(float x, float y) { impl_->x_ += x; impl_->y_ += y; }
\r
230 void gpu_frame::mode(video_mode mode){ impl_->mode_ = mode;}
\r
231 video_mode gpu_frame::mode() const{ return impl_->mode_;}
\r