]> git.sesse.net Git - casparcg/commitdiff
2.1.0: ogl: Added secondary host allocation OpenGL thread to reduce blocking time...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 7 Feb 2012 21:25:45 +0000 (21:25 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 7 Feb 2012 21:25:45 +0000 (21:25 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2294 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

accelerator/ogl/context.cpp
accelerator/ogl/device_buffer.cpp
accelerator/ogl/host_buffer.cpp
modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/video/video_decoder.cpp
modules/ffmpeg/producer/video/video_decoder.h

index 805e9949ecdbe35003d7af70cd80b0f3ace755f7..48d8b31b34d18c4bd05e137bb4f86e86401c1610 100644 (file)
@@ -35,6 +35,8 @@
 \r
 #include <gl/glew.h>\r
 \r
+#include <windows.h>\r
+\r
 #include <SFML/Window/Context.hpp>\r
 \r
 #include <array>\r
 #include <tbb/concurrent_queue.h>\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
-       \r
+               \r
 struct context::impl : public std::enable_shared_from_this<impl>\r
 {\r
        std::unique_ptr<sf::Context> context_;\r
+       std::unique_ptr<sf::Context> secondary_context_;\r
        \r
        std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<device_buffer>>>, 4>        device_pools_;\r
        std::array<tbb::concurrent_unordered_map<int, tbb::concurrent_bounded_queue<std::shared_ptr<host_buffer>>>, 2>          host_pools_;\r
@@ -55,34 +58,60 @@ struct context::impl : public std::enable_shared_from_this<impl>
        GLuint fbo_;\r
 \r
        executor& executor_;\r
+       executor  secondary_executor_;\r
                                \r
        impl(executor& executor) \r
                : executor_(executor)\r
+               , secondary_executor_(L"OpenGL allocation context")\r
        {\r
                CASPAR_LOG(info) << L"Initializing OpenGL Device.";\r
                \r
-               executor_.invoke([=]\r
+               auto ctx1 = executor_.invoke([=]() -> HGLRC \r
                {\r
                        context_.reset(new sf::Context());\r
-                       context_->SetActive(true);\r
-               \r
+                       context_->SetActive(true);              \r
+                                               \r
                        if (glewInit() != GLEW_OK)\r
                                BOOST_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Failed to initialize GLEW."));\r
-                                               \r
-                       CASPAR_LOG(info) << L"OpenGL " << version();\r
-\r
+               \r
                        if(!GLEW_VERSION_3_0)\r
                                BOOST_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Your graphics card does not meet the minimum hardware requirements since it does not support OpenGL 3.0 or higher. CasparCG Server will not be able to continue."));\r
        \r
                        glGenFramebuffers(1, &fbo_);                            \r
                        glBindFramebuffer(GL_FRAMEBUFFER, fbo_);\r
+                       \r
+                       auto ctx1 = wglGetCurrentContext();\r
+                       \r
+                       context_->SetActive(false);\r
+\r
+                       return ctx1;\r
+               });\r
 \r
-                       CASPAR_LOG(info) << L"Successfully initialized OpenGL Device.";\r
+               secondary_executor_.invoke([=]\r
+               {\r
+                       secondary_context_.reset(new sf::Context());\r
+                       secondary_context_->SetActive(true);    \r
+                       auto ctx2 = wglGetCurrentContext();\r
+\r
+                       if(!wglShareLists(ctx1, ctx2))\r
+                                       BOOST_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Failed to share OpenGL contexts."));\r
                });\r
+\r
+               executor_.invoke([=]\r
+               {               \r
+                       context_->SetActive(true);\r
+               });\r
+               \r
+               CASPAR_LOG(info) << L"Successfully initialized OpenGL " << version();\r
        }\r
 \r
        ~impl()\r
        {\r
+               secondary_executor_.invoke([=]\r
+               {\r
+                       secondary_context_.reset();\r
+               });\r
+\r
                executor_.invoke([=]\r
                {\r
                        BOOST_FOREACH(auto& pool, device_pools_)\r
@@ -90,22 +119,27 @@ struct context::impl : public std::enable_shared_from_this<impl>
                        BOOST_FOREACH(auto& pool, host_pools_)\r
                                pool.clear();\r
                        glDeleteFramebuffers(1, &fbo_);\r
+\r
+                       context_.reset();\r
                });\r
        }\r
 \r
        spl::shared_ptr<device_buffer> allocate_device_buffer(int width, int height, int stride)\r
        {\r
-               std::shared_ptr<device_buffer> buffer;\r
-               try\r
+               return executor_.invoke([&]() -> spl::shared_ptr<device_buffer>\r
                {\r
-                       buffer.reset(new device_buffer(width, height, stride));\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG(error) << L"ogl: create_device_buffer failed!";\r
-                       throw;\r
-               }\r
-               return spl::make_shared_ptr(buffer);\r
+                       std::shared_ptr<device_buffer> buffer;\r
+                       try\r
+                       {\r
+                               buffer.reset(new device_buffer(width, height, stride));\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG(error) << L"ogl: create_device_buffer failed!";\r
+                               throw;\r
+                       }\r
+                       return spl::make_shared_ptr(buffer);\r
+               });\r
        }\r
                                \r
        spl::shared_ptr<device_buffer> create_device_buffer(int width, int height, int stride)\r
@@ -117,7 +151,7 @@ struct context::impl : public std::enable_shared_from_this<impl>
                \r
                std::shared_ptr<device_buffer> buffer;\r
                if(!pool->try_pop(buffer))              \r
-                       buffer = executor_.invoke([&]{return allocate_device_buffer(width, height, stride);}, task_priority::high_priority);                    \r
+                       buffer = allocate_device_buffer(width, height, stride);         \r
        \r
                auto self = shared_from_this();\r
                return spl::shared_ptr<device_buffer>(buffer.get(), [self, buffer, pool](device_buffer*) mutable\r
@@ -128,23 +162,26 @@ struct context::impl : public std::enable_shared_from_this<impl>
 \r
        spl::shared_ptr<host_buffer> allocate_host_buffer(int size, host_buffer::usage usage)\r
        {\r
-               std::shared_ptr<host_buffer> buffer;\r
-\r
-               try\r
-               {\r
-                       buffer.reset(new host_buffer(size, usage));\r
-                       if(usage == host_buffer::usage::write_only)\r
-                               buffer->map();\r
-                       else\r
-                               buffer->unmap();                        \r
-               }\r
-               catch(...)\r
+               return secondary_executor_.invoke([=]() -> spl::shared_ptr<host_buffer>\r
                {\r
-                       CASPAR_LOG(error) << L"ogl: create_host_buffer failed!";\r
-                       throw;  \r
-               }\r
+                       std::shared_ptr<host_buffer> buffer;\r
 \r
-               return spl::make_shared_ptr(buffer);\r
+                       try\r
+                       {\r
+                               buffer.reset(new host_buffer(size, usage));\r
+                               if(usage == host_buffer::usage::write_only)\r
+                                       buffer->map();\r
+                               else\r
+                                       buffer->unmap();                        \r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               CASPAR_LOG(error) << L"ogl: create_host_buffer failed!";\r
+                               throw;  \r
+                       }\r
+\r
+                       return spl::make_shared_ptr(buffer);\r
+               });\r
        }\r
        \r
        spl::shared_ptr<host_buffer> create_host_buffer(int size, host_buffer::usage usage)\r
@@ -156,13 +193,14 @@ struct context::impl : public std::enable_shared_from_this<impl>
                \r
                std::shared_ptr<host_buffer> buffer;\r
                if(!pool->try_pop(buffer))      \r
-                       buffer = executor_.invoke([=]{return allocate_host_buffer(size, usage);}, task_priority::high_priority);        \r
+                       buffer = allocate_host_buffer(size, usage);     \r
        \r
-               auto self               = shared_from_this();\r
-               bool is_write   = (usage == host_buffer::usage::write_only);\r
+               bool is_write = (usage == host_buffer::usage::write_only);\r
+\r
+               auto self = shared_from_this();\r
                return spl::shared_ptr<host_buffer>(buffer.get(), [self, is_write, buffer, pool](host_buffer*) mutable\r
                {\r
-                       self->executor_.begin_invoke([=]() mutable\r
+                       self->secondary_executor_.begin_invoke([=]() mutable\r
                        {               \r
                                if(is_write)\r
                                        buffer->map();\r
index 8f81ce12fe20015ec59c3f0eb2ace609bf14cddc..b17758d6ef87c81d7fbf292f4124d2fb6afe4ecc 100644 (file)
@@ -72,15 +72,7 @@ public:
 \r
        ~impl()\r
        {\r
-               try\r
-               {\r
-                       GL(glDeleteTextures(1, &id_));\r
-                       //CASPAR_LOG(trace) << "[device_buffer] [" << --g_total_count << L"] deallocated size:" << width_*height_*stride_;\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-               }\r
+               glDeleteTextures(1, &id_);\r
        }\r
        \r
        void bind()\r
index a34b4a1ccdf6c46aff6fe1e28576678dc010858b..245b34aee5203ee905c95677d2ec3822c88e6df4 100644 (file)
@@ -68,15 +68,7 @@ public:
 \r
        ~impl()\r
        {\r
-               try\r
-               {\r
-                       GL(glDeleteBuffers(1, &pbo_));\r
-                       //CASPAR_LOG(trace) << "[host_buffer] [" << --(usage_ == write_only ? g_w_total_count : g_r_total_count) << L"] deallocated size:" << size_ << " usage: " << (usage_ == write_only ? "write_only" : "read_only");\r
-               }\r
-               catch(...)\r
-               {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
-               }\r
+               glDeleteBuffers(1, &pbo_);\r
        }\r
 \r
        void* map()\r
index 37a355c31127caf1148c4fd92cf76dee2075de83..7cfec870b5906ee9dd3711be72da5886df4cc9db 100644 (file)
@@ -103,7 +103,7 @@ public:
                \r
                try\r
                {\r
-                       video_decoder_.reset(new video_decoder(input_.context(), frame_factory_));\r
+                       video_decoder_.reset(new video_decoder(input_.context()));\r
                        CASPAR_LOG(info) << print() << L" " << video_decoder_->print();\r
                }\r
                catch(averror_stream_not_found&)\r
index 564a196d2f4f42df9748f473a1fcbb0109e496b6..18797eb413f96010f43dbf468fa1967de32703e3 100644 (file)
@@ -67,18 +67,13 @@ struct video_decoder::impl : boost::noncopyable
        tbb::atomic<uint32_t>                                   file_frame_number_;\r
 \r
 public:\r
-       explicit impl(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory\r
+       explicit impl(const spl::shared_ptr<AVFormatContext>& context) \r
                : codec_context_(open_codec(*context, AVMEDIA_TYPE_VIDEO, index_))\r
                , nb_frames_(static_cast<uint32_t>(context->streams[index_]->nb_frames))\r
                , width_(codec_context_->width)\r
                , height_(codec_context_->height)\r
        {\r
                file_frame_number_ = 0;\r
-\r
-               // Reserve some frames\r
-               std::vector<spl::shared_ptr<core::write_frame>> frames;\r
-               for(int n = 0; n < 3; ++n)\r
-                       frames.push_back(frame_factory->create_frame(this, get_pixel_format_desc(codec_context_->pix_fmt, codec_context_->width, codec_context_->height)));\r
        }\r
 \r
        void push(const std::shared_ptr<AVPacket>& packet)\r
@@ -156,7 +151,7 @@ public:
        }\r
 };\r
 \r
-video_decoder::video_decoder(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory) : impl_(new impl(context, frame_factory)){}\r
+video_decoder::video_decoder(const spl::shared_ptr<AVFormatContext>& context) : impl_(new impl(context)){}\r
 void video_decoder::push(const std::shared_ptr<AVPacket>& packet){impl_->push(packet);}\r
 std::shared_ptr<AVFrame> video_decoder::poll(){return impl_->poll();}\r
 bool video_decoder::ready() const{return impl_->ready();}\r
index aee918e22f9fc1c365454c56042a695a84c424b6..a71f3e457e2506cd84020a7283790e7268468f01 100644 (file)
@@ -38,7 +38,7 @@ namespace caspar { namespace ffmpeg {
 class video_decoder : boost::noncopyable\r
 {\r
 public:\r
-       explicit video_decoder(const spl::shared_ptr<AVFormatContext>& context, const spl::shared_ptr<core::frame_factory>& frame_factory);\r
+       explicit video_decoder(const spl::shared_ptr<AVFormatContext>& context);\r
        \r
        bool ready() const;\r
        void push(const std::shared_ptr<AVPacket>& packet);\r