NEW: add config: prefer_to_use_dgpu

jira: STUDIO-10068 / STUDIO-9387

Change-Id: I78fe0e865e9665bbf3669e4834a39af624cde29e
(cherry picked from commit cc41c008548b4dc2874333afd63ef0035070cda5)
This commit is contained in:
jun.zhang 2025-02-08 16:23:31 +08:00 committed by lane.wei
parent c16d43ce31
commit 2353d0366d
12 changed files with 356 additions and 240 deletions

View File

@ -14,8 +14,8 @@ extern "C"
{
// Let the NVIDIA and AMD know we want to use their graphics card
// on a dual graphics card system.
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000000;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0;
}
#endif /* SLIC3R_GUI */
@ -34,174 +34,6 @@ extern "C"
#include <stdio.h>
#ifdef SLIC3R_GUI
class OpenGLVersionCheck
{
public:
std::string version;
std::string glsl_version;
std::string vendor;
std::string renderer;
HINSTANCE hOpenGL = nullptr;
bool success = false;
bool load_opengl_dll()
{
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc;
wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"BambuStudio_opengl_version_check";
wc.style = CS_OWNDC;
if (RegisterClass(&wc)) {
HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
if (hwnd) {
message_pump_exit = false;
while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
DispatchMessage(&msg);
}
}
return this->success;
}
void unload_opengl_dll()
{
if (this->hOpenGL) {
BOOL released = FreeLibrary(this->hOpenGL);
if (released)
printf("System OpenGL library released\n");
else
printf("System OpenGL library NOT released\n");
this->hOpenGL = nullptr;
}
}
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
std::vector<std::string> tokens;
boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
if (tokens.empty())
return false;
std::vector<std::string> numbers;
boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
unsigned int gl_major = 0;
unsigned int gl_minor = 0;
if (numbers.size() > 0)
gl_major = ::atoi(numbers[0].c_str());
if (numbers.size() > 1)
gl_minor = ::atoi(numbers[1].c_str());
// printf("Major: %d, minor: %d\n", gl_major, gl_minor);
if (gl_major < major)
return false;
else if (gl_major > major)
return true;
else
return gl_minor >= minor;
}
protected:
static bool message_pump_exit;
void check(HWND hWnd)
{
hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
if (hOpenGL == nullptr) {
printf("Failed loading the system opengl32.dll\n");
return;
}
typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC);
typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC);
typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC);
typedef GLubyte* (WINAPI *Func_glGetString )(GLenum);
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString");
if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
printf("Failed loading the system opengl32.dll: The library is invalid.\n");
return;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
// Gdi32.dll
int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
// Gdi32.dll
SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
// Opengl32.dll
HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
// Opengl32.dll
const char *data = (const char*)glGetString(GL_VERSION);
if (data != nullptr)
this->version = data;
// printf("check -version: %s\n", version.c_str());
data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
if (data != nullptr)
this->glsl_version = data;
data = (const char*)glGetString(GL_VENDOR);
if (data != nullptr)
this->vendor = data;
data = (const char*)glGetString(GL_RENDERER);
if (data != nullptr)
this->renderer = data;
// Opengl32.dll
wglDeleteContext(glcontext);
::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
this->success = true;
}
static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
{
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
ogl_data->check(hWnd);
DestroyWindow(hWnd);
return 0;
}
case WM_NCDESTROY:
message_pump_exit = true;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
};
bool OpenGLVersionCheck::message_pump_exit = false;
#endif /* SLIC3R_GUI */
extern "C" {
typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv);
Slic3rMainFunc bambustu_main = nullptr;
@ -245,15 +77,6 @@ int wmain(int argc, wchar_t **argv)
}
argv_extended.emplace_back(nullptr);
#ifdef SLIC3R_GUI
OpenGLVersionCheck opengl_version_check;
bool load_mesa =
// Forced from the command line.
force_mesa ||
// Try to load the default OpenGL driver and test its context version.
! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0);
#endif /* SLIC3R_GUI */
wchar_t path_to_exe[MAX_PATH + 1] = { 0 };
::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
wchar_t drive[_MAX_DRIVE];
@ -263,24 +86,6 @@ int wmain(int argc, wchar_t **argv)
_wsplitpath(path_to_exe, drive, dir, fname, ext);
_wmakepath(path_to_exe, drive, dir, nullptr, nullptr);
#ifdef SLIC3R_GUI
// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
if (load_mesa) {
opengl_version_check.unload_opengl_dll();
wchar_t path_to_mesa[MAX_PATH + 1] = { 0 };
wcscpy(path_to_mesa, path_to_exe);
wcscat(path_to_mesa, L"mesa\\opengl32.dll");
printf("Loading MESA OpenGL library: %S\n", path_to_mesa);
HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
if (hInstance_OpenGL == nullptr) {
printf("MESA OpenGL library was not loaded\n");
} else
printf("MESA OpenGL library was loaded sucessfully\n");
}
#endif /* SLIC3R_GUI */
wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 };
wcscpy(path_to_slic3r, path_to_exe);
wcscat(path_to_slic3r, L"BambuStudio.dll");

View File

@ -196,6 +196,9 @@ void AppConfig::set_defaults()
if (get("enable_multi_machine").empty())
set_bool("enable_multi_machine", false);
if (get("prefer_to_use_dgpu").empty())
set_bool("prefer_to_use_dgpu", true);
if (get("show_3d_navigator").empty())
set_bool("show_3d_navigator", true);

View File

@ -12,6 +12,8 @@
//BBS: add convex hull logic for toolpath check
#include "libslic3r/Geometry/ConvexHull.hpp"
#include "slic3r/GUI/OpenGLManager.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "Plater.hpp"

View File

@ -2050,7 +2050,12 @@ void GLCanvas3D::render(bool only_init)
glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top));
const std::array<int, 4>& viewport = camera.get_viewport();
auto& ogl_manager = wxGetApp().get_opengl_manager();
const auto& p_ogl_manager = wxGetApp().get_opengl_manager();
if (!p_ogl_manager) {
return;
}
auto& ogl_manager = *p_ogl_manager;
ogl_manager.set_viewport_size(viewport[2], viewport[3]);
ogl_manager.bind_vao();
@ -2267,11 +2272,14 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data,
bool for_picking,
bool ban_light)
{
auto& ogl_manager = wxGetApp().get_opengl_manager();
ogl_manager.bind_vao();
const auto& ogl_manager = wxGetApp().get_opengl_manager();
if (!ogl_manager) {
return;
}
ogl_manager->bind_vao();
ModelObjectPtrs &model_objects = GUI::wxGetApp().model().objects;
render_thumbnail(thumbnail_data, w, h, thumbnail_params, model_objects, m_volumes, camera_type, camera_view_angle_type, for_picking, ban_light);
ogl_manager.unbind_vao();
ogl_manager->unbind_vao();
}
void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data,
@ -2347,8 +2355,12 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_d
void GLCanvas3D::render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params)
{
//load current plate gcode
const auto& p_ogl_manager = wxGetApp().get_opengl_manager();
if (!p_ogl_manager) {
return;
}
m_gcode_viewer.render_calibration_thumbnail(thumbnail_data, w, h, thumbnail_params,
wxGetApp().plater()->get_partplate_list(), wxGetApp().get_opengl_manager());
wxGetApp().plater()->get_partplate_list(), *p_ogl_manager);
}
//BBS
@ -9916,8 +9928,12 @@ void GLCanvas3D::_render_silhouette_effect()
{;
RenderPipelineStageModifier render_pipeline_stage_modifier(*this, ERenderPipelineStage::Silhouette);
auto& ogl_manager = wxGetApp().get_opengl_manager();
const auto& p_ogl_manager = wxGetApp().get_opengl_manager();
if (!p_ogl_manager) {
return;
}
auto& ogl_manager = *p_ogl_manager;
{
// BBS: render silhouette
OpenGLManager::FrameBufferModifier frame_buffer_modifier(ogl_manager, "silhouette");

View File

@ -5,6 +5,7 @@
#include "GUI_Factories.hpp"
#include "slic3r/GUI/UserManager.hpp"
#include "slic3r/GUI/TaskManager.hpp"
#include "slic3r/GUI/OpenGLManager.hpp"
#include "format.hpp"
// Localization headers: include libslic3r version first so everything in this file
@ -2254,17 +2255,25 @@ std::string GUI_App::get_gl_info(bool for_github)
wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas)
{
return m_opengl_mgr.init_glcontext(canvas);
const auto& p_ogl_manager = get_opengl_manager();
if (!p_ogl_manager) {
return nullptr;
}
return p_ogl_manager->init_glcontext(canvas);
}
bool GUI_App::init_opengl()
{
const auto& p_ogl_mananager = get_opengl_manager();
if (!p_ogl_mananager) {
return false;
}
#ifdef __linux__
bool status = m_opengl_mgr.init_gl();
bool status = p_ogl_mananager->init_gl();
m_opengl_initialized = true;
return status;
#else
return m_opengl_mgr.init_gl();
return p_ogl_mananager->init_gl();
#endif
}
@ -5597,6 +5606,16 @@ static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguage
}
#endif
bool GUI_App::is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
return OpenGLManager::get_gl_info().is_version_greater_or_equal_to(major, minor);
}
bool GUI_App::is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
return OpenGLManager::get_gl_info().is_glsl_version_greater_or_equal_to(major, minor);
}
int GUI_App::GetSingleChoiceIndex(const wxString& message,
const wxString& caption,
const wxArrayString& choices,
@ -7037,6 +7056,45 @@ void GUI_App::gcode_thumbnails_debug()
}
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG
const std::shared_ptr<OpenGLManager>& GUI_App::get_opengl_manager() const
{
if (m_p_opengl_mgr) {
return m_p_opengl_mgr;
}
bool prefer_to_use_dgpu = false;
#ifdef __WIN32__
prefer_to_use_dgpu = app_config->get_bool("prefer_to_use_dgpu");
#endif // __WIN32__
const bool rt = OpenGLManager::init(prefer_to_use_dgpu);
if (rt)
{
m_p_opengl_mgr = std::make_shared<OpenGLManager>();
return m_p_opengl_mgr;
}
static std::shared_ptr<OpenGLManager> s_empty{nullptr};
return s_empty;
}
GLShaderProgram* GUI_App::get_shader(const std::string &shader_name) const
{
const auto& p_ogl_manager = get_opengl_manager();
if (p_ogl_manager) {
return p_ogl_manager->get_shader(shader_name);
}
return nullptr;
}
GLShaderProgram* GUI_App::get_current_shader() const
{
const auto& p_ogl_manager = get_opengl_manager();
if (p_ogl_manager) {
return p_ogl_manager->get_current_shader();
}
return nullptr;
}
void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name)
{
if (name.empty()) { return; }

View File

@ -5,7 +5,6 @@
#include <string>
#include "ImGuiWrapper.hpp"
#include "ConfigWizard.hpp"
#include "OpenGLManager.hpp"
#include "libslic3r/Preset.hpp"
#include "libslic3r/PresetBundle.hpp"
#include "libslic3r/Color.hpp"
@ -49,6 +48,8 @@ class wxMenuBar;
class wxTopLevelWindow;
class wxDataViewCtrl;
class wxBookCtrlBase;
class wxGLContext;
class wxGLCanvas;
// BBS
class Notebook;
struct wxLanguageInfo;
@ -83,7 +84,7 @@ class HMSQuery;
class ModelMallDialog;
class PingCodeBindDialog;
class NetworkErrorDialog;
class OpenGLManager;
enum FileType
{
@ -269,7 +270,7 @@ private:
// Best translation language, provided by Windows or OSX, owned by wxWidgets.
const wxLanguageInfo *m_language_info_best = nullptr;
OpenGLManager m_opengl_mgr;
mutable std::shared_ptr<OpenGLManager> m_p_opengl_mgr{ nullptr };
std::unique_ptr<RemovableDriveManager> m_removable_drive_manager;
std::unique_ptr<ImGuiWrapper> m_imgui;
@ -636,12 +637,12 @@ public:
void gcode_thumbnails_debug();
#endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG
OpenGLManager& get_opengl_manager() { return m_opengl_mgr; }
GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); }
GLShaderProgram* get_current_shader() { return m_opengl_mgr.get_current_shader(); }
const std::shared_ptr<OpenGLManager>& get_opengl_manager() const;
GLShaderProgram* get_shader(const std::string &shader_name) const;
GLShaderProgram* get_current_shader() const;
bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); }
bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); }
bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
int GetSingleChoiceIndex(const wxString& message, const wxString& caption, const wxArrayString& choices, int initialSelection);
#ifdef __WXMSW__

View File

@ -2711,7 +2711,10 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
const GLboolean was_scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST);
GLboolean was_texture2d_enabled = GL_FALSE;
const auto& ogl_manager = wxGetApp().get_opengl_manager();
const auto& gl_info = ogl_manager.get_gl_info();
if (!ogl_manager) {
return;
}
const auto& gl_info = ogl_manager->get_gl_info();
const auto formated_gl_version = gl_info.get_formated_gl_version();
if (formated_gl_version < 30) {
was_texture2d_enabled = glIsEnabled(GL_TEXTURE_2D);

View File

@ -23,6 +23,178 @@
#include "../Utils/MacDarkMode.hpp"
#endif // __APPLE__
#ifdef __WIN32__
#ifdef SLIC3R_GUI
class OpenGLVersionCheck
{
public:
std::string version;
std::string glsl_version;
std::string vendor;
std::string renderer;
HINSTANCE hOpenGL = nullptr;
bool success = false;
bool load_opengl_dll()
{
MSG msg = {0};
WNDCLASS wc = {0};
wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc;
wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr);
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"BambuStudio_opengl_version_check";
wc.style = CS_OWNDC;
if (RegisterClass(&wc)) {
HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this);
if (hwnd) {
message_pump_exit = false;
while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit)
DispatchMessage(&msg);
}
}
return this->success;
}
void unload_opengl_dll()
{
if (this->hOpenGL) {
BOOL released = FreeLibrary(this->hOpenGL);
if (released)
printf("System OpenGL library released\n");
else
printf("System OpenGL library NOT released\n");
this->hOpenGL = nullptr;
}
}
bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
{
// printf("is_version_greater_or_equal_to, version: %s\n", version.c_str());
std::vector<std::string> tokens;
boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
if (tokens.empty())
return false;
std::vector<std::string> numbers;
boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
unsigned int gl_major = 0;
unsigned int gl_minor = 0;
if (numbers.size() > 0)
gl_major = ::atoi(numbers[0].c_str());
if (numbers.size() > 1)
gl_minor = ::atoi(numbers[1].c_str());
// printf("Major: %d, minor: %d\n", gl_major, gl_minor);
if (gl_major < major)
return false;
else if (gl_major > major)
return true;
else
return gl_minor >= minor;
}
protected:
static bool message_pump_exit;
void check(HWND hWnd)
{
hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0);
if (hOpenGL == nullptr) {
printf("Failed loading the system opengl32.dll\n");
return;
}
typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC);
typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC);
typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC);
typedef GLubyte* (WINAPI *Func_glGetString )(GLenum);
Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext");
Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent");
Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext");
Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString");
if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) {
printf("Failed loading the system opengl32.dll: The library is invalid.\n");
return;
}
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette.
32, // Color depth of the framebuffer.
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24, // Number of bits for the depthbuffer
8, // Number of bits for the stencilbuffer
0, // Number of Aux buffers in the framebuffer.
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd);
// Gdi32.dll
int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd);
// Gdi32.dll
SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd);
// Opengl32.dll
HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext);
wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext);
// Opengl32.dll
const char *data = (const char*)glGetString(GL_VERSION);
if (data != nullptr)
this->version = data;
// printf("check -version: %s\n", version.c_str());
data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION
if (data != nullptr)
this->glsl_version = data;
data = (const char*)glGetString(GL_VENDOR);
if (data != nullptr)
this->vendor = data;
data = (const char*)glGetString(GL_RENDERER);
if (data != nullptr)
this->renderer = data;
// Opengl32.dll
wglDeleteContext(glcontext);
::ReleaseDC(hWnd, ourWindowHandleToDeviceContext);
this->success = true;
}
static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CREATE:
{
CREATESTRUCT *pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
OpenGLVersionCheck *ogl_data = reinterpret_cast<OpenGLVersionCheck*>(pCreate->lpCreateParams);
ogl_data->check(hWnd);
DestroyWindow(hWnd);
return 0;
}
case WM_NCDESTROY:
message_pump_exit = true;
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
};
bool OpenGLVersionCheck::message_pump_exit = false;
#endif /* SLIC3R_GUI */
#endif // __WIN32__
#define BBS_GL_EXTENSION_FUNC(_func) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _func ## EXT : _func)
#define BBS_GL_EXTENSION_FRAMEBUFFER OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? GL_FRAMEBUFFER_EXT : GL_FRAMEBUFFER
#define BBS_GL_EXTENSION_COLOR_ATTACHMENT(color_attachment) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? color_attachment ## _EXT : color_attachment)
@ -231,12 +403,16 @@ bool OpenGLManager::s_compressed_textures_supported = false;
bool OpenGLManager::m_use_manually_generated_mipmaps = true;
OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown;
OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
bool OpenGLManager::s_b_initialized = false;
#ifdef __APPLE__
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
OpenGLManager::OSInfo OpenGLManager::s_os_info;
#endif // __APPLE__
OpenGLManager::OpenGLManager()
{
}
OpenGLManager::~OpenGLManager()
{
release_vao();
@ -255,6 +431,61 @@ OpenGLManager::~OpenGLManager()
#endif //__APPLE__
}
bool OpenGLManager::init(bool prefer_to_use_dgpu)
{
if (s_b_initialized) {
return true;
}
#ifdef __WIN32__
if (prefer_to_use_dgpu) {
HMODULE hModExe = nullptr;
hModExe = GetModuleHandle(NULL);
if (hModExe) {
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe;
auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement");
auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance");
if (NvOptimusEnablement) {
*NvOptimusEnablement = 0x00000001;
}
if (AmdPowerXpressRequestHighPerformance) {
// BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance;
*AmdPowerXpressRequestHighPerformance = 1;
}
}
}
#ifdef SLIC3R_GUI
bool force_mesa = false;
wchar_t path_to_exe[MAX_PATH + 1] = {0};
::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH);
OpenGLVersionCheck opengl_version_check;
bool load_mesa =
force_mesa ||
// Try to load the default OpenGL driver and test its context version.
!opengl_version_check.load_opengl_dll() || !opengl_version_check.is_version_greater_or_equal_to(2, 0);
// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows
// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/
if (load_mesa) {
opengl_version_check.unload_opengl_dll();
wchar_t path_to_mesa[MAX_PATH + 1] = {0};
wcscpy(path_to_mesa, path_to_exe);
wcscat(path_to_mesa, L"mesa\\opengl32.dll");
BOOST_LOG_TRIVIAL(info) << "Loading MESA OpenGL library: " << path_to_mesa;
HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0);
if (hInstance_OpenGL == nullptr) {
BOOST_LOG_TRIVIAL(error) << "MESA OpenGL library was not loaded";
} else
BOOST_LOG_TRIVIAL(info) << "MESA OpenGL library was loaded sucessfully";
}
#endif /* SLIC3R_GUI */
#endif // __WIN32__
s_b_initialized = true;
return s_b_initialized;
}
bool OpenGLManager::init_gl(bool popup_error)
{
if (!m_gl_initialized) {

View File

@ -141,13 +141,14 @@ private:
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
static OSInfo s_os_info;
#endif //__APPLE__
static bool s_b_initialized;
static bool s_compressed_textures_supported;
static EMultisampleState s_multisample;
static EFramebufferType s_framebuffers_type;
static bool m_use_manually_generated_mipmaps;
public:
OpenGLManager() = default;
OpenGLManager();
~OpenGLManager();
bool init_gl(bool popup_error = true);
@ -165,6 +166,7 @@ public:
void unbind_vao();
void release_vao();
static bool init(bool prefer_to_use_dgpu = false);
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; }
static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }

View File

@ -22,6 +22,7 @@
#include "libslic3r/Tesselate.hpp"
#include "libslic3r/GCode/ThumbnailData.hpp"
#include "libslic3r/Utils.hpp"
#include "slic3r/GUI/OpenGLManager.hpp"
#include "I18N.hpp"
#include "GUI_App.hpp"

View File

@ -846,27 +846,12 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa
}
}
if (param == "enable_opengl_multi_instance") {
if (wxGetApp().plater()->is_project_dirty()) {
auto result = MessageDialog(static_cast<wxWindow *>(this), _L("The current project has unsaved changes, save it before continuing?"),
wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxYES_DEFAULT | wxCENTRE)
.ShowModal();
if (result == wxID_YES) { wxGetApp().plater()->save_project(); }
}
MessageDialog msg_wingow(nullptr,
_L("Change opengl multi instance rendering requires application restart.") + "\n" +
_L("Do you want to continue?"),
_L("Enable opengl multi instance rendering"), wxYES | wxYES_DEFAULT | wxCANCEL | wxCENTRE);
if (msg_wingow.ShowModal() == wxID_YES) {
Close();
GetParent()->RemoveChild(this);
wxGetApp().recreate_GUI(_L("Enable opengl multi instance rendering"));
} else {
checkbox->SetValue(!checkbox->GetValue());
app_config->set_bool(param, checkbox->GetValue());
app_config->save();
}
#ifdef __WIN32__
if (param == "prefer_to_use_dgpu") {
app_config->set_bool(param, checkbox->GetValue());
app_config->save();
}
#endif // __WIN32__
e.Skip();
});
@ -1181,8 +1166,12 @@ wxWindow* PreferencesDialog::create_general_page()
auto enable_lod_settings = create_item_checkbox(_L("Improve rendering performance by lod"), page,
_L("Improved rendering performance under the scene of multiple plates and many models."), 50,
"enable_lod");
auto enable_opengl_multi_instance_rendering = create_item_checkbox(_L("Enable multi instance rendering by opengl"), page,
_L("If enabled, it can improve certain rendering performance. But for some graphics cards, it may not be applicable, please turn it off."), 50, "enable_opengl_multi_instance");
#ifdef __WIN32__
auto prefer_to_use_dgpu = create_item_checkbox(_L("Prefer to use high performance GPU (Effective after manual restart Bambu Studio)"), page,
_L("If enabled, it can improve certain rendering performance. But for some multi-gpu platforms, it may cause flickering, please turn it off."), 50, "prefer_to_use_dgpu");
#endif // __WIN32__
float range_min = 1.0, range_max = 2.5;
auto item_grabber_size_settings = create_item_range_input(_L("Grabber scale"), page,
_L("Set grabber size for move,rotate,scale tool.") + _L("Value range") + ":[" + std::to_string(range_min) + "," +
@ -1279,7 +1268,11 @@ wxWindow* PreferencesDialog::create_general_page()
sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3));
sizer_page->Add(enable_opengl_multi_instance_rendering, 0, wxTOP, FromDIP(3));
#ifdef __WIN32__
sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3));
#endif // __WIN32__
sizer_page->Add(enable_lod_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_grabber_size_settings, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_presets, 0, wxTOP | wxEXPAND, FromDIP(20));

View File

@ -4,6 +4,7 @@
#include "../GUI/DeviceManager.hpp"
#include "../GUI/Jobs/ProgressIndicator.hpp"
#include "../GUI/PartPlate.hpp"
#include "../GUI/OpenGLManager.hpp"
#include "libslic3r/Model.hpp"
#include "../GUI/MsgDialog.hpp"