Warning messagebox for windows when an unsupported implementation of

OpenGL is detected:

Hoping to decrease the frequency of by far one of the most frequent bug
reports by windows users.

There is some reorganization of the GHOST API to allow easy addition of
further OpenGL options in the future. The change is not propagated too
deep to keep the size of the patch managable. We might reorganize things
here later.

For OpenGL we do two checks here:
One is a combination of GDI generic renderer or vendor microsoft
corporation and OpenGL version 1.1. This means the system does not
use GPU acceleration at all. We warn user to install a graphics
driver and of cases where this might happen (remote connection, using
blender through virtual machine)

The other one just checks if OpenGL version is less than 1.4 (we can
easily change that in the future of course) and warns that it is
deprecated.

Both cases will still let blender startup correctly but users should now
have a clear idea of the system being unsupported.

A user preference flag is provided to turn the warning off.

Now stop posting those bug reports without installing a driver first -
please?
This commit is contained in:
Antonis Ryakiotakis 2015-02-25 13:51:53 +01:00
parent 1da5e8df6f
commit b5b359b48f
Notes: blender-bot 2023-02-14 08:06:38 +01:00
Referenced by commit e95732bced, Fix broken "force setting multisamples only once", introduced in b5b359b48f
24 changed files with 128 additions and 63 deletions

View File

@ -186,8 +186,7 @@ extern GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const int stereoVisual,
const GHOST_TUns16 numOfAASamples);
GHOST_GLSettings glSettings);
/**
* Returns the window user data.

View File

@ -250,9 +250,8 @@ public:
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
const bool stereoVisual = false,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0) = 0;
/**

View File

@ -50,6 +50,17 @@ typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
typedef struct {
GHOST_TUns16 numOfAASamples;
int flags;
} GHOST_GLSettings;
typedef enum {
GHOST_glStereoVisual = 0,
GHOST_glWarnSupport
} GHOST_GLFlags;
#ifdef _MSC_VER
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;

View File

@ -140,14 +140,12 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const int stereoVisual,
const GHOST_TUns16 numOfAASamples)
GHOST_GLSettings glSettings)
{
GHOST_ISystem *system = (GHOST_ISystem *) systemhandle;
return (GHOST_WindowHandle) system->createWindow(title, left, top, width, height,
state, type, stereoVisual != 0, false,
numOfAASamples);
state, type, glSettings, false);
}
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)

View File

@ -48,6 +48,7 @@ HGLRC GHOST_ContextWGL::s_sharedHGLRC = NULL;
int GHOST_ContextWGL::s_sharedCount = 0;
bool GHOST_ContextWGL::s_singleContextMode = false;
bool GHOST_ContextWGL::s_warn_old = false;
/* Intel video-cards don't work fine with multiple contexts and
@ -863,12 +864,39 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
initClearGL();
::SwapBuffers(m_hDC);
const char *vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
const char *renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
const char *version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
#ifndef NDEBUG
reportContextString("Vendor", m_dummyVendor, reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
reportContextString("Renderer", m_dummyRenderer, reinterpret_cast<const char*>(glGetString(GL_RENDERER)));
reportContextString("Version", m_dummyVersion, reinterpret_cast<const char*>(glGetString(GL_VERSION)));
reportContextString("Vendor", m_dummyVendor, vendor);
reportContextString("Renderer", m_dummyRenderer, renderer);
reportContextString("Version", m_dummyVersion, version);
#endif
if (!s_warn_old) {
if ((strcmp(vendor, "Microsoft Corporation") == 0 ||
strcmp(renderer, "GDI Generic") == 0) && version[0] == '1' && version[0] == '1')
{
MessageBox(m_hWnd, "Your system does not use GPU acceleration.\n"
"Such systems can cause stability problems in blender and they are unsupported.\n\n"
"This may is caused by:\n"
"* A missing or faulty graphics driver installation.\n"
" Blender needs a graphics card driver to work correctly.\n"
"* Accessing blender through a remote connection.\n"
"* Using blender through a virtual machine.\n\n"
"Disable this message in <User Preferences - Interface - Warn On Deprecated OpenGL>",
"Blender - Can't detect GPU accelerated Driver!", MB_OK | MB_ICONWARNING);
}
else if (version[0] == '1' && version[2] < '4') {
MessageBox(m_hWnd, "The OpenGL version provided by your graphics driver version is too low\n"
"Blender requires version 1.4 and may not work correctly\n\n"
"Disable this message in <User Preferences - Interface - Warn On Deprecated OpenGL>",
"Blender - Unsupported Graphics Driver!", MB_OK | MB_ICONWARNING);
}
s_warn_old = true;
}
return GHOST_kSuccess;
error:

View File

@ -118,6 +118,8 @@ public:
*/
GHOST_TSuccess getSwapInterval(int &intervalOut);
static void unSetWarningOld(){s_warn_old = true;}
protected:
inline void activateWGLEW() const {
#ifdef WITH_GLEW_MX
@ -183,6 +185,7 @@ private:
static int s_sharedCount;
static bool s_singleContextMode;
static bool s_warn_old;
};
#endif // __GHOST_CONTEXTWGL_H__

View File

@ -350,6 +350,12 @@ GHOST_TSuccess GHOST_System::exit()
GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings,
const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
{
GHOST_GLSettings glSettings = {0};
if (stereoVisual)
glSettings.flags |= GHOST_glStereoVisual;
glSettings.numOfAASamples = numOfAASamples;
/* note: don't use getCurrentDisplaySetting() because on X11 we may
* be zoomed in and the desktop may be bigger then the viewport. */
GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager");
@ -359,9 +365,8 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const
0, 0, settings.xPixels, settings.yPixels,
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
stereoVisual,
true, /* exclusive */
numOfAASamples);
glSettings,
true /* exclusive */);
return (*window == NULL) ? GHOST_kFailure : GHOST_kSuccess;
}

View File

@ -118,9 +118,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual = false,
const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const GHOST_TEmbedderWindowID parentWindow = 0
);

View File

@ -530,9 +530,8 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
@ -551,7 +550,7 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
// Add contentRect.origin.y to respect docksize
bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, stereoVisual, numOfAASamples);
window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), glSettings.numOfAASamples);
if (window->getValid()) {
// Store the pointer to the window

View File

@ -75,12 +75,12 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool stereoVisual,
GHOST_GLSettings glSettings,
bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
return new GHOST_WindowNULL(this, title, left, top, width, height, state, parentWindow, type,
((glSettings.flags & GHOST_glStereoVisual) != 0), 1);
}
};

View File

@ -67,19 +67,20 @@ GHOST_SystemSDL::createWindow(const STR_String& title,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
GHOST_WindowSDL *window = NULL;
(void) warnOld;
window = new GHOST_WindowSDL(this, title,
left, top, width, height,
state, parentWindow, type,
stereoVisual, exclusive,
numOfAASamples);
((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
glSettings.numOfAASamples);
if (window) {
if (GHOST_kWindowStateFullScreen == state) {

View File

@ -108,9 +108,8 @@ private:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);

View File

@ -231,9 +231,8 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
GHOST_TInt32 left, GHOST_TInt32 top,
GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
bool wantStereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive,
const GHOST_TUns16 wantNumOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
GHOST_Window *window =
@ -246,8 +245,9 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
height,
state,
type,
wantStereoVisual,
wantNumOfAASamples,
((glSettings.flags & GHOST_glStereoVisual) != 0),
((glSettings.flags & GHOST_glWarnSupport) != 0),
glSettings.numOfAASamples,
parentWindow);
if (window->getValid()) {

View File

@ -125,9 +125,8 @@ public:
const STR_String& title,
GHOST_TInt32 left, GHOST_TInt32 top, GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state, GHOST_TDrawingContextType type,
const bool stereoVisual = false,
const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const GHOST_TEmbedderWindowID parentWindow = 0);
/***************************************************************************************

View File

@ -289,31 +289,26 @@ getAllDisplayDimensions(
*/
GHOST_IWindow *
GHOST_SystemX11::
createWindow(
const STR_String& title,
createWindow(const STR_String& title,
GHOST_TInt32 left,
GHOST_TInt32 top,
GHOST_TUns32 width,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow)
{
GHOST_WindowX11 *window = 0;
if (!m_display) return 0;
window = new GHOST_WindowX11(this, m_display, title,
left, top, width, height,
state, parentWindow, type,
stereoVisual, exclusive,
numOfAASamples);
((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive,
glSettings.numOfAASamples);
if (window) {
/* Both are now handle in GHOST_WindowX11.cpp

View File

@ -151,9 +151,8 @@ public:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
const bool stereoVisual,
GHOST_GLSettings glSettings,
const bool exclusive = false,
const GHOST_TUns16 numOfAASamples = 0,
const GHOST_TEmbedderWindowID parentWindow = 0
);

View File

@ -62,8 +62,7 @@ extern "C" {
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
GHOST_WindowWin32::GHOST_WindowWin32(
GHOST_SystemWin32 *system,
GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
const STR_String &title,
GHOST_TInt32 left,
GHOST_TInt32 top,
@ -71,7 +70,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
bool wantStereoVisual,
bool wantStereoVisual, bool warnOld,
GHOST_TUns16 wantNumOfAASamples,
GHOST_TEmbedderWindowID parentwindowhwnd)
: GHOST_Window(width, height, state,
@ -97,6 +96,13 @@ GHOST_WindowWin32::GHOST_WindowWin32(
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
#if !defined(WITH_GL_EGL)
if (!warnOld)
GHOST_ContextWGL::unSetWarningOld();
#else
(void)(warnOld);
#endif
if (!GetVersionEx((OSVERSIONINFO *)&versionInfo)) {
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO *)&versionInfo)) {

View File

@ -90,6 +90,7 @@ public:
GHOST_TWindowState state,
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
bool wantStereoVisual = false,
bool warnOld = false,
GHOST_TUns16 wantNumOfAASamples = 0,
GHOST_TEmbedderWindowID parentWindowHwnd = 0
);

View File

@ -170,6 +170,12 @@ class USERPREF_PT_interface(Panel):
sub.prop(view, "mini_axis_brightness", text="Brightness")
col.separator()
if sys.platform[:3] == "win":
col.label("Warnings")
col.prop(view, "use_quit_dialog")
col.prop(view, "use_gl_warn_support")
row.separator()
row.separator()
@ -238,9 +244,6 @@ class USERPREF_PT_interface(Panel):
col.prop(view, "show_splash")
if sys.platform[:3] == "win":
col.prop(view, "use_quit_dialog")
class USERPREF_PT_edit(Panel):
bl_space_type = 'USER_PREFERENCES'

View File

@ -667,9 +667,10 @@ typedef enum eUserpref_UI_Flag {
/* uiflag2 */
typedef enum eUserpref_UI_Flag2 {
USER_KEEP_SESSION = (1 << 0),
USER_REGION_OVERLAP = (1 << 1),
USER_TRACKPAD_NATURAL = (1 << 2)
USER_KEEP_SESSION = (1 << 0),
USER_REGION_OVERLAP = (1 << 1),
USER_TRACKPAD_NATURAL = (1 << 2),
USER_OPENGL_NO_WARN_SUPPORT = (1 << 3)
} eUserpref_UI_Flag2;
/* Auto-Keying mode */

View File

@ -3338,6 +3338,11 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Prompt Quit",
"Asks for confirmation when quitting through the window close button");
prop = RNA_def_property(srna, "use_gl_warn_support", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag2", USER_OPENGL_NO_WARN_SUPPORT);
RNA_def_property_ui_text(prop, "Warn On Deprecated OpenGL",
"Pops up a warning when an old OpenGL version is detected");
/* Toolbox click-hold delay */
prop = RNA_def_property(srna, "open_left_mouse_delay", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "tb_leftmouse");

View File

@ -848,6 +848,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
{
GHOST_GLSettings glsettings = {0};
GHOST_TUns32 scr_w, scr_h;
GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &scr_w, &scr_h);
@ -860,7 +861,7 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
/* could optionally start fullscreen */
GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL,
false /* no stereo */, false);
glsettings);
}
static void playanim_window_zoom(PlayState *ps, const float zoom_offset)

View File

@ -356,14 +356,18 @@ float wm_window_pixelsize(wmWindow *win)
static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wmWindow *win)
{
GHOST_WindowHandle ghostwin;
GHOST_GLSettings glSettings = {0};
static int multisamples = -1;
int scr_w, scr_h, posy;
/* force setting multisamples only once, it requires restart - and you cannot
* mix it, either all windows have it, or none (tested in OSX opengl) */
if (multisamples == -1)
multisamples = U.ogl_multisamples;
glSettings.numOfAASamples = U.ogl_multisamples;
if (!(U.uiflag2 & USER_OPENGL_NO_WARN_SUPPORT))
glSettings.flags |= GHOST_glWarnSupport;
wm_get_screensize(&scr_w, &scr_h);
posy = (scr_h - win->posy - win->sizey);
@ -371,8 +375,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wm
win->posx, posy, win->sizex, win->sizey,
(GHOST_TWindowState)win->windowstate,
GHOST_kDrawingContextTypeOpenGL,
0 /* no stereo */,
multisamples /* AA */);
glSettings);
if (ghostwin) {
GHOST_RectangleHandle bounds;

View File

@ -323,11 +323,16 @@ bool GPG_Application::startWindow(
const int stereoMode,
const GHOST_TUns16 samples)
{
GHOST_GLSettings glSettings = {0};
bool success;
// Create the main window
//STR_String title ("Blender Player - GHOST");
if (stereoVisual)
glSettings.flags |= GHOST_glStereoVisual;
glSettings.numOfAASamples = samples;
m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples);
GHOST_kDrawingContextTypeOpenGL, glSettings);
if (!m_mainWindow) {
printf("error: could not create main window\n");
exit(-1);
@ -354,10 +359,16 @@ bool GPG_Application::startEmbeddedWindow(
const GHOST_TUns16 samples)
{
GHOST_TWindowState state = GHOST_kWindowStateNormal;
GHOST_GLSettings glSettings = {0};
if (stereoVisual)
glSettings.flags |= GHOST_glStereoVisual;
glSettings.numOfAASamples = samples;
if (parentWindow != 0)
state = GHOST_kWindowStateEmbedded;
m_mainWindow = fSystem->createWindow(title, 0, 0, 0, 0, state,
GHOST_kDrawingContextTypeOpenGL, stereoVisual, false, samples, parentWindow);
GHOST_kDrawingContextTypeOpenGL, glSettings, parentWindow);
if (!m_mainWindow) {
printf("error: could not create main window\n");