Fix OPENGL_GAL initialization sequence (Version for 5.1)

- New public static function OPENGL_GAL::CheckFeatures() gets called in EDA_DRAW_PANEL_GAL::SwitchBackend() before switching to OPENGL_GAL
- Moved all OpenGL feature checks from OPENGL_GAL constructor to OPENGL_GAL::init()

Fixes https://gitlab.com/kicad/code/kicad/-/issues/4714
This commit is contained in:
Roberto Fernandez Bautista 2020-10-29 19:50:00 +00:00
parent 73bf4cbce7
commit 24a4f06013
3 changed files with 64 additions and 23 deletions

View File

@ -379,21 +379,23 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
switch( aGalType )
{
case GAL_TYPE_OPENGL:
try
{
wxString errormsg = KIGFX::OPENGL_GAL::CheckFeatures( m_options );
if( errormsg.empty() )
{
new_gal = new KIGFX::OPENGL_GAL( m_options, this, this, this );
break;
}
catch( std::runtime_error& err )
else
{
aGalType = GAL_TYPE_CAIRO;
DisplayInfoMessage( m_parent,
_( "Could not use OpenGL, falling back to software rendering" ),
wxString( err.what() ) );
_( "Could not use OpenGL, falling back to software rendering" ), errormsg );
new_gal = new KIGFX::CAIRO_GAL( m_options, this, this, this );
}
new_gal = new KIGFX::CAIRO_GAL( m_options, this, this, this );
break;
}
case GAL_TYPE_CAIRO:
new_gal = new KIGFX::CAIRO_GAL( m_options, this, this, this );

View File

@ -198,30 +198,16 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
isContextLocked( false ),
lockClientCookie( 0 )
{
// IsDisplayAttr() handles WX_GL_{MAJOR,MINOR}_VERSION correctly only in 3.0.4
// starting with 3.1.0 one should use wxGLContext::IsOk() (done by GL_CONTEXT_MANAGER)
#if wxCHECK_VERSION( 3, 0, 3 ) and !wxCHECK_VERSION( 3, 1, 0 )
const int attr[] = { WX_GL_MAJOR_VERSION, 2, WX_GL_MINOR_VERSION, 1, 0 };
if( !IsDisplaySupported( attr ) )
throw std::runtime_error( "OpenGL 2.1 or higher is required!" );
#endif /* wxCHECK_VERSION( 3, 0, 3 ) */
if( glMainContext == NULL )
{
glMainContext = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
if( !glMainContext )
throw std::runtime_error( "Could not create the main OpenGL context" );
glPrivContext = glMainContext;
}
else
{
glPrivContext = GL_CONTEXT_MANAGER::Get().CreateCtx( this, glMainContext );
if( !glPrivContext )
throw std::runtime_error( "Could not create a private OpenGL context" );
}
shader = new SHADER();
@ -272,9 +258,6 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
tesselator = gluNewTess();
InitTesselatorCallbacks( tesselator );
if( tesselator == NULL )
throw std::runtime_error( "Could not create the tesselator" );
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
SetTarget( TARGET_NONCACHED );
@ -336,6 +319,35 @@ void OPENGL_GAL::PostPaint( wxPaintEvent& aEvent )
}
wxString OPENGL_GAL::CheckFeatures( GAL_DISPLAY_OPTIONS& aOptions )
{
wxFrame* testFrame = new wxFrame( NULL, wxID_ANY, wxT( "" ), wxDefaultPosition, wxSize( 1, 1 ),
wxFRAME_TOOL_WINDOW | wxNO_BORDER );
KIGFX::OPENGL_GAL* opengl_gal = new KIGFX::OPENGL_GAL( aOptions, testFrame );
testFrame->Raise();
testFrame->Show();
try
{
GAL_CONTEXT_LOCKER lock( opengl_gal );
opengl_gal->init();
}
catch( std::runtime_error& err )
{
//Test failed
delete opengl_gal;
delete testFrame;
return wxString( err.what() );
}
//Test passed
delete opengl_gal;
delete testFrame;
return wxEmptyString;
}
bool OPENGL_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
{
bool refresh = false;
@ -1990,6 +2002,26 @@ void OPENGL_GAL::init()
wxASSERT_MSG( isContextLocked, "This should only be called from within a locked context." );
// IsDisplayAttr() handles WX_GL_{MAJOR,MINOR}_VERSION correctly only in 3.0.4
// starting with 3.1.0 one should use wxGLContext::IsOk() (done by GL_CONTEXT_MANAGER)
#if wxCHECK_VERSION( 3, 0, 3 ) and !wxCHECK_VERSION( 3, 1, 0 )
const int attr[] = { WX_GL_MAJOR_VERSION, 2, WX_GL_MINOR_VERSION, 1, 0 };
if( !IsDisplaySupported( attr ) )
throw std::runtime_error( "OpenGL 2.1 or higher is required!" );
#endif /* wxCHECK_VERSION( 3, 0, 3 ) */
// Check correct initialization from the constructor
if( !glMainContext )
throw std::runtime_error( "Could not create the main OpenGL context" );
if( !glPrivContext )
throw std::runtime_error( "Could not create a private OpenGL context" );
if( tesselator == NULL )
throw std::runtime_error( "Could not create the tesselator" );
// End initialzation checks
GLenum err = glewInit();
if( GLEW_OK != err )

View File

@ -86,6 +86,13 @@ public:
virtual ~OPENGL_GAL();
/**
* @brief Checks OpenGL features
* @param aOptions
* @return wxEmptyString if OpenGL 2.1 or greater is available, otherwise returns error message
*/
static wxString CheckFeatures( GAL_DISPLAY_OPTIONS& aOptions );
virtual bool IsOpenGlEngine() override { return true; }
/// @copydoc GAL::IsInitialized()