Fix DoRePaint routine in EDA_3D_CANVAS
- Check that we aren't already painting (return if we are) - Check that GLEW functions exist before calling them in 3D canvas and throw exception if they are no longer available - Catch above exceptions in paint routine and show an infobar message to the user Fixes https://gitlab.com/kicad/code/kicad/-/issues/6246
This commit is contained in:
parent
2d33b23530
commit
1bbc569151
|
@ -48,6 +48,7 @@
|
|||
#include <settings/settings_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
|
||||
#include <confirm.h>
|
||||
#include <widgets/wx_busy_indicator.h>
|
||||
|
||||
|
||||
|
@ -134,6 +135,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD*
|
|||
NULL,
|
||||
this );
|
||||
|
||||
m_is_currently_painting.clear();
|
||||
|
||||
m_3d_render_raytracing = new C3D_RENDER_RAYTRACING( m_boardAdapter, m_camera );
|
||||
m_3d_render_ogl_legacy = new C3D_RENDER_OGL_LEGACY( m_boardAdapter, m_camera );
|
||||
|
||||
|
@ -361,10 +364,15 @@ void EDA_3D_CANVAS::OnPaint( wxPaintEvent& aEvent )
|
|||
|
||||
void EDA_3D_CANVAS::DoRePaint()
|
||||
{
|
||||
if( m_is_currently_painting.test_and_set() )
|
||||
return;
|
||||
|
||||
|
||||
// SwapBuffer requires the window to be shown before calling
|
||||
if( !IsShownOnScreen() )
|
||||
{
|
||||
wxLogTrace( m_logTrace, "EDA_3D_CANVAS::DoRePaint !IsShown" );
|
||||
m_is_currently_painting.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -414,6 +422,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
|||
if( !initializeOpenGL() )
|
||||
{
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
|
||||
m_is_currently_painting.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -435,6 +444,7 @@ void EDA_3D_CANVAS::DoRePaint()
|
|||
SwapBuffers();
|
||||
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
|
||||
m_is_currently_painting.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -493,19 +503,32 @@ void EDA_3D_CANVAS::DoRePaint()
|
|||
|
||||
if( m_3d_render )
|
||||
{
|
||||
m_3d_render->SetCurWindowSize( clientSize );
|
||||
try
|
||||
{
|
||||
m_3d_render->SetCurWindowSize( clientSize );
|
||||
|
||||
bool reloadRaytracingForIntersectionCalculations = false;
|
||||
bool reloadRaytracingForIntersectionCalculations = false;
|
||||
|
||||
if( ( m_boardAdapter.RenderEngineGet() == RENDER_ENGINE::OPENGL_LEGACY ) &&
|
||||
m_3d_render_ogl_legacy->IsReloadRequestPending() )
|
||||
reloadRaytracingForIntersectionCalculations = true;
|
||||
if( ( m_boardAdapter.RenderEngineGet() == RENDER_ENGINE::OPENGL_LEGACY )
|
||||
&& m_3d_render_ogl_legacy->IsReloadRequestPending() )
|
||||
reloadRaytracingForIntersectionCalculations = true;
|
||||
|
||||
requested_redraw = m_3d_render->Redraw( m_mouse_was_moved || m_camera_is_moving,
|
||||
&activityReporter, &warningReporter );
|
||||
requested_redraw = m_3d_render->Redraw(
|
||||
m_mouse_was_moved || m_camera_is_moving, &activityReporter, &warningReporter );
|
||||
|
||||
if( reloadRaytracingForIntersectionCalculations )
|
||||
m_3d_render_raytracing->Reload( nullptr, nullptr, true );
|
||||
if( reloadRaytracingForIntersectionCalculations )
|
||||
m_3d_render_raytracing->Reload( nullptr, nullptr, true );
|
||||
}
|
||||
catch( std::runtime_error& err )
|
||||
{
|
||||
DisplayInfoMessage( m_parent, _( "Unable to use OpenGL" ), wxString( err.what() ) );
|
||||
m_is_opengl_version_supported = false;
|
||||
m_opengl_supports_raytracing = false;
|
||||
m_is_opengl_initialized = false;
|
||||
GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );
|
||||
m_is_currently_painting.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_render_pivot )
|
||||
|
@ -546,6 +569,8 @@ void EDA_3D_CANVAS::DoRePaint()
|
|||
m_mouse_was_moved = false;
|
||||
Request_refresh( false );
|
||||
}
|
||||
|
||||
m_is_currently_painting.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -872,7 +897,8 @@ void EDA_3D_CANVAS::stop_editingTimeOut_Timer()
|
|||
|
||||
void EDA_3D_CANVAS::restart_editingTimeOut_Timer()
|
||||
{
|
||||
m_editing_timeout_timer.Start( m_3d_render->GetWaitForEditingTimeOut() , wxTIMER_ONE_SHOT );
|
||||
if( m_3d_render )
|
||||
m_editing_timeout_timer.Start( m_3d_render->GetWaitForEditingTimeOut(), wxTIMER_ONE_SHOT );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef EDA_3D_CANVAS_H
|
||||
#define EDA_3D_CANVAS_H
|
||||
|
||||
|
||||
#include <atomic>
|
||||
#include "board_adapter.h"
|
||||
#include "3d_rendering/3d_render_raytracing/accelerators/caccelerator.h"
|
||||
#include "3d_rendering/c3d_render_base.h"
|
||||
|
@ -249,6 +249,7 @@ private:
|
|||
wxTimer m_editing_timeout_timer; // Expires after some time signalling that
|
||||
// the mouse / keyboard movements are over
|
||||
wxTimer m_redraw_trigger_timer; // Used to schedule a redraw event
|
||||
std::atomic_flag m_is_currently_painting; // Avoid drawing twice at the same time
|
||||
|
||||
bool m_mouse_is_moving; // Mouse activity is in progress
|
||||
bool m_mouse_was_moved;
|
||||
|
|
|
@ -400,6 +400,10 @@ void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMat
|
|||
if( aOpacity <= FLT_EPSILON )
|
||||
return;
|
||||
|
||||
|
||||
if( !glBindBuffer )
|
||||
throw std::runtime_error( "The OpenGL context no longer exists: unable to draw" );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, m_vertex_buffer );
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_index_buffer );
|
||||
|
||||
|
@ -457,15 +461,21 @@ void C_OGL_3DMODEL::Draw(bool aTransparent, float aOpacity, bool aUseSelectedMat
|
|||
|
||||
C_OGL_3DMODEL::~C_OGL_3DMODEL()
|
||||
{
|
||||
glDeleteBuffers( 1, &m_vertex_buffer );
|
||||
glDeleteBuffers( 1, &m_index_buffer );
|
||||
glDeleteBuffers( 1, &m_bbox_vertex_buffer );
|
||||
glDeleteBuffers( 1, &m_bbox_index_buffer );
|
||||
if( glDeleteBuffers )
|
||||
{
|
||||
glDeleteBuffers( 1, &m_vertex_buffer );
|
||||
glDeleteBuffers( 1, &m_index_buffer );
|
||||
glDeleteBuffers( 1, &m_bbox_vertex_buffer );
|
||||
glDeleteBuffers( 1, &m_bbox_index_buffer );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void C_OGL_3DMODEL::Draw_bbox() const
|
||||
{
|
||||
if( !glBindBuffer )
|
||||
throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bbox" );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
|
||||
|
||||
|
@ -482,6 +492,9 @@ void C_OGL_3DMODEL::Draw_bbox() const
|
|||
|
||||
void C_OGL_3DMODEL::Draw_bboxes() const
|
||||
{
|
||||
if( !glBindBuffer )
|
||||
throw std::runtime_error( "The OpenGL context no longer exists: unable to draw bboxes" );
|
||||
|
||||
glBindBuffer( GL_ARRAY_BUFFER, m_bbox_vertex_buffer );
|
||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_bbox_index_buffer );
|
||||
|
||||
|
|
|
@ -212,6 +212,9 @@ void OGL_DrawBackground( const SFVEC3F &aTopColor, const SFVEC3F &aBotColor )
|
|||
|
||||
void OGL_ResetTextureStateDefaults()
|
||||
{
|
||||
if( !glActiveTexture || !glClientActiveTexture )
|
||||
throw std::runtime_error( "The OpenGL context no longer exists: unable to Reset Textures" );
|
||||
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, 0 );
|
||||
glClientActiveTexture( GL_TEXTURE0 );
|
||||
|
|
Loading…
Reference in New Issue