]> git.sesse.net Git - casparcg/commitdiff
2.1.0: -ogl: Refactoring.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 7 Feb 2012 20:37:08 +0000 (20:37 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Tue, 7 Feb 2012 20:37:08 +0000 (20:37 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2293 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

12 files changed:
accelerator/image/image_kernel.cpp
accelerator/image/image_mixer.cpp
accelerator/ogl/context.cpp
accelerator/ogl/context.h
accelerator/ogl/device_buffer.cpp
accelerator/ogl/device_buffer.h
accelerator/ogl/host_buffer.cpp
accelerator/ogl/host_buffer.h
accelerator/ogl/shader.cpp
accelerator/ogl/shader.h
shell/casparcg.config
shell/server.cpp

index eb2ce3dbb8161b94909aaa49f8109d153d2c8931..c2589fba3bceed616f5d3a923590617cd3ccd344 100644 (file)
@@ -70,8 +70,8 @@ struct image_kernel::impl : boost::noncopyable
        {\r
                static const double epsilon = 0.001;\r
                \r
-               ogl_->yield();\r
-\r
+               ogl_->yield();          \r
+               \r
                CASPAR_ASSERT(params.pix_desc.planes.size() == params.textures.size());\r
 \r
                if(params.textures.empty() || !params.background)\r
@@ -93,7 +93,7 @@ struct image_kernel::impl : boost::noncopyable
                        \r
                // Setup shader\r
                                                                \r
-               ogl_->use(*shader_);\r
+               shader_->use();\r
 \r
                shader_->set("plane[0]",                texture_id::plane0);\r
                shader_->set("plane[1]",                texture_id::plane1);\r
@@ -209,7 +209,7 @@ struct image_kernel::impl : boost::noncopyable
                        glTextureBarrierNV(); \r
                }\r
 \r
-               ogl_->attach(*params.background);\r
+               params.background->attach();\r
                \r
                // Draw\r
                                \r
index 7e9d2a88d3159110e023ac9a2dd755c6a52ab795..5605a59fdc402544f55870054689e7e418910e43 100644 (file)
@@ -188,7 +188,7 @@ private:
                                        item.buffers.clear();\r
                                }\r
                        }       \r
-\r
+                       \r
                        // Draw\r
                        boost::shared_future<spl::shared_ptr<host_buffer>> buffer = ogl_->begin_invoke([=]() mutable -> spl::shared_ptr<host_buffer>\r
                        {\r
@@ -220,14 +220,18 @@ private:
                                }\r
                        \r
                                auto result = ogl_->create_host_buffer(static_cast<int>(format_desc.size), host_buffer::usage::read_only); \r
-                               draw_buffer->copy_to(result);                                                   \r
+                               draw_buffer->copy_to(*result);                                                  \r
                                return result;\r
                        });\r
                \r
                        // Defer memory mapping.\r
                        return async(launch_policy::deferred, [=]() mutable -> boost::iterator_range<const uint8_t*>\r
                        {\r
-                               auto ptr = reinterpret_cast<const uint8_t*>(buffer.get()->data()); // .get() and ->data() can block calling thread, ->data() can also block OpenGL thread, defer it as long as possible.\r
+                               const auto& buf = buffer.get();\r
+                               if(!buf->data())\r
+                                       ogl_->invoke(std::bind(&host_buffer::map, std::ref(buf)), task_priority::high_priority);\r
+\r
+                               auto ptr = reinterpret_cast<const uint8_t*>(buf->data()); // .get() and ->data() can block calling thread, ->data() can also block OpenGL thread, defer it as long as possible.\r
                                return boost::iterator_range<const uint8_t*>(ptr, ptr + buffer.get()->size());\r
                        });\r
                }\r
@@ -349,7 +353,7 @@ private:
        spl::shared_ptr<device_buffer> create_mixer_buffer(int stride, const core::video_format_desc& format_desc)\r
        {\r
                auto buffer = ogl_->create_device_buffer(format_desc.width, format_desc.height, stride);\r
-               ogl_->clear(*buffer);\r
+               buffer->clear();\r
                return buffer;\r
        }\r
 };\r
index f0aeb21b3be4467777626bed705c1423dcd56d8b..805e9949ecdbe35003d7af70cd80b0f3ace755f7 100644 (file)
 \r
 #include "shader.h"\r
 \r
-#include <common/except.h>\r
 #include <common/assert.h>\r
+#include <common/except.h>\r
 #include <common/gl/gl_check.h>\r
 \r
 #include <boost/foreach.hpp>\r
 \r
 #include <gl/glew.h>\r
 \r
-namespace caspar { namespace accelerator { namespace ogl {\r
+#include <SFML/Window/Context.hpp>\r
 \r
-context::context() \r
-       : executor_(L"context")\r
+#include <array>\r
+#include <unordered_map>\r
+\r
+#include <tbb/concurrent_unordered_map.h>\r
+#include <tbb/concurrent_queue.h>\r
+\r
+namespace caspar { namespace accelerator { namespace ogl {\r
+       \r
+struct context::impl : public std::enable_shared_from_this<impl>\r
 {\r
-       CASPAR_LOG(info) << L"Initializing OpenGL Device.";\r
-               \r
-       invoke([=]\r
+       std::unique_ptr<sf::Context> 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
+       \r
+       GLuint fbo_;\r
+\r
+       executor& executor_;\r
+                               \r
+       impl(executor& executor) \r
+               : executor_(executor)\r
        {\r
-               context_.reset(new sf::Context());\r
-               context_->SetActive(true);\r
+               CASPAR_LOG(info) << L"Initializing OpenGL Device.";\r
+               \r
+               executor_.invoke([=]\r
+               {\r
+                       context_.reset(new sf::Context());\r
+                       context_->SetActive(true);\r
                \r
-               if (glewInit() != GLEW_OK)\r
-                       BOOST_THROW_EXCEPTION(gl::ogl_exception() << msg_info("Failed to initialize GLEW."));\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
+                       CASPAR_LOG(info) << L"OpenGL " << version();\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
+                       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
-               \r
-               CASPAR_LOG(info) << L"Successfully initialized OpenGL Device.";\r
-       });\r
-}\r
+                       glGenFramebuffers(1, &fbo_);                            \r
+                       glBindFramebuffer(GL_FRAMEBUFFER, fbo_);\r
 \r
-context::~context()\r
-{\r
-       invoke([=]\r
-       {\r
-               BOOST_FOREACH(auto& pool, device_pools_)\r
-                       pool.clear();\r
-               BOOST_FOREACH(auto& pool, host_pools_)\r
-                       pool.clear();\r
-               glDeleteFramebuffers(1, &fbo_);\r
-       });\r
-}\r
+                       CASPAR_LOG(info) << L"Successfully initialized OpenGL Device.";\r
+               });\r
+       }\r
 \r
-spl::shared_ptr<device_buffer> context::allocate_device_buffer(int width, int height, int stride)\r
-{\r
-       std::shared_ptr<device_buffer> buffer;\r
-       try\r
+       ~impl()\r
        {\r
-               buffer.reset(new device_buffer(shared_from_this(), width, height, stride));\r
+               executor_.invoke([=]\r
+               {\r
+                       BOOST_FOREACH(auto& pool, device_pools_)\r
+                               pool.clear();\r
+                       BOOST_FOREACH(auto& pool, host_pools_)\r
+                               pool.clear();\r
+                       glDeleteFramebuffers(1, &fbo_);\r
+               });\r
        }\r
-       catch(...)\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
                {\r
-                       executor_.yield();\r
-                       gc().wait();\r
-                                       \r
-                       // Try again\r
-                       buffer.reset(new device_buffer(shared_from_this(), width, height, stride));\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
-       return spl::make_shared_ptr(buffer);\r
-}\r
                                \r
-spl::shared_ptr<device_buffer> context::create_device_buffer(int width, int height, int stride)\r
-{\r
-       CASPAR_VERIFY(stride > 0 && stride < 5);\r
-       CASPAR_VERIFY(width > 0 && height > 0);\r
-       auto& pool = device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
-       std::shared_ptr<device_buffer> buffer;\r
-       if(!pool->items.try_pop(buffer))                \r
-               buffer = executor_.invoke([&]{return allocate_device_buffer(width, height, stride);}, task_priority::high_priority);                    \r
-       \r
-       //++pool->usage_count;\r
-\r
-       return spl::shared_ptr<device_buffer>(buffer.get(), [=](device_buffer*) mutable\r
-       {               \r
-               pool->items.push(buffer);       \r
-       });\r
-}\r
-\r
-spl::shared_ptr<host_buffer> context::allocate_host_buffer(int size, host_buffer::usage usage)\r
-{\r
-       std::shared_ptr<host_buffer> buffer;\r
-\r
-       try\r
+       spl::shared_ptr<device_buffer> create_device_buffer(int width, int height, int stride)\r
        {\r
-               buffer.reset(new host_buffer(shared_from_this(), size, usage));\r
-               if(usage == host_buffer::usage::write_only)\r
-                       buffer->map();\r
-               else\r
-                       buffer->unmap();                        \r
+               CASPAR_VERIFY(stride > 0 && stride < 5);\r
+               CASPAR_VERIFY(width > 0 && height > 0);\r
+               \r
+               auto pool = &device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
+               \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
+       \r
+               auto self = shared_from_this();\r
+               return spl::shared_ptr<device_buffer>(buffer.get(), [self, buffer, pool](device_buffer*) mutable\r
+               {               \r
+                       pool->push(buffer);     \r
+               });\r
        }\r
-       catch(...)\r
+\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
-                       executor_.yield();\r
-                       gc().wait();\r
-\r
-                       // Try again\r
-                       buffer.reset(new host_buffer(shared_from_this(), size, usage));\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
+                               buffer->unmap();                        \r
                }\r
                catch(...)\r
                {\r
                        CASPAR_LOG(error) << L"ogl: create_host_buffer failed!";\r
-                       throw;          \r
+                       throw;  \r
                }\r
-       }\r
 \r
-       return spl::make_shared_ptr(buffer);\r
-}\r
-       \r
-spl::shared_ptr<host_buffer> context::create_host_buffer(int size, host_buffer::usage usage)\r
-{\r
-       CASPAR_VERIFY(usage == host_buffer::usage::write_only || usage == host_buffer::usage::read_only);\r
-       CASPAR_VERIFY(size > 0);\r
-       auto& pool = host_pools_[usage.value()][size];\r
-       std::shared_ptr<host_buffer> buffer;\r
-       if(!pool->items.try_pop(buffer))        \r
-               buffer = executor_.invoke([=]{return allocate_host_buffer(size, usage);}, task_priority::high_priority);        \r
+               return spl::make_shared_ptr(buffer);\r
+       }\r
        \r
-       auto self = shared_from_this();\r
-       bool is_write_only      = (usage == host_buffer::usage::write_only);\r
-       return spl::shared_ptr<host_buffer>(buffer.get(), [=](host_buffer*) mutable\r
+       spl::shared_ptr<host_buffer> create_host_buffer(int size, host_buffer::usage usage)\r
        {\r
-               self->executor_.begin_invoke([=]() mutable\r
-               {               \r
-                       if(is_write_only)\r
-                               buffer->map();\r
-                       else\r
-                               buffer->unmap();\r
-\r
-                       pool->items.push(buffer);\r
-               }, task_priority::high_priority);       \r
-       });\r
-}\r
-\r
-spl::shared_ptr<context> context::create()\r
-{\r
-       return spl::shared_ptr<context>(new context());\r
-}\r
-\r
-//template<typename T>\r
-//void flush_pool(buffer_pool<T>& pool)\r
-//{    \r
-//     if(pool.flush_count.fetch_and_increment() < 16)\r
-//             return;\r
-//\r
-//     if(pool.usage_count.fetch_and_store(0) < pool.items.size())\r
-//     {\r
-//             std::shared_ptr<T> buffer;\r
-//             pool.items.try_pop(buffer);\r
-//     }\r
-//\r
-//     pool.flush_count = 0;\r
-//     pool.usage_count = 0;\r
-//}\r
-\r
-boost::unique_future<void> context::gc()\r
-{      \r
-       return begin_invoke([=]\r
-       {\r
-               CASPAR_LOG(info) << " ogl: Running GC.";                \r
+               CASPAR_VERIFY(usage == host_buffer::usage::write_only || usage == host_buffer::usage::read_only);\r
+               CASPAR_VERIFY(size > 0);\r
+               \r
+               auto pool = &host_pools_[usage.value()][size];\r
+               \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
        \r
-               try\r
+               auto self               = shared_from_this();\r
+               bool is_write   = (usage == host_buffer::usage::write_only);\r
+               return spl::shared_ptr<host_buffer>(buffer.get(), [self, is_write, buffer, pool](host_buffer*) mutable\r
                {\r
-                       BOOST_FOREACH(auto& pools, device_pools_)\r
-                       {\r
-                               BOOST_FOREACH(auto& pool, pools)\r
-                                       pool.second->items.clear();\r
-                       }\r
-                       BOOST_FOREACH(auto& pools, host_pools_)\r
-                       {\r
-                               BOOST_FOREACH(auto& pool, pools)\r
-                                       pool.second->items.clear();\r
-                       }\r
-               }\r
-               catch(...)\r
+                       self->executor_.begin_invoke([=]() mutable\r
+                       {               \r
+                               if(is_write)\r
+                                       buffer->map();\r
+                               else\r
+                                       buffer->unmap();\r
+\r
+                               pool->push(buffer);\r
+                       }, task_priority::high_priority);       \r
+               });\r
+       }\r
+               \r
+       std::wstring version()\r
+       {       \r
+               static std::wstring ver = L"Not found";\r
+               try\r
                {\r
-                       CASPAR_LOG_CURRENT_EXCEPTION();\r
+                       ver = u16(executor_.invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VERSION)));})\r
+                       + " "   + executor_.invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));}));                    \r
                }\r
-       }, task_priority::high_priority);\r
-}\r
+               catch(...){}\r
 \r
-std::wstring context::version()\r
-{      \r
-       static std::wstring ver = L"Not found";\r
-       try\r
+               return ver;\r
+       }\r
+                       \r
+       boost::unique_future<spl::shared_ptr<device_buffer>> copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride)\r
        {\r
-               ver = u16(invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VERSION)));})\r
-               + " "   + invoke([]{return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));}));                      \r
+               return executor_.begin_invoke([=]() -> spl::shared_ptr<device_buffer>\r
+               {\r
+                       auto result = create_device_buffer(width, height, stride);\r
+                       result->copy_from(*source);\r
+                       return result;\r
+               }, task_priority::high_priority);\r
        }\r
-       catch(...){}\r
-\r
-       return ver;\r
-}\r
-\r
-void context::attach(device_buffer& texture)\r
-{      \r
-       glBindFramebuffer(GL_FRAMEBUFFER, fbo_);\r
-       GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, texture.id(), 0));\r
-}\r
-\r
-void context::clear(device_buffer& texture)\r
-{      \r
-       attach(texture);\r
-       GL(glClear(GL_COLOR_BUFFER_BIT));\r
-}\r
-\r
-void context::use(shader& shader)\r
-{      \r
-       GL(glUseProgramObjectARB(shader.id())); \r
-}\r
 \r
-boost::unique_future<spl::shared_ptr<device_buffer>> context::copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride)\r
-{\r
-       return executor_.begin_invoke([=]() -> spl::shared_ptr<device_buffer>\r
+       void yield()\r
        {\r
-               auto result = create_device_buffer(width, height, stride);\r
-               result->copy_from(source);\r
-               return result;\r
-       }, task_priority::high_priority);\r
-}\r
+               executor_.yield(task_priority::high_priority);\r
+       }\r
+};\r
 \r
-void context::yield()\r
+context::context() \r
+       : executor_(L"context")\r
+       , impl_(new impl(executor_))\r
 {\r
-       executor_.yield(task_priority::high_priority);\r
 }\r
+       \r
+void                                                                                                   context::yield(){impl_->yield();}       \r
+spl::shared_ptr<device_buffer>                                                 context::create_device_buffer(int width, int height, int stride){return impl_->create_device_buffer(width, height, stride);}\r
+spl::shared_ptr<host_buffer>                                                   context::create_host_buffer(int size, host_buffer::usage usage){return impl_->create_host_buffer(size, usage);}\r
+boost::unique_future<spl::shared_ptr<device_buffer>>   context::copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride){return impl_->copy_async(source, width, height, stride);}\r
+std::wstring                                                                                   context::version(){return impl_->version();}\r
+\r
 \r
 }}}\r
 \r
index cc0579cf876ed35dd89bc905ff7d5d642efe61ad..a0a5ba6f5a470f5404b816d945b5f501430b2d9d 100644 (file)
 #include "host_buffer.h"\r
 #include "device_buffer.h"\r
 \r
-#include <common/concurrency/executor.h>\r
 #include <common/spl/memory.h>\r
 \r
-#include <gl/glew.h>\r
-\r
-#include <SFML/Window/Context.hpp>\r
-\r
-#include <tbb/concurrent_unordered_map.h>\r
-#include <tbb/concurrent_queue.h>\r
-\r
 #include <boost/noncopyable.hpp>\r
 #include <boost/thread/future.hpp>\r
 \r
-#include <array>\r
-#include <unordered_map>\r
+#include <common/concurrency/executor.h>\r
 \r
 namespace caspar { namespace accelerator { namespace ogl {\r
-\r
-class shader;\r
-\r
-template<typename T>\r
-struct buffer_pool\r
-{\r
-       tbb::atomic<int> usage_count;\r
-       tbb::atomic<int> flush_count;\r
-       tbb::concurrent_bounded_queue<std::shared_ptr<T>> items;\r
-\r
-       buffer_pool()\r
-       {\r
-               usage_count = 0;\r
-               flush_count = 0;\r
-       }\r
-};\r
-\r
+       \r
 class context : public std::enable_shared_from_this<context>, boost::noncopyable\r
 {      \r
-       std::unique_ptr<sf::Context> context_;\r
-       \r
-       std::array<tbb::concurrent_unordered_map<int, spl::shared_ptr<buffer_pool<device_buffer>>>, 4> device_pools_;\r
-       std::array<tbb::concurrent_unordered_map<int, spl::shared_ptr<buffer_pool<host_buffer>>>, 2> host_pools_;\r
-       \r
-       GLuint fbo_;\r
-\r
        executor executor_;\r
-                               \r
-       context();\r
 public:                \r
-       static spl::shared_ptr<context> create();\r
-       ~context();\r
+       context();\r
        \r
-       void attach(device_buffer& texture);\r
-       void clear(device_buffer& texture);             \r
-       void use(shader& shader);\r
-
-       void yield();
+       void yield();\r
        \r
        spl::shared_ptr<device_buffer>                                                  create_device_buffer(int width, int height, int stride);\r
        spl::shared_ptr<host_buffer>                                                    create_host_buffer(int size, host_buffer::usage usage);\r
+\r
        boost::unique_future<spl::shared_ptr<device_buffer>>    copy_async(spl::shared_ptr<host_buffer>& source, int width, int height, int stride);\r
        \r
-       boost::unique_future<void> gc();\r
        std::wstring version();\r
 \r
        template<typename Func>\r
@@ -99,8 +60,8 @@ public:
                return executor_.invoke(std::forward<Func>(func), priority);\r
        }\r
 private:\r
-       spl::shared_ptr<device_buffer> allocate_device_buffer(int width, int height, int stride);\r
-       spl::shared_ptr<host_buffer>    allocate_host_buffer(int size, host_buffer::usage usage);\r
+       struct impl;\r
+       spl::shared_ptr<impl> impl_;\r
 };\r
 \r
 }}}
\ No newline at end of file
index 589b572e71d3d250a06a0e08739b58aea9259473..8f81ce12fe20015ec59c3f0eb2ace609bf14cddc 100644 (file)
@@ -48,16 +48,14 @@ static tbb::atomic<int> g_total_count;
 \r
 struct device_buffer::impl : boost::noncopyable\r
 {\r
-       std::weak_ptr<context>  parent_;\r
        GLuint                                          id_;\r
 \r
        const int width_;\r
        const int height_;\r
        const int stride_;\r
 public:\r
-       impl(std::weak_ptr<context> parent, int width, int height, int stride) \r
-               : parent_(parent)\r
-               , width_(width)\r
+       impl(int width, int height, int stride) \r
+               : width_(width)\r
                , height_(height)\r
                , stride_(stride)\r
        {       \r
@@ -100,52 +98,51 @@ public:
        {\r
                GL(glBindTexture(GL_TEXTURE_2D, 0));\r
        }\r
-               \r
-       void copy_from(const spl::shared_ptr<host_buffer>& source)\r
-       {\r
-               auto ogl = parent_.lock();\r
-               if(!ogl)\r
-                       BOOST_THROW_EXCEPTION(invalid_operation());\r
 \r
-               ogl->begin_invoke([=]\r
-               {\r
-                       source->unmap();\r
-                       source->bind();\r
-                       GL(glBindTexture(GL_TEXTURE_2D, id_));\r
-                       GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, FORMAT[stride_], TYPE[stride_], NULL));\r
-                       GL(glBindTexture(GL_TEXTURE_2D, 0));\r
-                       source->unbind();\r
-               }, task_priority::high_priority);\r
+       void attach()\r
+       {               \r
+               GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, id_, 0));\r
        }\r
 \r
-       void copy_to(const spl::shared_ptr<host_buffer>& dest)\r
+       void clear()\r
        {\r
-               auto ogl = parent_.lock();\r
-               if(!ogl)\r
-                       BOOST_THROW_EXCEPTION(invalid_operation());\r
+               attach();               \r
+               GL(glClear(GL_COLOR_BUFFER_BIT));\r
+       }\r
+               \r
+       void copy_from(host_buffer& source)\r
+       {\r
+               source.unmap();\r
+               source.bind();\r
+               GL(glBindTexture(GL_TEXTURE_2D, id_));\r
+               GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, FORMAT[stride_], TYPE[stride_], NULL));\r
+               GL(glBindTexture(GL_TEXTURE_2D, 0));\r
+               source.unbind();\r
+       }\r
 \r
-               ogl->begin_invoke([=]\r
-               {\r
-                       dest->unmap();\r
-                       dest->bind();\r
-                       GL(glBindTexture(GL_TEXTURE_2D, id_));\r
-                       GL(glReadBuffer(GL_COLOR_ATTACHMENT0));\r
-                       GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], TYPE[stride_], NULL));\r
-                       GL(glBindTexture(GL_TEXTURE_2D, 0));\r
-                       dest->unbind();\r
-                       GL(glFlush());\r
-               }, task_priority::high_priority);\r
+       void copy_to(host_buffer& dest)\r
+       {\r
+               dest.unmap();\r
+               dest.bind();\r
+               GL(glBindTexture(GL_TEXTURE_2D, id_));\r
+               GL(glReadBuffer(GL_COLOR_ATTACHMENT0));\r
+               GL(glReadPixels(0, 0, width_, height_, FORMAT[stride_], TYPE[stride_], NULL));\r
+               GL(glBindTexture(GL_TEXTURE_2D, 0));\r
+               dest.unbind();\r
+               GL(glFlush());\r
        }\r
 };\r
 \r
-device_buffer::device_buffer(std::weak_ptr<context> parent, int width, int height, int stride) : impl_(new impl(parent, width, height, stride)){}\r
+device_buffer::device_buffer(int width, int height, int stride) : impl_(new impl(width, height, stride)){}\r
 int device_buffer::stride() const { return impl_->stride_; }\r
 int device_buffer::width() const { return impl_->width_; }\r
 int device_buffer::height() const { return impl_->height_; }\r
 void device_buffer::bind(int index){impl_->bind(index);}\r
 void device_buffer::unbind(){impl_->unbind();}\r
-void device_buffer::copy_from(const spl::shared_ptr<host_buffer>& source){impl_->copy_from(source);}\r
-void device_buffer::copy_to(const spl::shared_ptr<host_buffer>& dest){impl_->copy_to(dest);}\r
+void device_buffer::attach(){impl_->attach();}\r
+void device_buffer::clear(){impl_->clear();}\r
+void device_buffer::copy_from(host_buffer& source){impl_->copy_from(source);}\r
+void device_buffer::copy_to(host_buffer& dest){impl_->copy_to(dest);}\r
 int device_buffer::id() const{ return impl_->id_;}\r
 \r
 }}}
\ No newline at end of file
index c390c84afa737c02e2f9d4e42e239cedb30987e8..cae7570bd10689e010ded562e28793eb92f5a815 100644 (file)
@@ -36,21 +36,21 @@ class context;
 class device_buffer : boost::noncopyable\r
 {\r
 public:        \r
+       device_buffer(int width, int height, int stride);\r
+\r
        int stride() const;     \r
        int width() const;\r
        int height() const;\r
                \r
-       void copy_from(const spl::shared_ptr<host_buffer>& source);\r
-       void copy_to(const spl::shared_ptr<host_buffer>& dest);\r
-private:\r
-       friend class context;\r
-       friend class image_kernel;\r
-       device_buffer(std::weak_ptr<context> parent, int width, int height, int stride);\r
+       void copy_from(host_buffer& source);\r
+       void copy_to(host_buffer& dest);\r
                        \r
+       void attach();\r
+       void clear();\r
        void bind(int index);\r
        void unbind();\r
        int id() const;\r
-\r
+private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
 };\r
index 45255c3124c73d3fb14974065045c3b972a10949..a34b4a1ccdf6c46aff6fe1e28576678dc010858b 100644 (file)
@@ -45,12 +45,10 @@ struct host_buffer::impl : boost::noncopyable
        tbb::atomic<void*>                      data_;\r
        GLenum                                          usage_;\r
        GLenum                                          target_;\r
-       std::weak_ptr<context>  parent_;\r
 \r
 public:\r
-       impl(std::weak_ptr<context> parent, int size, host_buffer::usage usage) \r
-               : parent_(parent)\r
-               , size_(size)\r
+       impl(int size, host_buffer::usage usage) \r
+               : size_(size)\r
                , pbo_(0)\r
                , target_(usage == host_buffer::usage::write_only ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_PACK_BUFFER)\r
                , usage_(usage == host_buffer::usage::write_only ? GL_STREAM_DRAW : GL_STREAM_READ)\r
@@ -120,27 +118,10 @@ public:
        {\r
                GL(glBindBuffer(target_, 0));\r
        }\r
-       \r
-       void* data()\r
-       {\r
-               if(data_ != nullptr)\r
-                       return data_;\r
-\r
-               auto ogl = parent_.lock();\r
-\r
-               if(!ogl)\r
-                       BOOST_THROW_EXCEPTION(invalid_operation());\r
-               \r
-               return ogl->invoke([&]\r
-               {\r
-                       return map();\r
-               }, task_priority::high_priority);\r
-       }\r
 };\r
 \r
-host_buffer::host_buffer(std::weak_ptr<context> parent, int size, usage usage) : impl_(new impl(parent, size, usage)){}\r
-const void* host_buffer::data() const {return impl_->data_;}\r
-void* host_buffer::data() {return impl_->data();}\r
+host_buffer::host_buffer(int size, usage usage) : impl_(new impl(size, usage)){}\r
+void* host_buffer::data(){return impl_->data_;}\r
 void host_buffer::map(){impl_->map();}\r
 void host_buffer::unmap(){impl_->unmap();}\r
 void host_buffer::bind(){impl_->bind();}\r
index a5cb16cc4e5c6829a0c850acdf888a421c5bdd82..7b1fd50c8f3ae5c74fcef86b29197c0e04be5610 100644 (file)
@@ -41,22 +41,18 @@ public:
        };\r
        typedef enum_class<usage_def> usage;\r
        \r
+       host_buffer(int size, usage usage);\r
+\r
        const void* data() const;\r
        void* data();\r
        int size() const;       \r
        \r
-private:\r
-       friend class context;\r
-       friend class device_buffer;\r
-\r
-       void bind();\r
-       void unbind();\r
-\r
        void map();\r
        void unmap();\r
 \r
-       host_buffer(std::weak_ptr<context> parent, int size, usage usage);\r
-\r
+       void bind();\r
+       void unbind();\r
+private:\r
        struct impl;\r
        spl::shared_ptr<impl> impl_;\r
 };\r
index 441eb9300c5528ad50f100cf74bc682347ef43e3..5e2af5ca3f26b47198061ce3e0e640db9447e3c8 100644 (file)
@@ -132,6 +132,11 @@ public:
        {\r
                GL(glUniform1f(get_location(name.c_str()), static_cast<float>(value)));\r
        }\r
+\r
+       void use()\r
+       {               \r
+               GL(glUseProgramObjectARB(program_));    \r
+       }\r
 };\r
 \r
 \r
@@ -141,5 +146,6 @@ void shader::set(const std::string& name, int value){impl_->set(name, value);}
 void shader::set(const std::string& name, float value){impl_->set(name, value);}\r
 void shader::set(const std::string& name, double value){impl_->set(name, value);}\r
 int shader::id() const{return impl_->program_;}\r
+void shader::use()const{impl_->use();}\r
 \r
 }}}
\ No newline at end of file
index ec0454ce202c3e27aaf4d674b1e782d70e136fff..426d011704c0957d6856d779e5a33bb57fd01c5b 100644 (file)
@@ -37,6 +37,7 @@ public:
        void set(const std::string& name, int value);\r
        void set(const std::string& name, float value);\r
        void set(const std::string& name, double value);\r
+       void use() const;\r
 private:\r
        friend class context;\r
        struct impl;\r
index 811d5cb94c8165d342050985be3a5a2d9d27b644..35eba31c8e5f9a65f2340bbccb168f23bc8092ad 100644 (file)
@@ -10,7 +10,7 @@
   <log-level>trace</log-level>\r
   <channels>\r
     <channel>\r
-      <video-mode>PAL</video-mode>\r
+      <video-mode>720p5000</video-mode>\r
       <consumers>\r
         <screen>\r
         </screen>\r
index ba1d18e7c8bb494d98fa9766545b35d8bf02c0a2..efd3f21a4572f47982d8cb459965977d85f75b00 100644 (file)
@@ -71,7 +71,6 @@ struct server::impl : boost::noncopyable
        std::vector<spl::shared_ptr<video_channel>>                     channels_;\r
 \r
        impl()          \r
-               : ogl_(accelerator::ogl::context::create())\r
        {                       \r
                ffmpeg::init();\r
                CASPAR_LOG(info) << L"Initialized ffmpeg module.";\r