From 01ba59158df082de5219c37b1406c49fe0e9aa37 Mon Sep 17 00:00:00 2001
From: Enrico Turri <enricoturri@seznam.cz>
Date: Tue, 2 Oct 2018 14:01:22 +0200
Subject: [PATCH] Multisample detection

---
 src/slic3r/GUI/GLCanvas3DManager.cpp | 36 +++++++++++++++++-----------
 src/slic3r/GUI/GLCanvas3DManager.hpp | 12 +++++++++-
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp
index 643171a17..09821f853 100644
--- a/src/slic3r/GUI/GLCanvas3DManager.cpp
+++ b/src/slic3r/GUI/GLCanvas3DManager.cpp
@@ -110,6 +110,8 @@ std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool exten
     return out.str();
 }
 
+GLCanvas3DManager::EMultisampleState GLCanvas3DManager::s_multisample = GLCanvas3DManager::MS_Unknown;
+
 GLCanvas3DManager::GLCanvas3DManager()
     : m_current(nullptr)
     , m_gl_initialized(false)
@@ -827,24 +829,17 @@ void GLCanvas3DManager::register_action_selectbyparts_callback(wxGLCanvas* canva
         it->second->register_action_selectbyparts_callback(callback);
 }
 
-bool GLCanvas3DManager::can_multisample()
-{
-    int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
-    const AppConfig* app_config = GUI::get_app_config();
-    bool enable_multisample = app_config != nullptr
-        && app_config->get("use_legacy_opengl") != "1" 
-        && wxVersion >= 30003;
-
-    // if multisample is not enabled or supported by the graphic card, remove it from the attributes list
-    return enable_multisample && wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample");
-    // <<< Alternative method: but IsDisplaySupported() seems not to work
-    // bool return enable_multisample && wxGLCanvas::IsDisplaySupported(attribList); 
-}
-
 wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent)
 {
     int attribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 24, WX_GL_SAMPLE_BUFFERS, GL_TRUE, WX_GL_SAMPLES, 4, 0 };
 
+    if (s_multisample == MS_Unknown)
+    {
+        _detect_multisample(attribList);
+        // debug output
+        std::cout << "Multisample " << (can_multisample() ? "enabled" : "disabled") << std::endl;
+    }
+
     if (! can_multisample()) {
         attribList[4] = 0;
     }
@@ -870,5 +865,18 @@ bool GLCanvas3DManager::_init(GLCanvas3D& canvas)
     return canvas.init(m_use_VBOs, m_use_legacy_opengl);
 }
 
+void GLCanvas3DManager::_detect_multisample(int* attribList)
+{
+    int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
+    const AppConfig* app_config = GUI::get_app_config();
+    bool enable_multisample = app_config != nullptr
+        && app_config->get("use_legacy_opengl") != "1"
+        && wxVersion >= 30003;
+
+    s_multisample = (enable_multisample && wxGLCanvas::IsDisplaySupported(attribList)) ? MS_Enabled : MS_Disabled;
+    // Alternative method: it was working on previous version of wxWidgets but not with the latest, at least on Windows
+    // s_multisample = enable_multisample && wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample");
+}
+
 } // namespace GUI
 } // namespace Slic3r
diff --git a/src/slic3r/GUI/GLCanvas3DManager.hpp b/src/slic3r/GUI/GLCanvas3DManager.hpp
index c833de397..452584550 100644
--- a/src/slic3r/GUI/GLCanvas3DManager.hpp
+++ b/src/slic3r/GUI/GLCanvas3DManager.hpp
@@ -42,6 +42,13 @@ class GLCanvas3DManager
         std::string to_string(bool format_as_html, bool extensions) const;
     };
 
+    enum EMultisampleState : unsigned char
+    {
+        MS_Unknown,
+        MS_Enabled,
+        MS_Disabled
+    };
+
     typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
 
     CanvasesMap m_canvases;
@@ -50,6 +57,7 @@ class GLCanvas3DManager
     bool m_gl_initialized;
     bool m_use_legacy_opengl;
     bool m_use_VBOs;
+    static EMultisampleState s_multisample;
 
 public:
     GLCanvas3DManager();
@@ -187,13 +195,15 @@ public:
     void register_action_layersediting_callback(wxGLCanvas* canvas, void* callback);
     void register_action_selectbyparts_callback(wxGLCanvas* canvas, void* callback);
 
-    static bool can_multisample();
+    static bool can_multisample() { return s_multisample == MS_Enabled; }
     static wxGLCanvas* create_wxglcanvas(wxWindow *parent);
+
 private:
     CanvasesMap::iterator _get_canvas(wxGLCanvas* canvas);
     CanvasesMap::const_iterator _get_canvas(wxGLCanvas* canvas) const;
 
     bool _init(GLCanvas3D& canvas);
+    static void _detect_multisample(int* attribList);
 };
 
 } // namespace GUI