]> git.sesse.net Git - casparcg/commitdiff
2.0. Refactoring.
authorRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 7 Aug 2011 11:39:36 +0000 (11:39 +0000)
committerRonag <Ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 7 Aug 2011 11:39:36 +0000 (11:39 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.0.2@1073 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

core/mixer/gpu/device_buffer.cpp
core/mixer/gpu/device_buffer.h
core/mixer/gpu/fence.cpp
core/mixer/gpu/host_buffer.cpp
core/mixer/gpu/host_buffer.h
core/mixer/image/image_mixer.cpp
core/mixer/read_frame.cpp

index 66a417011ab8681b6cb0627f8340b7bc6f9aa95c..beceba82808ed3c5d090ea4aa8a3504e374229f4 100644 (file)
 \r
 namespace caspar { namespace core {\r
        \r
-GLenum FORMAT[] = {0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
-GLenum INTERNAL_FORMAT[] = {0, GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8};        \r
+static GLenum FORMAT[] = {0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA};\r
+static GLenum INTERNAL_FORMAT[] = {0, GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8}; \r
+\r
+GLenum format(size_t stride)\r
+{\r
+       return FORMAT[stride];\r
+}\r
 \r
 struct device_buffer::implementation : boost::noncopyable\r
 {\r
@@ -39,6 +44,8 @@ struct device_buffer::implementation : boost::noncopyable
        const size_t height_;\r
        const size_t stride_;\r
 \r
+       fence            fence_;\r
+\r
 public:\r
        implementation(size_t width, size_t height, size_t stride) \r
                : width_(width)\r
@@ -93,20 +100,10 @@ public:
                GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
                source.unbind();\r
                GL(glBindTexture(GL_TEXTURE_2D, 0));\r
+               fence_.set();\r
+               GL(glFlush());\r
        }\r
        \r
-       void write(host_buffer& target)\r
-       {\r
-               attach(0);\r
-               GL(glBindTexture(GL_TEXTURE_2D, id_));\r
-               target.unmap();\r
-               target.bind();\r
-               GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], GL_UNSIGNED_BYTE, NULL));\r
-               target.unbind();\r
-               GL(glBindTexture(GL_TEXTURE_2D, 0));\r
-               target.fence();\r
-       }\r
-\r
        void attach(int index)\r
        {\r
                GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index, GL_TEXTURE_2D, id_, 0));\r
@@ -117,6 +114,11 @@ public:
                attach(0);\r
                GL(glClear(GL_COLOR_BUFFER_BIT));\r
        }\r
+\r
+       bool ready() const\r
+       {\r
+               return fence_.ready();\r
+       }\r
 };\r
 \r
 device_buffer::device_buffer(size_t width, size_t height, size_t stride) : impl_(new implementation(width, height, stride)){}\r
@@ -128,7 +130,8 @@ void device_buffer::bind(){impl_->bind();}
 void device_buffer::bind(int index){impl_->bind(index);}\r
 void device_buffer::unbind(){impl_->unbind();}\r
 void device_buffer::read(host_buffer& source){impl_->read(source);}\r
-void device_buffer::write(host_buffer& target){impl_->write(target);}\r
 void device_buffer::clear(){impl_->clear();}\r
+bool device_buffer::ready() const{return impl_->ready();}\r
+\r
 \r
 }}
\ No newline at end of file
index da71c6deb735cf66a3bb8baaf9c69458c834c09a..e7052dd56329dd18e528919ebda75fcfdea6a4ba 100644 (file)
 \r
 #include <memory>\r
 \r
-namespace caspar { namespace core {\r
+#include "GL/glew.h"\r
 \r
+namespace caspar { namespace core {\r
+               \r
 class host_buffer;\r
 \r
 class device_buffer : boost::noncopyable\r
@@ -44,9 +46,9 @@ public:
        void clear();\r
 \r
        void attach(int index = 0);\r
+\r
        void read(host_buffer& source);\r
-       void write(host_buffer& target);\r
-       \r
+       bool ready() const;\r
 private:\r
        friend class ogl_device;\r
        device_buffer(size_t width, size_t height, size_t stride);\r
@@ -54,5 +56,7 @@ private:
        struct implementation;\r
        safe_ptr<implementation> impl_;\r
 };\r
+       \r
+GLenum format(size_t stride);\r
 \r
 }}
\ No newline at end of file
index 3c29d4fa46cc8ba2e59cd55e28d764126fde5e6c..f36d4a95d44f1223951b86f116102232677cb9dc 100644 (file)
@@ -23,12 +23,15 @@ struct fence::implementation
 \r
        bool ready() const\r
        {\r
+               if(!sync_)\r
+                       return true;\r
+\r
                GLsizei length = 0;\r
                int values[] = {0};\r
 \r
                GL(glGetSynciv(sync_, GL_SYNC_STATUS, 1, &length, values));\r
 \r
-               return sync_ ? values[0] == GL_SIGNALED : true;\r
+               return values[0] == GL_SIGNALED;\r
        }\r
 \r
        void wait(ogl_device& ogl)\r
@@ -44,7 +47,7 @@ struct fence::implementation
                }\r
 \r
                if(delay > 0)\r
-                       CASPAR_LOG(warning) << L"[ogl_device] Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
+                       CASPAR_LOG(warning) << L"[fence] Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
        }\r
 };\r
        \r
@@ -53,7 +56,7 @@ fence::fence()
        if(GLEW_ARB_sync)\r
                impl_.reset(new implementation());\r
        else\r
-               CASPAR_LOG(warning) << "GL_SYNC not supported, running without fences. This might cause performance degradation when running multiple channels.";\r
+               CASPAR_LOG(warning) << "[fence] GL_SYNC not supported, running without fences. This might cause performance degradation when running multiple channels and short buffer depth.";\r
 \r
 }\r
 \r
index 125956ef554266ca6d562dbe62fb97ba7945a683..d06d64a7c6c0a07c2c2ecd58e742bf5bade6eb1d 100644 (file)
@@ -22,6 +22,7 @@
 #include "host_buffer.h"\r
 \r
 #include "fence.h"\r
+#include "device_buffer.h"\r
 #include "ogl_device.h"\r
 \r
 #include <common/gl/gl_check.h>\r
@@ -35,7 +36,7 @@ struct host_buffer::implementation : boost::noncopyable
        void*                   data_;\r
        GLenum                  usage_;\r
        GLenum                  target_;\r
-       core::fence             fence_;\r
+       fence                   fence_;\r
 \r
 public:\r
        implementation(size_t size, usage_t usage) \r
@@ -84,10 +85,9 @@ public:
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Failed to map target_ OpenGL Pixel Buffer Object."));\r
        }\r
 \r
-       void map2(ogl_device& ogl)\r
+       void wait(ogl_device& ogl)\r
        {\r
                fence_.wait(ogl);\r
-               ogl.invoke(std::bind(&implementation::map, this), high_priority);\r
        }\r
 \r
        void unmap()\r
@@ -111,22 +111,35 @@ public:
                GL(glBindBuffer(target_, 0));\r
        }\r
 \r
-       void fence()\r
+       void read(device_buffer& source)\r
        {\r
+               source.attach(0);\r
+               source.bind();\r
+               unmap();\r
+               bind();\r
+               GL(glReadPixels(0, 0, source.width(), source.height(), format(source.stride()), GL_UNSIGNED_BYTE, NULL));\r
+               unbind();\r
+               source.unbind();\r
                fence_.set();\r
                GL(glFlush());\r
        }\r
+\r
+       bool ready() const\r
+       {\r
+               return fence_.ready();\r
+       }\r
 };\r
 \r
 host_buffer::host_buffer(size_t size, usage_t usage) : impl_(new implementation(size, usage)){}\r
 const void* host_buffer::data() const {return impl_->data_;}\r
 void* host_buffer::data() {return impl_->data_;}\r
 void host_buffer::map(){impl_->map();}\r
-void host_buffer::map(ogl_device& ogl){impl_->map2(ogl);}\r
 void host_buffer::unmap(){impl_->unmap();}\r
 void host_buffer::bind(){impl_->bind();}\r
 void host_buffer::unbind(){impl_->unbind();}\r
-void host_buffer::fence(){impl_->fence();}\r
+void host_buffer::read(device_buffer& source){impl_->read(source);}\r
 size_t host_buffer::size() const { return impl_->size_; }\r
+bool host_buffer::ready() const{return impl_->ready();}\r
+void host_buffer::wait(ogl_device& ogl){impl_->wait(ogl);}\r
 \r
 }}
\ No newline at end of file
index 3d9e48c8ded61730191acd6a572f6215703e35e1..af97c9fa1d11f28cf4c97af61de132445803cf60 100644 (file)
@@ -26,6 +26,7 @@
 namespace caspar { namespace core {\r
 \r
 class ogl_device;\r
+class device_buffer;\r
                \r
 class host_buffer : boost::noncopyable\r
 {\r
@@ -44,10 +45,11 @@ public:
        void unbind();\r
 \r
        void map();\r
-       void map(ogl_device& ogl);\r
        void unmap();\r
-\r
-       void fence();\r
+       \r
+       void read(device_buffer& source);\r
+       bool ready() const;\r
+       void wait(ogl_device& ogl);\r
 private:\r
        friend class ogl_device;\r
        host_buffer(size_t size, usage_t usage);\r
index edf7d9bf16cf1250535a8c3db14cd3b504dc5114..0522be120368468b4010d2611694516e4c52f20d 100644 (file)
@@ -187,14 +187,23 @@ public:
 \r
                std::swap(draw_buffer_[0], write_buffer_);\r
 \r
-               // device -> host.                              \r
-               write_buffer_->write(*read_buffer);\r
+               // device -> host.                      \r
+               read_buffer->read(*write_buffer_);\r
 \r
                return read_buffer;\r
        }\r
        \r
        void render_item(std::array<std::shared_ptr<device_buffer>,2>& targets, render_item&& item, const std::shared_ptr<device_buffer>& local_key, const std::shared_ptr<device_buffer>& layer_key)\r
        {\r
+               BOOST_FOREACH(auto& texture, item.textures)\r
+               {\r
+                       if(!texture->ready())\r
+                       {\r
+                               CASPAR_LOG(warning) << L"[image_mixer] Performance warning. Host to device transfer not complete, GPU will be stalled";\r
+                               channel_.ogl().yield(); // Try to give it some more time.\r
+                       }\r
+               }\r
+\r
                targets[1]->attach();\r
                        \r
                kernel_.draw(item, make_safe(targets[0]), local_key, layer_key);\r
index be4aaf169b722d7058ac37dd0b5e2c6d73e4bf89..81f708efa70ace883c679091860f7ebb3701be7b 100644 (file)
@@ -42,7 +42,10 @@ public:
        const boost::iterator_range<const uint8_t*> image_data()\r
        {\r
                if(!image_data_->data())\r
-                       image_data_->map(ogl_);\r
+               {\r
+                       image_data_->wait(ogl_);\r
+                       ogl_.invoke([=]{image_data_->map();}, high_priority);\r
+               }\r
 \r
                auto ptr = static_cast<const uint8_t*>(image_data_->data());\r
                return boost::iterator_range<const uint8_t*>(ptr, ptr + image_data_->size());\r
@@ -66,7 +69,7 @@ const boost::iterator_range<const int16_t*> read_frame::audio_data()
        return impl_ ? impl_->audio_data() : boost::iterator_range<const int16_t*>();\r
 }\r
 \r
-size_t read_frame::image_size() const{return impl_->image_data_->size();}\r
+size_t read_frame::image_size() const{return impl_ ? impl_->image_data_->size() : 0;}\r
 \r
 //#include <tbb/scalable_allocator.h>\r
 //#include <tbb/parallel_for.h>\r