]> git.sesse.net Git - casparcg/commitdiff
OGL image_mixer: Fixed a performance hotspot where an idle channel without any layers...
authorHelge Norberg <helge.norberg@svt.se>
Thu, 5 Mar 2015 21:10:47 +0000 (22:10 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Thu, 5 Mar 2015 21:10:47 +0000 (22:10 +0100)
accelerator/ogl/image/image_mixer.cpp
common/array.h
common/enum_class.h
modules/ffmpeg/producer/util/util.cpp
modules/psd/psd.vcxproj
shell/shell.vcxproj

index 5e2287e41614fcca1efb644e3e7fcbed034a29f4..d0296e5cee77f208bc3f41a59a2554946d126d0e 100644 (file)
@@ -43,6 +43,7 @@
 #include <gl/glew.h>
 
 #include <boost/range/algorithm_ext/erase.hpp>
+#include <boost/range/algorithm/max_element.hpp>
 #include <boost/thread/future.hpp>
 
 #include <algorithm>
@@ -77,6 +78,17 @@ struct layer
        }
 };
 
+std::size_t get_max_video_format_size()
+{
+       return *boost::range::max_element(
+               iterate_enum<core::video_format>()
+               | boost::adaptors::transformed(
+                               [] (core::video_format format)
+                               {
+                                       return core::video_format_desc(format).size;
+                               }));
+}
+
 class image_renderer
 {
        spl::shared_ptr<device> ogl_;
@@ -92,9 +104,9 @@ public:
        {       
                if(layers.empty())
                { // Bypass GPU with empty frame.
-                       auto buffer = spl::make_shared<const cache_aligned_vector<uint8_t>>(format_desc.size, 0);
-                       return make_ready_future(array<const std::uint8_t>(buffer->data(), format_desc.size, true, buffer));
-               }               
+                       static const cache_aligned_vector<uint8_t> buffer(get_max_video_format_size(), 0);
+                       return make_ready_future(array<const std::uint8_t>(buffer.data(), format_desc.size, true));
+               }
 
                if(format_desc.field_mode != core::field_mode::progressive)
                { // Remove jitter from still.
index 8446e20b05d782b457ff6a2fb591b0b21a19e3d3..08c1e2e653b575eb824b3064e923c3676274d87b 100644 (file)
@@ -96,7 +96,15 @@ public:
                , storage_(new boost::any(std::forward<T>(storage)))
        {
        }
-       
+
+       explicit array(const std::uint8_t* ptr, std::size_t size, bool cacheable)
+               : ptr_(ptr)
+               , size_(size)
+               , cacheable_(cacheable)
+               , storage_(new boost::any)
+       {
+       }
+
        array(const array& other)
                : ptr_(other.ptr_)
                , size_(other.size_)
index 4d919aff22e5fe45a8a55a8462eeef5c76bc1ad6..91b2555bca7dd85be41f64e66bade015aa0affc8 100644 (file)
@@ -2,6 +2,9 @@
 
 #include <type_traits>
 
+#include <boost/range/adaptor/transformed.hpp>
+#include <boost/range/irange.hpp>
+
 // Macro that defines & and &= for an enum class. Add more when needed.
 
 #define ENUM_ENABLE_BITWISE(enum_class) \
                lhs = lhs & rhs; \
                return lhs; \
        };
+
+namespace caspar {
+
+template<typename E>
+struct enum_from_int
+{
+       typedef E result_type;
+
+       E operator()(typename std::underlying_type<E>::type i) const
+       {
+               return static_cast<E>(i);
+       }
+};
+
+// For enum classes starting at 0 and without any gaps with a terminating count constant.
+template <typename E>
+boost::transformed_range<enum_from_int<E>, const boost::integer_range<typename std::underlying_type<E>::type>> iterate_enum()
+{
+       typedef typename std::underlying_type<E>::type integer;
+       return boost::irange(static_cast<integer>(0), static_cast<integer>(E::count)) | boost::adaptors::transformed(enum_from_int<E>());
+}
+
+}
\ No newline at end of file
index 785599e0b725d5dce23e8bb5342694ae272537d7..215dc906dcbb338f094a1a6092ce85ce50426295 100644 (file)
@@ -394,9 +394,10 @@ double read_fps(AVFormatContext& context, double fail_value)
                double fps = static_cast<double>(time_base.den) / static_cast<double>(time_base.num);
 
                double closest_fps = 0.0;
-               for(int n = 0; n < static_cast<int>(core::video_format::count); ++n)
+
+               for (auto video_mode : iterate_enum<core::video_format>())
                {
-                       auto format = core::video_format_desc(core::video_format(n));
+                       auto format = core::video_format_desc(core::video_format(video_mode));
 
                        double diff1 = std::abs(format.fps - fps);
                        double diff2 = std::abs(closest_fps - fps);
index 1360e0bf2ff4bd0cba1a52474188d917a784c9a2..295cfca26d9154864970f7ff74d0f95fd068f303 100644 (file)
@@ -95,6 +95,7 @@
       <TreatWarningAsError>true</TreatWarningAsError>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <ForcedIncludeFiles>common/compiler/vs/disable_silly_warnings.h</ForcedIncludeFiles>
+      <MinimalRebuild>false</MinimalRebuild>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
index b2bd900851b5228522acbee96470f5668d18f709..a8fdc277f58c6a623d51ada03b1b4930b93b7ed5 100644 (file)
@@ -9,6 +9,10 @@
       <Configuration>Release</Configuration>\r
       <Platform>x64</Platform>\r
     </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32"> <!-- Only to enable profiling. See http://stackoverflow.com/questions/13934895/profiling-with-cmake-c-and-visual-studio-2012 -->\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="server.cpp">\r