]> git.sesse.net Git - casparcg/commitdiff
2.1.0: - device: Move buffer reset to texture copy function instead of shared_ptr...
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 20 Feb 2012 01:27:38 +0000 (01:27 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Mon, 20 Feb 2012 01:27:38 +0000 (01:27 +0000)
       - executor: Added "is_current" method for querying if the current context is the executor.

git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.1.0@2459 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

accelerator/ogl/image/image_mixer.cpp
accelerator/ogl/util/device.cpp
accelerator/ogl/util/texture.cpp
common/concurrency/executor.h

index e9f5e2ed35a02252e69fe9ea4baa25def29db89a..7c2a9830124fe95fcc37772bb521ac0a86a5846b 100644 (file)
@@ -306,6 +306,8 @@ public:
                item.pix_desc   = frame.pixel_format_desc();\r
                item.field_mode = frame.field_mode();\r
                item.transform  = transform_stack_.back();\r
+\r
+               // NOTE: Once we have copied the arrays they are no longer valid for reading!!! Check for alternative solution e.g. transfer with AMD_pinned_memory.\r
                for(int n = 0; n < static_cast<int>(item.pix_desc.planes.size()); ++n)\r
                        item.textures.push_back(ogl_->copy_async(frame.image_data(n), item.pix_desc.planes[n].width, item.pix_desc.planes[n].height, item.pix_desc.planes[n].stride));\r
                \r
index e5bc998a6e786c6ca0bd9e4112ea6b02383f6404..0fab52d2eaa7234a3f8960debc8403caabefd2e3 100644 (file)
@@ -156,24 +156,24 @@ struct device::impl : public std::enable_shared_from_this<impl>
                                                        \r
        spl::shared_ptr<texture> create_texture(int width, int height, int stride, bool clear = false)\r
        {\r
-               return render_executor_.invoke([=]() -> spl::shared_ptr<texture>\r
-               {\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
+               CASPAR_VERIFY(stride > 0 && stride < 5);\r
+               CASPAR_VERIFY(width > 0 && height > 0);\r
+\r
+               if(!render_executor_.is_current())\r
+                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Operation only valid in an OpenGL Context."));\r
+                                       \r
+               auto pool = &device_pools_[stride-1][((width << 16) & 0xFFFF0000) | (height & 0x0000FFFF)];\r
                \r
-                       std::shared_ptr<texture> buffer;\r
-                       if(!pool->try_pop(buffer))              \r
-                               buffer = spl::make_shared<texture>(width, height, stride);\r
+               std::shared_ptr<texture> buffer;\r
+               if(!pool->try_pop(buffer))              \r
+                       buffer = spl::make_shared<texture>(width, height, stride);\r
        \r
-                       if(clear)\r
-                               buffer->clear();\r
+               if(clear)\r
+                       buffer->clear();\r
 \r
-                       return spl::shared_ptr<texture>(buffer.get(), [buffer, pool](texture*) mutable\r
-                       {               \r
-                               pool->push(buffer);     \r
-                       });\r
+               return spl::shared_ptr<texture>(buffer.get(), [buffer, pool](texture*) mutable\r
+               {               \r
+                       pool->push(buffer);     \r
                });\r
        }\r
                \r
@@ -191,25 +191,12 @@ struct device::impl : public std::enable_shared_from_this<impl>
                                return spl::make_shared<buffer>(size, usage);\r
                        });\r
                }\r
-                               \r
-               auto ptr = buf->data();\r
-               auto self = shared_from_this(); // buffers can leave the device context, take a hold on life-time.\r
-\r
-               auto on_release = [self, buf, ptr, usage, pool]() mutable\r
-               {               \r
-                       if(usage == buffer::usage::write_only)                                  \r
-                               buf->map();                                     \r
-                       else\r
-                               buf->unmap();\r
-\r
-                       self->texture_cache_.erase(buf.get());\r
-\r
-                       pool->push(buf);\r
-               };\r
                \r
+               auto self = shared_from_this(); // buffers can leave the device context, take a hold on life-time.\r
                return spl::shared_ptr<buffer>(buf.get(), [=](buffer*) mutable\r
-               {\r
-                       self->alloc_executor_.begin_invoke(on_release); \r
+               {       \r
+                       texture_cache_.erase(buf.get());\r
+                       pool->push(buf);\r
                });\r
        }\r
 \r
@@ -252,21 +239,21 @@ struct device::impl : public std::enable_shared_from_this<impl>
 \r
        boost::unique_future<array<const std::uint8_t>> copy_async(const spl::shared_ptr<texture>& source)\r
        {\r
-               return flatten(render_executor_.begin_invoke([=]() -> boost::shared_future<array<const std::uint8_t>>\r
-               {\r
-                       auto buffer = create_buffer(source->size(), buffer::usage::read_only); \r
-                       source->copy_to(*buffer);       \r
+               if(!render_executor_.is_current())\r
+                       BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Operation only valid in an OpenGL Context."));\r
 \r
-                       auto self = shared_from_this();\r
-                       return async(launch::deferred, [self, buffer]() mutable -> array<const std::uint8_t>\r
-                       {\r
-                               const auto& buf = buffer.get();\r
-                               if(!buf->data())\r
-                                       self->alloc_executor_.invoke(std::bind(&buffer::map, std::ref(buf))); // Defer blocking "map" call until data is needed.\r
+               auto buffer = create_buffer(source->size(), buffer::usage::read_only); \r
+               source->copy_to(*buffer);       \r
 \r
-                               return array<const std::uint8_t>(buf->data(), buf->size(), true, buffer);\r
-                       });\r
-               }, task_priority::high_priority));\r
+               auto self = shared_from_this();\r
+               return async(launch::deferred, [self, buffer]() mutable -> array<const std::uint8_t>\r
+               {\r
+                       const auto& buf = buffer.get();\r
+                       if(!buf->data())\r
+                               self->alloc_executor_.invoke(std::bind(&buffer::map, std::ref(buf))); // Defer blocking "map" call until data is needed.\r
+\r
+                       return array<const std::uint8_t>(buf->data(), buf->size(), true, buffer);\r
+               });\r
        }\r
 };\r
 \r
index 34d7a344c2ccf341d8a5142a1eb715314e8fb972..426cd9a2a2f8ccfa3ea357d75cba884597cf3a6b 100644 (file)
@@ -106,6 +106,7 @@ public:
                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
+               source.map(); // Just map it back since map will orphan buffer.\r
        }\r
 \r
        void copy_to(buffer& dest)\r
index c4190ecc036277918857045129dd1e24bc492f45..9c82c63ec1e19cbc0b5f871f29c37c72585d6991 100644 (file)
@@ -134,7 +134,7 @@ public:
                {\r
                        try\r
                        {\r
-                               if(boost::this_thread::get_id() == thread_.get_id())  // Avoids potential deadlock.\r
+                               if(is_current())  // Avoids potential deadlock.\r
                                        my_task();\r
                        }\r
                        catch(boost::task_already_started&){}\r
@@ -162,7 +162,7 @@ public:
        template<typename Func>\r
        auto invoke(Func&& func, task_priority prioriy = task_priority::normal_priority) -> decltype(func()) // noexcept\r
        {\r
-               if(boost::this_thread::get_id() == thread_.get_id())  // Avoids potential deadlock.\r
+               if(is_current())  // Avoids potential deadlock.\r
                        return func();\r
                \r
                return begin_invoke(std::forward<Func>(func), prioriy).get();\r
@@ -170,7 +170,7 @@ public:
 \r
        void yield() // noexcept\r
        {\r
-               if(boost::this_thread::get_id() != thread_.get_id())\r
+               if(!is_current())\r
                        BOOST_THROW_EXCEPTION(invalid_operation() << msg_info("Executor can only yield inside of thread context."));\r
 \r
                int dummy;\r
@@ -219,6 +219,11 @@ public:
        {\r
                return is_running_; \r
        }       \r
+\r
+       bool is_current() const\r
+       {\r
+               return boost::this_thread::get_id() == thread_.get_id();\r
+       }\r
                \r
 private:       \r
 \r