]> git.sesse.net Git - casparcg/blob - mixer/gpu/device_buffer.cpp
2.0.0.2: Added performance graphs.
[casparcg] / mixer / gpu / device_buffer.cpp
1 #include "../stdafx.h"\r
2 \r
3 #include "device_buffer.h"\r
4 \r
5 #include <common/gl/gl_check.h>\r
6 namespace caspar { namespace core {\r
7         \r
8 GLenum FORMAT[] = {0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
9 GLenum INTERNAL_FORMAT[] = {0, GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8}; \r
10 \r
11 struct device_buffer::implementation : boost::noncopyable\r
12 {\r
13         GLuint id_;\r
14 \r
15         const size_t width_;\r
16         const size_t height_;\r
17         const size_t stride_;\r
18 \r
19 public:\r
20         implementation(size_t width, size_t height, size_t stride) \r
21                 : width_(width)\r
22                 , height_(height)\r
23                 , stride_(stride)\r
24         {       \r
25                 GL(glGenTextures(1, &id_));\r
26                 GL(glBindTexture(GL_TEXTURE_2D, id_));\r
27                 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));\r
28                 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));\r
29                 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));\r
30                 GL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));\r
31                 GL(glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT[stride_], width_, height_, 0, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
32                 GL(glBindTexture(GL_TEXTURE_2D, 0));\r
33                 //CASPAR_LOG(trace) << "[device_buffer] allocated size:" << width*height*stride;        \r
34         }       \r
35 \r
36         ~implementation()\r
37         {\r
38                 GL(glDeleteTextures(1, &id_));\r
39         }\r
40         \r
41         void bind()\r
42         {\r
43                 GL(glBindTexture(GL_TEXTURE_2D, id_));\r
44         }\r
45 \r
46         void unbind()\r
47         {\r
48                 GL(glBindTexture(GL_TEXTURE_2D, 0));\r
49         }\r
50 \r
51         void read(host_buffer& source)\r
52         {\r
53                 GL(glBindTexture(GL_TEXTURE_2D, id_));\r
54                 source.unmap();\r
55                 source.bind();\r
56                 GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
57                 source.unbind();\r
58                 GL(glBindTexture(GL_TEXTURE_2D, 0));\r
59         }\r
60         \r
61         void write(host_buffer& target)\r
62         {\r
63                 GL(glBindTexture(GL_TEXTURE_2D, id_));\r
64                 target.unmap();\r
65                 target.bind();\r
66                 GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
67                 target.unbind();\r
68                 GL(glBindTexture(GL_TEXTURE_2D, 0));\r
69         }\r
70 \r
71         void attach(int index)\r
72         {\r
73                 GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, GL_TEXTURE_2D, id_, 0));\r
74         }\r
75 };\r
76 \r
77 device_buffer::device_buffer(size_t width, size_t height, size_t stride) : impl_(new implementation(width, height, stride)){}\r
78 size_t device_buffer::stride() const { return impl_->stride_; }\r
79 size_t device_buffer::width() const { return impl_->width_; }\r
80 size_t device_buffer::height() const { return impl_->height_; }\r
81 void device_buffer::attach(int index){impl_->attach(index);}\r
82 void device_buffer::bind(){impl_->bind();}\r
83 void device_buffer::unbind(){impl_->unbind();}\r
84 void device_buffer::read(host_buffer& source){impl_->read(source);}\r
85 void device_buffer::write(host_buffer& target){impl_->write(target);}\r
86 \r
87 }}