2016-05-02 13:56:14 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
2017-01-13 15:46:02 +00:00
|
|
|
* Copyright (C) 2016-2017 CERN
|
2021-02-16 22:25:27 +00:00
|
|
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
|
|
|
*
|
2016-05-02 13:56:14 +00:00
|
|
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, you may find one here:
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
|
|
|
* or you may write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
#include <confirm.h> // DisplayError
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
#include <gal/opengl/kiglew.h> // Must be included first
|
2020-11-10 23:24:01 +00:00
|
|
|
|
2017-01-13 16:15:32 +00:00
|
|
|
#include <stdexcept>
|
2021-02-16 22:25:27 +00:00
|
|
|
#include <wx/log.h> // wxLogDebug
|
2020-08-18 14:17:16 +00:00
|
|
|
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-03-22 19:34:33 +00:00
|
|
|
/**
|
|
|
|
* Flag to enable debug output of the GAL OpenGL error checking.
|
|
|
|
*
|
|
|
|
* Use "KICAD_GAL_OPENGL_ERROR" to enable GAL OpenGL error tracing.
|
|
|
|
*
|
|
|
|
* @ingroup trace_env_vars
|
|
|
|
*/
|
|
|
|
static const wxChar* const traceGalOpenGlError = wxT( "KICAD_GAL_OPENGL_ERROR" );
|
|
|
|
|
|
|
|
|
|
|
|
int checkGlError( const std::string& aInfo, const char* aFile, int aLine, bool aThrow )
|
2016-05-02 13:56:14 +00:00
|
|
|
{
|
2021-02-16 22:25:27 +00:00
|
|
|
int result = glGetError();
|
2017-01-13 15:46:02 +00:00
|
|
|
wxString errorMsg;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
|
|
|
switch( result )
|
|
|
|
{
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_NO_ERROR:
|
|
|
|
// all good
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_INVALID_ENUM:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: invalid enum", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_INVALID_VALUE:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: invalid value", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_INVALID_OPERATION:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: invalid operation", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
|
|
|
{
|
|
|
|
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
2018-10-12 22:42:44 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
|
|
|
|
{
|
|
|
|
switch( status )
|
2018-10-12 22:42:44 +00:00
|
|
|
{
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "The framebuffer attachment points are incomplete." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "No images attached to the framebuffer." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "The framebuffer does not have at least one image attached to it." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "The framebuffer read buffer is incomplete." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "The combination of internal formats of the attached images violates " )
|
|
|
|
wxT( "an implementation dependent set of restrictions." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "GL_RENDERBUFFER_SAMPLES is not the same for all attached render " )
|
|
|
|
wxT( "buffers." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "Framebuffer incomplete layer targets errors." );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg = wxT( "Framebuffer attachments have different dimensions" );
|
2021-02-16 22:25:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2022-02-05 00:24:26 +00:00
|
|
|
errorMsg.Printf( wxT( "Unknown incomplete framebuffer error id %X" ), status );
|
2018-10-12 22:42:44 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-16 22:25:27 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
errorMsg = wxString::Format( "Error: %s: invalid framebuffer operation", aInfo );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_OUT_OF_MEMORY:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: out of memory", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_STACK_UNDERFLOW:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: stack underflow", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_STACK_OVERFLOW:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: stack overflow", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
|
2021-02-16 22:25:27 +00:00
|
|
|
default:
|
|
|
|
errorMsg = wxString::Format( "Error: %s: unknown error", aInfo );
|
|
|
|
break;
|
2016-05-02 13:56:14 +00:00
|
|
|
}
|
|
|
|
|
2017-01-13 15:46:02 +00:00
|
|
|
if( result != GL_NO_ERROR )
|
|
|
|
{
|
|
|
|
if( aThrow )
|
2021-03-22 19:34:33 +00:00
|
|
|
{
|
2021-04-05 13:24:57 +00:00
|
|
|
wxLogTrace( traceGalOpenGlError, wxT( "Throwing exception for glGetError() '%s' "
|
2022-02-05 00:24:26 +00:00
|
|
|
wxT( "in file '%s' on line %d." ) ),
|
2021-10-03 12:58:56 +00:00
|
|
|
errorMsg,
|
|
|
|
aFile,
|
|
|
|
aLine );
|
|
|
|
|
2017-01-13 21:48:26 +00:00
|
|
|
throw std::runtime_error( (const char*) errorMsg.char_str() );
|
2021-03-22 19:34:33 +00:00
|
|
|
}
|
2017-01-13 15:46:02 +00:00
|
|
|
else
|
2021-03-22 19:34:33 +00:00
|
|
|
{
|
2021-10-03 12:58:56 +00:00
|
|
|
wxString msg = wxString::Format( wxT( "glGetError() '%s' in file '%s' on line %d." ),
|
|
|
|
errorMsg,
|
|
|
|
aFile,
|
|
|
|
aLine );
|
2021-03-22 19:34:33 +00:00
|
|
|
|
2022-02-05 00:24:26 +00:00
|
|
|
DisplayErrorMessage( nullptr, wxT( "OpenGL Error" ), errorMsg );
|
2021-03-22 19:34:33 +00:00
|
|
|
}
|
2017-01-13 15:46:02 +00:00
|
|
|
}
|
2016-05-02 13:56:14 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-08-04 08:07:39 +00:00
|
|
|
|
2017-08-09 12:04:46 +00:00
|
|
|
// debugMsgCallback is a callback function for glDebugMessageCallback.
|
2017-08-09 13:30:01 +00:00
|
|
|
// It must have the right type ( GLAPIENTRY )
|
2021-02-16 22:25:27 +00:00
|
|
|
static void GLAPIENTRY debugMsgCallback( GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity,
|
|
|
|
GLsizei aLength, const GLchar* aMessage,
|
|
|
|
const void* aUserParam )
|
2017-08-04 08:07:39 +00:00
|
|
|
{
|
2018-02-09 15:19:25 +00:00
|
|
|
switch( aSeverity )
|
|
|
|
{
|
2022-02-05 00:24:26 +00:00
|
|
|
case GL_DEBUG_SEVERITY_HIGH: wxLogDebug( wxT( "OpenGL ERROR: " ) ); break;
|
|
|
|
case GL_DEBUG_SEVERITY_MEDIUM: wxLogDebug( wxT( "OpenGL WARNING: " ) ); break;
|
|
|
|
case GL_DEBUG_SEVERITY_LOW: wxLogDebug( wxT( "OpenGL INFO: " ) ); break;
|
2021-02-16 22:25:27 +00:00
|
|
|
case GL_DEBUG_SEVERITY_NOTIFICATION: return;
|
2018-02-09 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
2022-02-05 00:24:26 +00:00
|
|
|
wxLogDebug( wxT( "%s\n" ), aMessage );
|
2017-08-04 08:07:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void enableGlDebug( bool aEnable )
|
|
|
|
{
|
|
|
|
if( aEnable )
|
|
|
|
{
|
|
|
|
glEnable( GL_DEBUG_OUTPUT );
|
2017-08-08 13:26:50 +00:00
|
|
|
glDebugMessageCallback( (GLDEBUGPROC) debugMsgCallback, nullptr );
|
2017-08-04 08:07:39 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glDisable( GL_DEBUG_OUTPUT );
|
|
|
|
}
|
|
|
|
}
|