]> 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, 18 Feb 2012 11:41:32 +0000 (11:41 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sat, 18 Feb 2012 11:41:32 +0000 (11:41 +0000)
accelerator/cpu/image/image_mixer.cpp
accelerator/ogl/image/image_mixer.cpp
accelerator/ogl/util/device.cpp
common/concurrency/async.h
modules/ffmpeg/producer/tbb_avcodec.cpp

index 93d933a144d5763fac5f7555017cc3d6c2de9fcf..71f24e5eba7653ed1619f066e32f35cf086ec657 100644 (file)
@@ -172,7 +172,7 @@ public:
 \r
                temp_buffers_.clear();\r
                \r
-               return async(launch_policy::deferred, [=]\r
+               return async(launch::deferred, [=]\r
                {\r
                        return core::const_array(result->data(), format_desc.size, result);\r
                });     \r
index da9d1dfa0cb9941cc0c71ed8d80a4b21a78056e2..01060f8cabfef06eddda70680885ab0a6129fe05 100644 (file)
@@ -101,13 +101,13 @@ public:
                if(layers.empty())\r
                { // Bypass GPU with empty frame.\r
                        auto buffer = spl::make_shared<const std::vector<uint8_t, tbb::cache_aligned_allocator<uint8_t>>>(format_desc.size, 0);\r
-                       return async(launch_policy::deferred, [=]\r
+                       return async(launch::deferred, [=]\r
                        {\r
                                return core::const_array(buffer->data(), static_cast<std::size_t>(format_desc.size), buffer);\r
                        });\r
                }               \r
 \r
-               return fold(ogl_->begin_invoke([=]() mutable -> boost::shared_future<core::const_array>\r
+               return flatten(ogl_->begin_invoke([=]() mutable -> boost::shared_future<core::const_array>\r
                {\r
                        auto draw_buffer = create_mixer_buffer(format_desc.width, format_desc.height, 4);\r
 \r
index f8f3813694a69229bf2fb4cddd954b5e3bafd294..dccde2e5785c9eacdbcf7169d55bfdee655bbfcd 100644 (file)
@@ -236,12 +236,12 @@ struct device::impl : public std::enable_shared_from_this<impl>
 \r
        boost::unique_future<core::const_array> copy_async(const spl::shared_ptr<texture>& source)\r
        {\r
-               return fold(render_executor_.begin_invoke([=]() -> boost::shared_future<core::const_array>\r
+               return flatten(render_executor_.begin_invoke([=]() -> boost::shared_future<core::const_array>\r
                {\r
                        auto buffer = create_buffer(source->size(), buffer::usage::read_only); \r
                        source->copy_to(*buffer);       \r
 \r
-                       return make_shared(async(launch_policy::deferred, [=]() mutable -> core::const_array\r
+                       return make_shared(async(launch::deferred, [=]() mutable -> core::const_array\r
                        {\r
                                const auto& buf = buffer.get();\r
                                if(!buf->data())\r
index 3a0f66beac1fa45daa2dda3e56cf6a6ea51af453..9069fedfadb7c619b13281baf91a76b186e5ca50 100644 (file)
@@ -20,7 +20,7 @@ struct launch_policy_def
                deferred\r
        };\r
 };\r
-typedef enum_class<launch_policy_def> launch_policy;\r
+typedef enum_class<launch_policy_def> launch;\r
 \r
 namespace detail {\r
 \r
@@ -48,33 +48,44 @@ struct invoke_function<void>
 }\r
        \r
 template<typename F>\r
-auto async(launch_policy lp, F&& f) -> boost::unique_future<decltype(f())>\r
+auto async(launch lp, F&& f) -> boost::unique_future<decltype(f())>\r
 {              \r
        typedef decltype(f()) result_type;\r
+       \r
+       typedef boost::promise<result_type> promise_t;\r
 \r
-       if(lp == launch_policy::deferred)\r
-       {\r
-               typedef boost::promise<result_type> promise_t;\r
+       // WORKAROUND: Use heap storage since lambdas don't support move semantics and do a lot of unnecessary copies.\r
+       auto promise = new promise_t();\r
+       auto func        = new F(std::forward<F>(f));\r
+       auto future  = promise->get_future();\r
 \r
-               auto promise = new promise_t();\r
-               auto future  = promise->get_future();\r
-       \r
+       if(lp == launch::deferred)\r
+       {       \r
                promise->set_wait_callback(std::function<void(promise_t&)>([=](promise_t&) mutable\r
                {\r
                        std::unique_ptr<promise_t> pointer_guard(promise);\r
-                       detail::invoke_function<result_type>()(*promise, f);\r
+                       std::unique_ptr<F>                 func_guard(func);\r
+                       detail::invoke_function<result_type>()(*promise, *func);\r
                }));\r
 \r
                return std::move(future);\r
        }\r
        else\r
        {\r
-               typedef boost::packaged_task<result_type> packaged_task_t;\r
-\r
-               auto task   = packaged_task_t(f);    \r
-               auto future = task.get_future();\r
-\r
-               boost::thread(std::move(task)).detach();\r
+               boost::thread([=]\r
+               {\r
+                       std::unique_ptr<promise_t> pointer_guard(promise);\r
+                       std::unique_ptr<F>                 func_guard(func);\r
+\r
+                       try\r
+                       {                               \r
+                               detail::invoke_function<result_type>()(*promise, *func);\r
+                       }\r
+                       catch(...)\r
+                       {\r
+                               promise->set_exception(boost::current_exception());\r
+                       }\r
+               }).detach();\r
 \r
                return std::move(future);\r
        }\r
@@ -83,7 +94,7 @@ auto async(launch_policy lp, F&& f) -> boost::unique_future<decltype(f())>
 template<typename F>\r
 auto async(F&& f) -> boost::unique_future<decltype(f())>\r
 {      \r
-       return async(launch_policy::async, std::forward<F>(f));\r
+       return async(launch::async, std::forward<F>(f));\r
 }\r
 \r
 template<typename T>\r
@@ -93,10 +104,10 @@ auto make_shared(boost::unique_future<T>&& f) -> boost::shared_future<T>
 }\r
 \r
 template<typename T>\r
-auto fold(boost::unique_future<T>&& f) -> boost::unique_future<decltype(f.get().get())>\r
+auto flatten(boost::unique_future<T>&& f) -> boost::unique_future<decltype(f.get().get())>\r
 {\r
        auto shared_f = make_shared(std::move(f));\r
-       return async(launch_policy::deferred, [=]() mutable\r
+       return async(launch::deferred, [=]() mutable\r
        {\r
                return shared_f.get().get();\r
        });\r
index 9d669863d776f62b1c921f0e00df8cf56fc41376..2e21622379b26886664d4a5e0e3b49aa59561fa8 100644 (file)
@@ -91,8 +91,6 @@ void thread_init(AVCodecContext* s)
     s->execute                   = thread_execute;\r
     s->execute2                          = thread_execute2;\r
     s->thread_count              = MAX_THREADS; // We are using a task-scheduler, so use as many "threads/tasks" as possible. \r
-\r
-       CASPAR_LOG(info) << "Initialized ffmpeg tbb context.";\r
 }\r
 \r
 void thread_free(AVCodecContext* s)\r
@@ -101,8 +99,6 @@ void thread_free(AVCodecContext* s)
                return;\r
 \r
        s->thread_opaque = nullptr;\r
-       \r
-       CASPAR_LOG(info) << "Released ffmpeg tbb context.";\r
 }\r
 \r
 int tbb_avcodec_open(AVCodecContext* avctx, AVCodec* codec)\r