]> git.sesse.net Git - casparcg/commitdiff
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 21 Jan 2012 03:42:27 +0000 (03:42 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 21 Jan 2012 03:42:27 +0000 (03:42 +0000)
common/concurrency/executor.h
core/core.vcxproj.filters
core/mixer/gpu/device_buffer.cpp
core/mixer/gpu/ogl_device.cpp
core/mixer/gpu/ogl_device.h
core/mixer/image/image_kernel.cpp
core/mixer/image/image_mixer.cpp
shell/casparcg.config

index 9b973626df259d90e741129fea9db33d4cc0957c..ff2e84454fa50df678d80edf67ab173af53288df 100644 (file)
@@ -210,10 +210,10 @@ public:
                return begin_invoke(std::forward<Func>(func), prioriy).get();\r
        }\r
        \r
-       void yield() // noexcept\r
+       bool yield() // noexcept\r
        {\r
                if(boost::this_thread::get_id() != thread_.get_id())  // Only yield when calling from execution thread.\r
-                       return;\r
+                       return false;\r
 \r
                std::function<void()> func;\r
                while(execution_queue_[high_priority].try_pop(func))\r
@@ -227,9 +227,9 @@ public:
                        execution_queue_[normal_priority].try_pop(func);\r
                        if(func)\r
                                func();\r
-                       else\r
-                               boost::thread::yield();\r
                }\r
+\r
+               return func != nullptr;\r
        }\r
        \r
        function_queue::size_type capacity() const /*noexcept*/ { return execution_queue_[normal_priority].capacity();  }\r
index fad1f823653c220639795f5f499b3f9aacc3a728..0da8769b51e9d03d03dbc717f4e835d88a79b7bc 100644 (file)
     <ClInclude Include="producer\playlist\playlist_producer.h">\r
       <Filter>source\producer\playlist</Filter>\r
     </ClInclude>\r
-    <ClInclude Include="mixer\image\shader\image_shader.h">\r
-      <Filter>source\mixer\image\shader</Filter>\r
-    </ClInclude>\r
     <ClInclude Include="mixer\image\blend_modes.h">\r
       <Filter>source\mixer\image</Filter>\r
     </ClInclude>\r
     <ClInclude Include="mixer\data_frame.h">\r
       <Filter>source\mixer</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="mixer\image\shader\image_shader.h">\r
+      <Filter>source\mixer\image\shader</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="producer\transition\transition_producer.cpp">\r
index c8af1e4d7dbc0638dd2cda94e899fae0af15f75b..4cd93db930ffc0b55f8e7f103904b9130b4aec1f 100644 (file)
@@ -80,11 +80,6 @@ public:
                        CASPAR_LOG_CURRENT_EXCEPTION();\r
                }\r
        }\r
-       \r
-       void bind()\r
-       {\r
-               GL(glBindTexture(GL_TEXTURE_2D, id_));\r
-       }\r
 };\r
 \r
 device_buffer::device_buffer(int width, int height, int stride) : impl_(new impl(width, height, stride)){}\r
index d771df013d11b81f5f42dadd3623940157274515..584038fbc58eac6e0b193b63340f589b58e461b4 100644 (file)
@@ -35,6 +35,8 @@
 #include <common/assert.h>\r
 #include <boost/foreach.hpp>\r
 \r
+#include <asmlib.h>\r
+\r
 #include <gl/glew.h>\r
 \r
 namespace caspar { namespace core {\r
@@ -111,14 +113,25 @@ safe_ptr<device_buffer> ogl_device::allocate_device_buffer(int width, int height
        return make_safe_ptr(buffer);\r
 }\r
                                \r
-safe_ptr<device_buffer> ogl_device::create_device_buffer(int width, int height, int stride)\r
+safe_ptr<device_buffer> ogl_device::create_device_buffer(int width, int height, int stride, bool zero)\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);}, high_priority);                   \r
+               \r
+       if(!pool->items.try_pop(buffer))                        \r
+               buffer =  executor_.invoke([&]{return allocate_device_buffer(width, height, stride);});\r
+\r
+       if(zero)\r
+       {               \r
+               executor_.invoke([&]\r
+               {\r
+                       scoped_state scope(*this);\r
+                       attach(*buffer);\r
+                       glClear(GL_COLOR_BUFFER_BIT);\r
+               }, high_priority);      \r
+       }               \r
        \r
        //++pool->usage_count;\r
 \r
@@ -234,15 +247,10 @@ void ogl_device::flush()
        //}\r
 }\r
 \r
-void ogl_device::yield()\r
+bool ogl_device::yield()\r
 {\r
-       push_state();\r
-       auto restore_state = make_scope_guard([&]\r
-       {\r
-               pop_state();\r
-       });\r
-       \r
-       executor_.yield();\r
+       scoped_state scope(*this);\r
+       return executor_.yield();\r
 }\r
 \r
 boost::unique_future<void> ogl_device::gc()\r
@@ -289,21 +297,25 @@ void ogl_device::push_state()
        state_stack_.push(state_);\r
 }\r
 \r
-void ogl_device::pop_state()\r
+ogl_device::state ogl_device::pop_state()\r
 {\r
-       if(state_stack_.size() == 1)\r
+       if(state_stack_.size() <= 1)\r
                BOOST_THROW_EXCEPTION(invalid_operation());\r
 \r
+       auto prev_state = state_stack_.top();\r
        state_stack_.pop();\r
        auto new_state = state_stack_.top();\r
-       viewport(new_state.viewport[0], new_state.viewport[1], new_state.viewport[2], new_state.viewport[3]);\r
-       scissor(new_state.scissor[0], new_state.scissor[1], new_state.scissor[2], new_state.scissor[3]);\r
-       stipple_pattern(new_state.pattern.data());\r
-       blend_func(new_state.blend_func[0], new_state.blend_func[1], new_state.blend_func[2], new_state.blend_func[3]);\r
+       \r
+       viewport(new_state.viewport);\r
+       scissor(new_state.scissor);\r
+       stipple_pattern(new_state.pattern);\r
+       blend_func(new_state.blend_func);\r
        attach(new_state.attached_texture);\r
        use(new_state.active_shader);\r
        for(int n = 0; n < 16; ++n)\r
                bind(new_state.binded_textures[n], n);\r
+\r
+       return prev_state;\r
 }\r
 \r
 void ogl_device::enable(GLenum cap)\r
@@ -326,9 +338,8 @@ void ogl_device::disable(GLenum cap)
        }\r
 }\r
 \r
-void ogl_device::viewport(int x, int y, int width, int height)\r
+void ogl_device::viewport(const std::array<GLint, 4>& viewport)\r
 {\r
-       std::array<int, 4> viewport = {{x, y, width, height}};\r
        if(viewport != state_.viewport)\r
        {               \r
                glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);\r
@@ -336,13 +347,17 @@ void ogl_device::viewport(int x, int y, int width, int height)
        }\r
 }\r
 \r
-void ogl_device::scissor(int x, int y, int width, int height)\r
+void ogl_device::viewport(int x, int y, int width, int height)\r
+{\r
+       std::array<int, 4> ar = {{x, y, width, height}};\r
+       viewport(ar);\r
+}\r
+\r
+void ogl_device::scissor(const std::array<GLint, 4>& scissor)\r
 {\r
-       std::array<int, 4> scissor = {{x, y, width, height}};\r
        if(scissor != state_.scissor)\r
        {               \r
-               state def_state_;\r
-               if(scissor == def_state_.scissor)\r
+               if(scissor == state().scissor)\r
                {\r
                        disable(GL_SCISSOR_TEST);\r
                }\r
@@ -355,21 +370,23 @@ void ogl_device::scissor(int x, int y, int width, int height)
        }\r
 }\r
 \r
-void ogl_device::stipple_pattern(const GLubyte* pattern)\r
+void ogl_device::scissor(int x, int y, int width, int height)\r
 {\r
-       std::array<GLubyte, 32*32> pattern2;\r
-       memcpy(pattern2.data(), pattern, 32*32);\r
+       std::array<int, 4> ar = {{x, y, width, height}};\r
+       scissor(ar);\r
+}\r
 \r
-       if(pattern2 != state_.pattern)\r
+void ogl_device::stipple_pattern(const std::array<GLubyte, 32*32>& pattern)\r
+{\r
+       if(pattern != state_.pattern)\r
        {\r
-               state def_state_;\r
-               if(pattern2 == def_state_.pattern)\r
+               if(pattern == state().pattern)\r
                        disable(GL_POLYGON_STIPPLE);\r
                else\r
                {\r
                        enable(GL_POLYGON_STIPPLE);\r
-                       glPolygonStipple(pattern2.data());\r
-                       state_.pattern = pattern2;\r
+                       glPolygonStipple(pattern.data());\r
+                       state_.pattern = pattern;\r
                }\r
        }\r
 }\r
@@ -399,6 +416,33 @@ void ogl_device::bind(GLint id, int index)
        }\r
 }\r
 \r
+void ogl_device::blend_func(const std::array<GLint, 4>& func)\r
+{\r
+       if(state_.blend_func != func)\r
+       {\r
+               state def_state_;\r
+               if(func == def_state_.blend_func)\r
+                       disable(GL_BLEND);\r
+               else\r
+               {\r
+                       enable(GL_BLEND);\r
+                       GL(glBlendFuncSeparate(func[0], func[1], func[2], func[3]));\r
+                       state_.blend_func = func;\r
+               }\r
+       }\r
+}\r
+\r
+void ogl_device::blend_func(int c1, int c2, int a1, int a2)\r
+{\r
+       std::array<int, 4> ar = {c1, c2, a1, a2};\r
+       blend_func(ar);\r
+}\r
+\r
+void ogl_device::blend_func(int c1, int c2)\r
+{\r
+       blend_func(c1, c2, c1, c2);\r
+}\r
+\r
 void ogl_device::bind(const device_buffer& texture, int index)\r
 {\r
        //while(true)\r
@@ -412,17 +456,6 @@ void ogl_device::bind(const device_buffer& texture, int index)
        bind(texture.id(), index);\r
 }\r
 \r
-void ogl_device::clear(device_buffer& texture)\r
-{      \r
-       auto prev = state_.attached_texture;\r
-       attach(texture);\r
-       auto restore_attachement = make_scope_guard([&]\r
-       {\r
-               attach(prev);\r
-       });\r
-\r
-       GL(glClear(GL_COLOR_BUFFER_BIT));\r
-}\r
 \r
 void ogl_device::use(GLint id)\r
 {\r
@@ -438,46 +471,23 @@ void ogl_device::use(const shader& shader)
        use(shader.id());\r
 }\r
 \r
-void ogl_device::blend_func(int c1, int c2, int a1, int a2)\r
-{\r
-       std::array<int, 4> func = {c1, c2, a1, a2};\r
-\r
-       if(state_.blend_func != func)\r
-       {\r
-               state def_state_;\r
-               if(func == def_state_.blend_func)\r
-                       disable(GL_BLEND);\r
-               else\r
-               {\r
-                       enable(GL_BLEND);\r
-                       GL(glBlendFuncSeparate(c1, c2, a1, a2));\r
-                       state_.blend_func = func;\r
-               }\r
-       }\r
-}\r
-\r
-void ogl_device::blend_func(int c1, int c2)\r
-{\r
-       blend_func(c1, c2, c1, c2);\r
-}\r
 \r
 boost::unique_future<safe_ptr<host_buffer>> ogl_device::transfer(const safe_ptr<device_buffer>& source)\r
 {              \r
        return begin_invoke([=]() -> safe_ptr<host_buffer>\r
        {\r
-               push_state();\r
-               auto restore_state = make_scope_guard([&]\r
-               {\r
-                       pop_state();\r
-               });\r
-\r
                auto dest = create_host_buffer(source->width()*source->height()*source->stride(), host_buffer::read_only);\r
 \r
-               attach(*source);\r
+               {\r
+                       scoped_state scope(*this);\r
+\r
+                       attach(*source);\r
        \r
-               dest->bind();\r
-               GL(glReadPixels(0, 0, source->width(), source->height(), format(source->stride()), GL_UNSIGNED_BYTE, NULL));\r
-               dest->unbind();\r
+                       dest->bind();\r
+                       GL(glReadPixels(0, 0, source->width(), source->height(), format(source->stride()), GL_UNSIGNED_BYTE, NULL));\r
+\r
+                       dest->unbind();\r
+               }\r
        \r
                auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);\r
 \r
@@ -491,7 +501,10 @@ boost::unique_future<safe_ptr<host_buffer>> ogl_device::transfer(const safe_ptr<
                        GL(glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, values));\r
 \r
                        if(values[0] != GL_SIGNALED)            \r
-                               yield();\r
+                       {\r
+                               if(!yield())\r
+                                       Sleep(2);\r
+                       }\r
                        else\r
                                break;\r
                }\r
@@ -505,14 +518,10 @@ boost::unique_future<safe_ptr<host_buffer>> ogl_device::transfer(const safe_ptr<
 boost::unique_future<safe_ptr<device_buffer>> ogl_device::transfer(const safe_ptr<host_buffer>& source, int width, int height, int stride)\r
 {              \r
        return begin_invoke([=]() -> safe_ptr<device_buffer>\r
-       {\r
-               push_state();\r
-               auto restore_state = make_scope_guard([&]\r
-               {\r
-                       pop_state();\r
-               });\r
-               \r
+       {               \r
                auto dest = create_device_buffer(width, height, stride);\r
+               \r
+               scoped_state scope(*this);\r
 \r
                source->unmap();\r
                source->bind();\r
@@ -521,10 +530,31 @@ boost::unique_future<safe_ptr<device_buffer>> ogl_device::transfer(const safe_pt
                GL(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dest->width(), dest->height(), format(dest->stride()), GL_UNSIGNED_BYTE, NULL));\r
                        \r
                source->unbind();\r
-\r
+               \r
                return dest;\r
        });\r
 }\r
 \r
+ogl_device::state::state()\r
+       : attached_texture(0)\r
+       , active_shader(0)\r
+{\r
+       binded_textures.assign(0);\r
+       viewport.assign(std::numeric_limits<int>::max());\r
+       scissor.assign(std::numeric_limits<int>::max());\r
+       blend_func.assign(std::numeric_limits<int>::max());\r
+       pattern.assign(0xFF);\r
+}       \r
+\r
+ogl_device::state::state(const state& other)\r
+{\r
+       A_memcpy(this, &other, sizeof(state));\r
+}\r
+\r
+ogl_device::state& ogl_device::state::operator=(const state& other)\r
+{\r
+       A_memcpy(this, &other, sizeof(state));\r
+}\r
+\r
 }}\r
 \r
index 368c8490c248dfbb06cfc0a7b72411b5d9f229ff..31c4a37542fb59ecceaea30f76cac803cba146bb 100644 (file)
@@ -40,6 +40,7 @@
 #include <array>\r
 #include <stack>\r
 #include <unordered_map>\r
+#include <type_traits>\r
 \r
 FORWARD1(boost, template<typename> class unique_future);\r
 \r
@@ -64,28 +65,22 @@ struct buffer_pool : boost::noncopyable
 class ogl_device : public std::enable_shared_from_this<ogl_device>\r
                                 , boost::noncopyable\r
 {      \r
-       struct state\r
+       __declspec(align(16)) struct state\r
        {\r
-               std::array<int, 4>                                              viewport;\r
-               std::array<int, 4>                                              scissor;\r
                std::array<GLubyte, 32*32>                              pattern;\r
-               GLint                                                                   attached_texture;\r
-               GLint                                                                   active_shader;\r
+               std::array<GLint, 4>                                    viewport;\r
+               std::array<GLint, 4>                                    scissor;\r
                std::array<GLint, 4>                                    blend_func;\r
                std::array<GLint, 16>                                   binded_textures;\r
+               GLint                                                                   attached_texture;\r
+               GLint                                                                   active_shader;\r
+               GLint padding[2];\r
 \r
-               state()\r
-                       : attached_texture(0)\r
-                       , active_shader(0)\r
-               {\r
-                       binded_textures.assign(0);\r
-                       viewport.assign(std::numeric_limits<int>::max());\r
-                       scissor.assign(std::numeric_limits<int>::max());\r
-                       blend_func.assign(std::numeric_limits<int>::max());\r
-                       pattern.assign(0xFF);\r
-               }        \r
+               state(); \r
+               state(const state& other);\r
+               state& operator=(const state& other);\r
        };\r
-\r
+       \r
        state state_;\r
        std::stack<state> state_stack_;\r
 \r
@@ -106,22 +101,24 @@ class ogl_device : public std::enable_shared_from_this<ogl_device>
        void use(GLint id);\r
        void attach(GLint id);\r
        void bind(GLint id, int index); \r
-       void push_state();\r
-       void pop_state();\r
        void flush();\r
-\r
+       \r
+       friend class scoped_state;\r
 public:                \r
+       void push_state();\r
+       state pop_state();\r
+       \r
        static safe_ptr<ogl_device> create();\r
        ~ogl_device();\r
 \r
-\r
        // Not thread-safe, must be called inside of context\r
        void viewport(int x, int y, int width, int height);\r
+       void viewport(const std::array<GLint, 4>& ar);\r
        void scissor(int x, int y, int width, int height);\r
-       void stipple_pattern(const GLubyte* pattern);\r
-       \r
-       void clear(device_buffer& texture);\r
-       \r
+       void scissor(const std::array<GLint, 4>& ar);\r
+       void stipple_pattern(const std::array<GLubyte, 32*32>& pattern);\r
+               \r
+       void blend_func(const std::array<GLint, 4>& ar);\r
        void blend_func(int c1, int c2, int a1, int a2);\r
        void blend_func(int c1, int c2);\r
        \r
@@ -145,13 +142,13 @@ public:
                return executor_.invoke(std::forward<Func>(func), priority);\r
        }\r
                \r
-       safe_ptr<device_buffer> create_device_buffer(int width, int height, int stride);\r
+       safe_ptr<device_buffer> create_device_buffer(int width, int height, int stride, bool zero = false);\r
        safe_ptr<host_buffer> create_host_buffer(int size, host_buffer::usage_t usage);\r
 \r
        boost::unique_future<safe_ptr<host_buffer>> transfer(const safe_ptr<device_buffer>& source);\r
        boost::unique_future<safe_ptr<device_buffer>> transfer(const safe_ptr<host_buffer>& source, int width, int height, int stride);\r
        \r
-       void yield();\r
+       bool yield();\r
        boost::unique_future<void> gc();\r
 \r
        std::wstring version();\r
@@ -161,4 +158,20 @@ private:
        safe_ptr<host_buffer> allocate_host_buffer(int size, host_buffer::usage_t usage);\r
 };\r
 \r
+class scoped_state\r
+{\r
+       ogl_device& context_;\r
+public:\r
+       scoped_state(ogl_device& context)\r
+               : context_(context)\r
+       {\r
+               context_.push_state();\r
+       }\r
+\r
+       ~scoped_state()\r
+       {\r
+               context_.pop_state();\r
+       }\r
+};\r
+\r
 }}
\ No newline at end of file
index a25d23143b77c69662f38d74c83abf6a67f899be..9d668e2dc504973144578dda477b47e89fb34f43 100644 (file)
 \r
 namespace caspar { namespace core {\r
        \r
-GLubyte upper_pattern[] = {\r
+std::array<GLubyte, 32*32> upper_pattern = {{\r
        0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
        0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
        0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\r
-       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};\r
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}};\r
                \r
-GLubyte lower_pattern[] = {\r
+std::array<GLubyte, 32*32> lower_pattern = {{\r
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, \r
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
        0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,\r
-       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};\r
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}};\r
 \r
 struct image_kernel::impl : boost::noncopyable\r
 {      \r
@@ -72,7 +72,9 @@ struct image_kernel::impl : boost::noncopyable
                static const double epsilon = 0.001;\r
 \r
                ogl_->invoke([&]\r
-               {                       \r
+               {               \r
+                       scoped_state scope(*ogl_);\r
+\r
                        CASPAR_ASSERT(params.pix_desc.planes.size() == params.textures.size());\r
 \r
                        if(params.textures.empty() || !params.background)\r
@@ -196,16 +198,7 @@ struct image_kernel::impl : boost::noncopyable
                        // Set render target\r
                \r
                        ogl_->attach(*params.background);\r
-               \r
-                       // Sync background\r
-\r
-                       if(blend_modes_)\r
-                       {\r
-                               // http://www.opengl.org/registry/specs/NV/texture_barrier.txt\r
-                               // This allows us to use framebuffer (background) both as source and target while blending.\r
-                               glTextureBarrierNV(); \r
-                       }\r
-\r
+                       \r
                        // Draw                 \r
 \r
                        glBegin(GL_QUADS);\r
@@ -214,10 +207,15 @@ struct image_kernel::impl : boost::noncopyable
                                glMultiTexCoord2d(GL_TEXTURE0, 1.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1, (f_p[0]+f_s[0]), (f_p[1]+f_s[1]));             glVertex2d((f_p[0]+f_s[0])*2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
                                glMultiTexCoord2d(GL_TEXTURE0, 0.0, 1.0); glMultiTexCoord2d(GL_TEXTURE1,  f_p[0]        , (f_p[1]+f_s[1]));             glVertex2d( f_p[0]        *2.0-1.0, (f_p[1]+f_s[1])*2.0-1.0);\r
                        glEnd();\r
-               \r
-                       // Cleanup\r
-                                                                       \r
-                       params.textures.clear();\r
+\r
+                       // Sync background\r
+\r
+                       if(blend_modes_)\r
+                       {\r
+                               // http://www.opengl.org/registry/specs/NV/texture_barrier.txt\r
+                               // This allows us to use framebuffer (background) both as source and target while blending.\r
+                               glTextureBarrierNV(); \r
+                       }\r
                });\r
        }\r
 };\r
index 42c0ad63e30280ed8b5045649e015dfa9072cb4a..7164330fee9e2737147a7b4593464ad44b669c8a 100644 (file)
@@ -68,8 +68,8 @@ public:
        \r
        boost::unique_future<safe_ptr<host_buffer>> operator()(std::vector<layer>&& layers, const video_format_desc& format_desc)\r
        {               \r
-               auto draw_buffer = create_mixer_buffer(4, format_desc);\r
-\r
+               auto draw_buffer = ogl_->create_device_buffer(format_desc.width, format_desc.height, 4, true);\r
+                       \r
                if(format_desc.field_mode != field_mode::progressive)\r
                {\r
                        auto upper = layers;\r
@@ -94,8 +94,8 @@ public:
                {\r
                        draw(std::move(layers), draw_buffer, format_desc);\r
                }\r
-                                                               \r
-               return ogl_->transfer(draw_buffer);             \r
+                                               \r
+               return ogl_->transfer(draw_buffer);     \r
        }\r
 \r
 private:\r
@@ -125,7 +125,7 @@ private:
                                \r
                if(layer.first != blend_mode::normal)\r
                {\r
-                       auto layer_draw_buffer = create_mixer_buffer(4, format_desc);\r
+                       auto layer_draw_buffer = ogl_->create_device_buffer(format_desc.width, format_desc.height, 4, true);\r
 \r
                        BOOST_FOREACH(auto& item, layer.second)\r
                                draw_item(std::move(item), layer_draw_buffer, layer_key_buffer, local_key_buffer, local_mix_buffer, format_desc);       \r
@@ -161,7 +161,7 @@ private:
 \r
                if(item.transform.is_key)\r
                {\r
-                       local_key_buffer = local_key_buffer ? local_key_buffer : create_mixer_buffer(1, format_desc);\r
+                       local_key_buffer = local_key_buffer ? local_key_buffer : ogl_->create_device_buffer(format_desc.width, format_desc.height, 4, true);\r
 \r
                        draw_params.background                  = local_key_buffer;\r
                        draw_params.local_key                   = nullptr;\r
@@ -171,7 +171,7 @@ private:
                }\r
                else if(item.transform.is_mix)\r
                {\r
-                       local_mix_buffer = local_mix_buffer ? local_mix_buffer : create_mixer_buffer(4, format_desc);\r
+                       local_mix_buffer = local_mix_buffer ? local_mix_buffer : ogl_->create_device_buffer(format_desc.width, format_desc.height, 4, true);\r
 \r
                        draw_params.background                  = local_mix_buffer;\r
                        draw_params.local_key                   = std::move(local_key_buffer);\r
@@ -210,13 +210,6 @@ private:
 \r
                kernel_.draw(std::move(draw_params));\r
        }\r
-                       \r
-       safe_ptr<device_buffer> create_mixer_buffer(int stride, const 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
-               return buffer;\r
-       }\r
 };\r
                \r
 struct image_mixer::impl : boost::noncopyable\r
index 26d83eacef155cdc8b71c5d99469bcf34f18ad9f..ee6f4ee54ee675a94e43aa25524702cadf20fb01 100644 (file)
@@ -8,15 +8,20 @@
   </paths>\r
   <log-level>trace</log-level>\r
   <channel-grid>true</channel-grid>\r
-  <blend-modes>true</blend-modes>\r
   <channels>\r
     <channel>\r
       <video-mode>720p5000</video-mode>\r
       <consumers>\r
-        <screen>\r
-          <device>1</device>\r
-        </screen>\r
-        <system-audio></system-audio>\r
+      </consumers>\r
+    </channel>\r
+    <channel>\r
+      <video-mode>720p5000</video-mode>\r
+      <consumers>\r
+      </consumers>\r
+    </channel>\r
+    <channel>\r
+      <video-mode>720p5000</video-mode>\r
+      <consumers>\r
       </consumers>\r
     </channel>\r
   </channels>\r