]> git.sesse.net Git - casparcg/blobdiff - core/mixer/gpu/ogl_device.cpp
- Increased consumer timeout to 10 seconds.
[casparcg] / core / mixer / gpu / ogl_device.cpp
index f7f17f94e18ee4f124cff80b020cdec7066921ac..0ea77fbb4641b625975a0eeca14650045352f734 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-* Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>\r
+* Copyright 2013 Sveriges Television AB http://casparcg.com/\r
 *\r
 * This file is part of CasparCG (www.casparcg.com).\r
 *\r
@@ -32,6 +32,7 @@
 #include <common/gl/gl_check.h>\r
 \r
 #include <boost/foreach.hpp>\r
+#include <boost/property_tree/ptree.hpp>\r
 \r
 #include <gl/glew.h>\r
 \r
@@ -41,6 +42,7 @@ ogl_device::ogl_device()
        : executor_(L"ogl_device")\r
        , pattern_(nullptr)\r
        , attached_texture_(0)\r
+       , attached_fbo_(0)\r
        , active_shader_(0)\r
        , read_buffer_(0)\r
 {\r
@@ -62,13 +64,10 @@ ogl_device::ogl_device()
                CASPAR_LOG(info) << L"OpenGL " << version();\r
 \r
                if(!GLEW_VERSION_3_0)\r
-                       CASPAR_LOG(warning) << "Missing OpenGL 3.0 support.";\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
-               CASPAR_LOG(info) << L"Successfully initialized GLEW.";\r
-\r
-               glGenFramebuffers(1, &fbo_);            \r
-               glBindFramebuffer(GL_FRAMEBUFFER, fbo_);\r
-\r
+               glGenFramebuffers(1, &fbo_);    \r
+               \r
                CASPAR_LOG(info) << L"Successfully initialized OpenGL Device.";\r
        });\r
 }\r
@@ -81,16 +80,16 @@ ogl_device::~ogl_device()
                        pool.clear();\r
                BOOST_FOREACH(auto& pool, host_pools_)\r
                        pool.clear();\r
-               glDeleteFramebuffersEXT(1, &fbo_);\r
+               glDeleteFramebuffers(1, &fbo_);\r
        });\r
 }\r
 \r
-safe_ptr<device_buffer> ogl_device::allocate_device_buffer(size_t width, size_t height, size_t stride)\r
+safe_ptr<device_buffer> ogl_device::allocate_device_buffer(size_t width, size_t height, size_t stride, bool mipmapped)\r
 {\r
        std::shared_ptr<device_buffer> buffer;\r
        try\r
        {\r
-               buffer.reset(new device_buffer(width, height, stride));\r
+               buffer.reset(new device_buffer(width, height, stride, mipmapped));\r
        }\r
        catch(...)\r
        {\r
@@ -100,7 +99,7 @@ safe_ptr<device_buffer> ogl_device::allocate_device_buffer(size_t width, size_t
                        gc().wait();\r
                                        \r
                        // Try again\r
-                       buffer.reset(new device_buffer(width, height, stride));\r
+                       buffer.reset(new device_buffer(width, height, stride, mipmapped));\r
                }\r
                catch(...)\r
                {\r
@@ -111,14 +110,14 @@ safe_ptr<device_buffer> ogl_device::allocate_device_buffer(size_t width, size_t
        return make_safe_ptr(buffer);\r
 }\r
                                \r
-safe_ptr<device_buffer> ogl_device::create_device_buffer(size_t width, size_t height, size_t stride)\r
+safe_ptr<device_buffer> ogl_device::create_device_buffer(size_t width, size_t height, size_t stride, bool mipmapped)\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
+       auto& pool = device_pools_[stride-1 + (mipmapped ? 4 : 0)][((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
+               buffer = executor_.invoke([&]{return allocate_device_buffer(width, height, stride, mipmapped);}, high_priority);                        \r
        \r
        //++pool->usage_count;\r
 \r
@@ -239,6 +238,97 @@ void ogl_device::yield()
        executor_.yield();\r
 }\r
 \r
+boost::property_tree::wptree ogl_device::info() const\r
+{\r
+       boost::property_tree::wptree info;\r
+\r
+       boost::property_tree::wptree pooled_device_buffers;\r
+       size_t total_pooled_device_buffer_size = 0;\r
+       size_t total_pooled_device_buffer_count = 0;\r
+\r
+       for (size_t i = 0; i < device_pools_.size(); ++i)\r
+       {\r
+               auto& pools = device_pools_.at(i);\r
+               bool mipmapping = i > 3;\r
+               int stride = mipmapping ? i - 3 : i + 1;\r
+\r
+               BOOST_FOREACH(auto& pool, pools)\r
+               {\r
+                       auto width = pool.first >> 16;\r
+                       auto height = pool.first & 0x0000FFFF;\r
+                       auto size = width * height * stride;\r
+                       auto count = pool.second->items.size();\r
+\r
+                       if (count == 0)\r
+                               continue;\r
+\r
+                       boost::property_tree::wptree pool_info;\r
+\r
+                       pool_info.add(L"stride", stride);\r
+                       pool_info.add(L"mipmapping", mipmapping);\r
+                       pool_info.add(L"width", width);\r
+                       pool_info.add(L"height", height);\r
+                       pool_info.add(L"size", size);\r
+                       pool_info.add(L"count", count);\r
+\r
+                       total_pooled_device_buffer_size += size * count;\r
+                       total_pooled_device_buffer_count += count;\r
+\r
+                       pooled_device_buffers.add_child(L"device_buffer_pool", pool_info);\r
+               }\r
+       }\r
+\r
+       info.add_child(L"gl.details.pooled_device_buffers", pooled_device_buffers);\r
+\r
+       boost::property_tree::wptree pooled_host_buffers;\r
+       size_t total_read_size = 0;\r
+       size_t total_write_size = 0;\r
+       size_t total_read_count = 0;\r
+       size_t total_write_count = 0;\r
+\r
+       for (size_t i = 0; i < host_pools_.size(); ++i)\r
+       {\r
+               auto& pools = host_pools_.at(i);\r
+               host_buffer::usage_t usage = static_cast<host_buffer::usage_t>(i);\r
+\r
+               BOOST_FOREACH(auto& pool, pools)\r
+               {\r
+                       auto size = pool.first;\r
+                       auto count = pool.second->items.size();\r
+\r
+                       if (count == 0)\r
+                               continue;\r
+\r
+                       boost::property_tree::wptree pool_info;\r
+\r
+                       pool_info.add(L"usage", usage == host_buffer::read_only\r
+                               ? L"read_only" : L"write_only");\r
+                       pool_info.add(L"size", size);\r
+                       pool_info.add(L"count", count);\r
+\r
+                       pooled_host_buffers.add_child(L"host_buffer_pool", pool_info);\r
+\r
+                       (usage == host_buffer::read_only\r
+                                       ? total_read_count : total_write_count) += count;\r
+                       (usage == host_buffer::read_only\r
+                                       ? total_read_size : total_write_size) += size * count;\r
+               }\r
+       }\r
+\r
+       info.add_child(L"gl.details.pooled_host_buffers", pooled_host_buffers);\r
+\r
+       info.add(L"gl.summary.pooled_device_buffers.total_count", total_pooled_device_buffer_count);\r
+       info.add(L"gl.summary.pooled_device_buffers.total_size", total_pooled_device_buffer_size);\r
+       info.add_child(L"gl.summary.all_device_buffers", device_buffer::info());\r
+       info.add(L"gl.summary.pooled_host_buffers.total_read_count", total_read_count);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_write_count", total_write_count);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_read_size", total_read_size);\r
+       info.add(L"gl.summary.pooled_host_buffers.total_write_size", total_write_size);\r
+       info.add_child(L"gl.summary.all_host_buffers", host_buffer::info());\r
+\r
+       return info;\r
+}\r
+\r
 boost::unique_future<void> ogl_device::gc()\r
 {      \r
        return begin_invoke([=]\r
@@ -336,6 +426,12 @@ void ogl_device::attach(device_buffer& texture)
 {      \r
        if(attached_texture_ != texture.id())\r
        {\r
+               if(attached_fbo_ != fbo_)\r
+               {\r
+                       glBindFramebuffer(GL_FRAMEBUFFER, fbo_);\r
+                       attached_fbo_ = fbo_;\r
+               }\r
+\r
                GL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, texture.id(), 0));\r
                attached_texture_ = texture.id();\r
        }\r
@@ -349,10 +445,10 @@ void ogl_device::clear(device_buffer& texture)
 \r
 void ogl_device::read_buffer(device_buffer&)\r
 {\r
-       if(read_buffer_ != GL_COLOR_ATTACHMENT0_EXT)\r
+       if(read_buffer_ != GL_COLOR_ATTACHMENT0)\r
        {\r
-               GL(glReadBuffer(GL_COLOR_ATTACHMENT0_EXT));\r
-               read_buffer_ = GL_COLOR_ATTACHMENT0_EXT;\r
+               GL(glReadBuffer(GL_COLOR_ATTACHMENT0));\r
+               read_buffer_ = GL_COLOR_ATTACHMENT0;\r
        }\r
 }\r
 \r