GAL code cleaning.
This commit is contained in:
parent
0d2ee266a1
commit
e7227a4f21
|
@ -2,7 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2017 CERN
|
* Copyright (C) 2013-2017 CERN
|
||||||
* Copyright (C) 2013-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2013-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -53,21 +54,20 @@
|
||||||
|
|
||||||
EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWindowId,
|
||||||
const wxPoint& aPosition, const wxSize& aSize,
|
const wxPoint& aPosition, const wxSize& aSize,
|
||||||
KIGFX::GAL_DISPLAY_OPTIONS& aOptions,
|
KIGFX::GAL_DISPLAY_OPTIONS& aOptions, GAL_TYPE aGalType ) :
|
||||||
GAL_TYPE aGalType )
|
wxScrolledCanvas( aParentWindow, aWindowId, aPosition, aSize ),
|
||||||
: wxScrolledCanvas( aParentWindow, aWindowId, aPosition, aSize ),
|
m_edaFrame( nullptr ),
|
||||||
m_edaFrame( nullptr ),
|
m_gal( nullptr ),
|
||||||
m_gal( nullptr ),
|
m_view( nullptr ),
|
||||||
m_view( nullptr ),
|
m_painter( nullptr ),
|
||||||
m_painter( nullptr ),
|
m_viewControls( nullptr ),
|
||||||
m_viewControls( nullptr ),
|
m_backend( GAL_TYPE_NONE ),
|
||||||
m_backend( GAL_TYPE_NONE ),
|
m_options( aOptions ),
|
||||||
m_options( aOptions ),
|
m_eventDispatcher( nullptr ),
|
||||||
m_eventDispatcher( nullptr ),
|
m_lostFocus( false ),
|
||||||
m_lostFocus( false ),
|
m_stealsFocus( true )
|
||||||
m_stealsFocus( true )
|
|
||||||
{
|
{
|
||||||
m_parent = aParentWindow;
|
m_parent = aParentWindow;
|
||||||
m_currentKiCursor = KICURSOR::DEFAULT;
|
m_currentKiCursor = KICURSOR::DEFAULT;
|
||||||
SetCurrentCursor( KICURSOR::ARROW );
|
SetCurrentCursor( KICURSOR::ARROW );
|
||||||
|
|
||||||
|
@ -91,23 +91,32 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||||
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
SetBackgroundStyle( wxBG_STYLE_CUSTOM );
|
||||||
|
|
||||||
ShowScrollbars( wxSHOW_SB_ALWAYS, wxSHOW_SB_ALWAYS );
|
ShowScrollbars( wxSHOW_SB_ALWAYS, wxSHOW_SB_ALWAYS );
|
||||||
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
|
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
|
||||||
|
|
||||||
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
|
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), NULL, this );
|
||||||
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
|
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), NULL, this );
|
||||||
Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( EDA_DRAW_PANEL_GAL::onLostFocus ), NULL, this );
|
Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( EDA_DRAW_PANEL_GAL::onLostFocus ), NULL, this );
|
||||||
Connect( wxEVT_SET_CURSOR, wxSetCursorEventHandler( EDA_DRAW_PANEL_GAL::onSetCursor ), NULL, this );
|
Connect( wxEVT_SET_CURSOR, wxSetCursorEventHandler( EDA_DRAW_PANEL_GAL::onSetCursor ), NULL,
|
||||||
|
this );
|
||||||
|
|
||||||
const wxEventType events[] =
|
const wxEventType events[] = {
|
||||||
{
|
|
||||||
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
|
// Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
|
||||||
// especially special key like arrow keys, are handled by the GAL event dispatcher,
|
// especially special key like arrow keys, are handled by the GAL event dispatcher,
|
||||||
// and not sent to GUI without filtering, because they have a default action (scroll)
|
// and not sent to GUI without filtering, because they have a default action (scroll)
|
||||||
// that must not be called.
|
// that must not be called.
|
||||||
wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK,
|
wxEVT_LEFT_UP,
|
||||||
wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK,
|
wxEVT_LEFT_DOWN,
|
||||||
wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK,
|
wxEVT_LEFT_DCLICK,
|
||||||
wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK,
|
wxEVT_RIGHT_UP,
|
||||||
|
wxEVT_RIGHT_DOWN,
|
||||||
|
wxEVT_RIGHT_DCLICK,
|
||||||
|
wxEVT_MIDDLE_UP,
|
||||||
|
wxEVT_MIDDLE_DOWN,
|
||||||
|
wxEVT_MIDDLE_DCLICK,
|
||||||
|
wxEVT_MOTION,
|
||||||
|
wxEVT_MOUSEWHEEL,
|
||||||
|
wxEVT_CHAR,
|
||||||
|
wxEVT_CHAR_HOOK,
|
||||||
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
|
||||||
wxEVT_MAGNIFY,
|
wxEVT_MAGNIFY,
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,7 +124,8 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||||
};
|
};
|
||||||
|
|
||||||
for( wxEventType eventType : events )
|
for( wxEventType eventType : events )
|
||||||
Connect( eventType, wxEventHandler( EDA_DRAW_PANEL_GAL::OnEvent ), NULL, m_eventDispatcher );
|
Connect( eventType, wxEventHandler( EDA_DRAW_PANEL_GAL::OnEvent ), NULL,
|
||||||
|
m_eventDispatcher );
|
||||||
|
|
||||||
m_pendingRefresh = false;
|
m_pendingRefresh = false;
|
||||||
m_drawing = false;
|
m_drawing = false;
|
||||||
|
@ -187,7 +197,8 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||||
wxASSERT( m_painter );
|
wxASSERT( m_painter );
|
||||||
|
|
||||||
m_drawing = true;
|
m_drawing = true;
|
||||||
KIGFX::RENDER_SETTINGS* settings = static_cast<KIGFX::RENDER_SETTINGS*>( m_painter->GetSettings() );
|
KIGFX::RENDER_SETTINGS* settings =
|
||||||
|
static_cast<KIGFX::RENDER_SETTINGS*>( m_painter->GetSettings() );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -196,7 +207,7 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||||
KIGFX::GAL_DRAWING_CONTEXT ctx( m_gal );
|
KIGFX::GAL_DRAWING_CONTEXT ctx( m_gal );
|
||||||
|
|
||||||
if( m_view->IsTargetDirty( KIGFX::TARGET_OVERLAY )
|
if( m_view->IsTargetDirty( KIGFX::TARGET_OVERLAY )
|
||||||
&& !m_gal->HasTarget( KIGFX::TARGET_OVERLAY ) )
|
&& !m_gal->HasTarget( KIGFX::TARGET_OVERLAY ) )
|
||||||
{
|
{
|
||||||
m_view->MarkDirty();
|
m_view->MarkDirty();
|
||||||
}
|
}
|
||||||
|
@ -206,14 +217,14 @@ void EDA_DRAW_PANEL_GAL::DoRePaint()
|
||||||
m_gal->SetCursorColor( settings->GetCursorColor() );
|
m_gal->SetCursorColor( settings->GetCursorColor() );
|
||||||
|
|
||||||
// TODO: find why ClearScreen() must be called here in opengl mode
|
// TODO: find why ClearScreen() must be called here in opengl mode
|
||||||
// and only if m_view->IsDirty() in Cairo mode to avoid distaly artifacts
|
// and only if m_view->IsDirty() in Cairo mode to avoid display artifacts
|
||||||
// when moving the mouse cursor
|
// when moving the mouse cursor
|
||||||
if( m_backend == GAL_TYPE_OPENGL )
|
if( m_backend == GAL_TYPE_OPENGL )
|
||||||
m_gal->ClearScreen();
|
m_gal->ClearScreen();
|
||||||
|
|
||||||
if( m_view->IsDirty() )
|
if( m_view->IsDirty() )
|
||||||
{
|
{
|
||||||
if( m_backend != GAL_TYPE_OPENGL && // Already called in opengl
|
if( m_backend != GAL_TYPE_OPENGL && // Already called in opengl
|
||||||
m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
|
m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
|
||||||
m_gal->ClearScreen();
|
m_gal->ClearScreen();
|
||||||
|
|
||||||
|
@ -262,7 +273,7 @@ void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
KIGFX::GAL_CONTEXT_LOCKER locker( m_gal );
|
KIGFX::GAL_CONTEXT_LOCKER locker( m_gal );
|
||||||
wxSize clientSize = GetClientSize();
|
wxSize clientSize = GetClientSize();
|
||||||
WX_INFOBAR* infobar = GetParentEDAFrame() ? GetParentEDAFrame()->GetInfoBar() : nullptr;
|
WX_INFOBAR* infobar = GetParentEDAFrame() ? GetParentEDAFrame()->GetInfoBar() : nullptr;
|
||||||
|
|
||||||
if( VECTOR2I( clientSize ) == m_gal->GetScreenPixelSize() )
|
if( VECTOR2I( clientSize ) == m_gal->GetScreenPixelSize() )
|
||||||
|
@ -313,8 +324,6 @@ void EDA_DRAW_PANEL_GAL::Refresh( bool aEraseBackground, const wxRect* aRect )
|
||||||
|
|
||||||
void EDA_DRAW_PANEL_GAL::ForceRefresh()
|
void EDA_DRAW_PANEL_GAL::ForceRefresh()
|
||||||
{
|
{
|
||||||
//wxPaintEvent redrawEvent;
|
|
||||||
//wxPostEvent( this, redrawEvent );
|
|
||||||
m_pendingRefresh = true;
|
m_pendingRefresh = true;
|
||||||
DoRePaint();
|
DoRePaint();
|
||||||
}
|
}
|
||||||
|
@ -338,9 +347,10 @@ void EDA_DRAW_PANEL_GAL::SetEventDispatcher( TOOL_DISPATCHER* aEventDispatcher )
|
||||||
for( wxEventType type : eventTypes )
|
for( wxEventType type : eventTypes )
|
||||||
{
|
{
|
||||||
// While loop is used to be sure that all event handlers are removed.
|
// While loop is used to be sure that all event handlers are removed.
|
||||||
while( m_parent->Disconnect( type,
|
while( m_parent->Disconnect(
|
||||||
wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ),
|
type, wxCommandEventHandler( TOOL_DISPATCHER::DispatchWxCommand ), NULL,
|
||||||
NULL, m_eventDispatcher ) );
|
m_eventDispatcher ) )
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,9 +426,10 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
if( GAL_FALLBACK != aGalType )
|
if( GAL_FALLBACK != aGalType )
|
||||||
{
|
{
|
||||||
aGalType = GAL_FALLBACK;
|
aGalType = GAL_FALLBACK;
|
||||||
DisplayInfoMessage( m_parent,
|
DisplayInfoMessage(
|
||||||
_( "Could not use OpenGL, falling back to software rendering" ),
|
m_parent,
|
||||||
errormsg );
|
_( "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 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -430,9 +441,7 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GAL_TYPE_CAIRO:
|
case GAL_TYPE_CAIRO: new_gal = new KIGFX::CAIRO_GAL( m_options, this, this, this ); break;
|
||||||
new_gal = new KIGFX::CAIRO_GAL( m_options, this, this, this );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxASSERT( false );
|
wxASSERT( false );
|
||||||
|
@ -455,8 +464,7 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// trigger update of the gal options in case they differ
|
// trigger update of the gal options in case they differ from the defaults
|
||||||
// from the defaults
|
|
||||||
m_options.NotifyChanged();
|
m_options.NotifyChanged();
|
||||||
|
|
||||||
wxWindow* galWindow = dynamic_cast<wxWindow*>( new_gal );
|
wxWindow* galWindow = dynamic_cast<wxWindow*>( new_gal );
|
||||||
|
@ -499,9 +507,8 @@ bool EDA_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
|
|
||||||
void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
|
void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
|
||||||
{
|
{
|
||||||
bool shouldSetFocus = m_lostFocus && m_stealsFocus
|
bool shouldSetFocus = m_lostFocus && m_stealsFocus && !KIUI::IsInputControlFocused()
|
||||||
&& !KIUI::IsInputControlFocused()
|
&& !KIUI::IsModalDialogFocused();
|
||||||
&& !KIUI::IsModalDialogFocused();
|
|
||||||
|
|
||||||
#if defined( _WIN32 )
|
#if defined( _WIN32 )
|
||||||
// Ensure we are the active foreground window before we attempt to steal focus
|
// Ensure we are the active foreground window before we attempt to steal focus
|
||||||
|
@ -523,9 +530,8 @@ void EDA_DRAW_PANEL_GAL::OnEvent( wxEvent& aEvent )
|
||||||
|
|
||||||
void EDA_DRAW_PANEL_GAL::onEnter( wxMouseEvent& aEvent )
|
void EDA_DRAW_PANEL_GAL::onEnter( wxMouseEvent& aEvent )
|
||||||
{
|
{
|
||||||
bool shouldSetFocus = m_stealsFocus
|
bool shouldSetFocus =
|
||||||
&& !KIUI::IsInputControlFocused()
|
m_stealsFocus && !KIUI::IsInputControlFocused() && !KIUI::IsModalDialogFocused();
|
||||||
&& !KIUI::IsModalDialogFocused();
|
|
||||||
|
|
||||||
#if defined( _WIN32 )
|
#if defined( _WIN32 )
|
||||||
// Ensure we are the active foreground window before we attempt to steal focus
|
// Ensure we are the active foreground window before we attempt to steal focus
|
||||||
|
@ -570,8 +576,6 @@ void EDA_DRAW_PANEL_GAL::onRefreshTimer( wxTimerEvent& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//wxPaintEvent redrawEvent;
|
|
||||||
//wxPostEvent( this, redrawEvent );
|
|
||||||
DoRePaint();
|
DoRePaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -35,8 +36,10 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
CAIRO_COMPOSITOR::CAIRO_COMPOSITOR( cairo_t** aMainContext ) :
|
CAIRO_COMPOSITOR::CAIRO_COMPOSITOR( cairo_t** aMainContext ) :
|
||||||
m_current( 0 ), m_currentContext( aMainContext ), m_mainContext( *aMainContext ),
|
m_current( 0 ),
|
||||||
m_currentAntialiasingMode( CAIRO_ANTIALIAS_DEFAULT )
|
m_currentContext( aMainContext ),
|
||||||
|
m_mainContext( *aMainContext ),
|
||||||
|
m_currentAntialiasingMode( CAIRO_ANTIALIAS_DEFAULT )
|
||||||
{
|
{
|
||||||
// Do not have uninitialized members:
|
// Do not have uninitialized members:
|
||||||
cairo_matrix_init_identity( &m_matrix );
|
cairo_matrix_init_identity( &m_matrix );
|
||||||
|
@ -59,20 +62,12 @@ void CAIRO_COMPOSITOR::Initialize()
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::SetAntialiasingMode( CAIRO_ANTIALIASING_MODE aMode )
|
void CAIRO_COMPOSITOR::SetAntialiasingMode( CAIRO_ANTIALIASING_MODE aMode )
|
||||||
{
|
{
|
||||||
|
|
||||||
switch( aMode )
|
switch( aMode )
|
||||||
{
|
{
|
||||||
case CAIRO_ANTIALIASING_MODE::FAST:
|
case CAIRO_ANTIALIASING_MODE::FAST: m_currentAntialiasingMode = CAIRO_ANTIALIAS_FAST; break;
|
||||||
m_currentAntialiasingMode = CAIRO_ANTIALIAS_FAST;
|
case CAIRO_ANTIALIASING_MODE::GOOD: m_currentAntialiasingMode = CAIRO_ANTIALIAS_GOOD; break;
|
||||||
break;
|
case CAIRO_ANTIALIASING_MODE::BEST: m_currentAntialiasingMode = CAIRO_ANTIALIAS_BEST; break;
|
||||||
case CAIRO_ANTIALIASING_MODE::GOOD:
|
default: m_currentAntialiasingMode = CAIRO_ANTIALIAS_NONE;
|
||||||
m_currentAntialiasingMode = CAIRO_ANTIALIAS_GOOD;
|
|
||||||
break;
|
|
||||||
case CAIRO_ANTIALIASING_MODE::BEST:
|
|
||||||
m_currentAntialiasingMode = CAIRO_ANTIALIAS_BEST;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_currentAntialiasingMode = CAIRO_ANTIALIAS_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clean();
|
clean();
|
||||||
|
@ -83,10 +78,10 @@ void CAIRO_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
|
||||||
{
|
{
|
||||||
clean();
|
clean();
|
||||||
|
|
||||||
m_width = aWidth;
|
m_width = aWidth;
|
||||||
m_height = aHeight;
|
m_height = aHeight;
|
||||||
|
|
||||||
m_stride = cairo_format_stride_for_width( CAIRO_FORMAT_ARGB32, m_width );
|
m_stride = cairo_format_stride_for_width( CAIRO_FORMAT_ARGB32, m_width );
|
||||||
m_bufferSize = m_stride * m_height;
|
m_bufferSize = m_stride * m_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,10 +93,9 @@ unsigned int CAIRO_COMPOSITOR::CreateBuffer()
|
||||||
|
|
||||||
// Create the Cairo surface
|
// Create the Cairo surface
|
||||||
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
cairo_surface_t* surface = cairo_image_surface_create_for_data(
|
||||||
(unsigned char*) bitmap,
|
(unsigned char*) bitmap, CAIRO_FORMAT_ARGB32, m_width, m_height, m_stride );
|
||||||
CAIRO_FORMAT_ARGB32, m_width,
|
|
||||||
m_height, m_stride );
|
|
||||||
cairo_t* context = cairo_create( surface );
|
cairo_t* context = cairo_create( surface );
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cairo_status_t status = cairo_status( context );
|
cairo_status_t status = cairo_status( context );
|
||||||
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
|
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
|
||||||
|
@ -136,14 +130,16 @@ void CAIRO_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
||||||
cairo_set_matrix( *m_currentContext, &m_matrix );
|
cairo_set_matrix( *m_currentContext, &m_matrix );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::Begin()
|
void CAIRO_COMPOSITOR::Begin()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
void CAIRO_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
|
||||||
{
|
{
|
||||||
// Clear the pixel storage
|
// Clear the pixel storage
|
||||||
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize * sizeof(int) );
|
memset( m_buffers[m_current].bitmap, 0x00, m_bufferSize * sizeof( int ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,10 +160,12 @@ void CAIRO_COMPOSITOR::DrawBuffer( unsigned int aBufferHandle )
|
||||||
cairo_set_matrix( m_mainContext, &m_matrix );
|
cairo_set_matrix( m_mainContext, &m_matrix );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::Present()
|
void CAIRO_COMPOSITOR::Present()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_COMPOSITOR::clean()
|
void CAIRO_COMPOSITOR::clean()
|
||||||
{
|
{
|
||||||
CAIRO_BUFFERS::const_iterator it;
|
CAIRO_BUFFERS::const_iterator it;
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||||
* Copyright (C) 2012-2020 Kicad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2012-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
* Copyright (C) 2017-2018 CERN
|
* Copyright (C) 2017-2018 CERN
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* CairoGal - Graphics Abstraction Layer for Cairo
|
* CairoGal - Graphics Abstraction Layer for Cairo
|
||||||
|
@ -33,7 +34,7 @@
|
||||||
#include <gal/cairo/cairo_compositor.h>
|
#include <gal/cairo/cairo_compositor.h>
|
||||||
#include <gal/definitions.h>
|
#include <gal/definitions.h>
|
||||||
#include <geometry/shape_poly_set.h>
|
#include <geometry/shape_poly_set.h>
|
||||||
#include <math/util.h> // for KiROUND
|
#include <math/util.h> // for KiROUND
|
||||||
#include <bitmap_base.h>
|
#include <bitmap_base.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -45,15 +46,13 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
|
||||||
|
CAIRO_GAL_BASE::CAIRO_GAL_BASE( GAL_DISPLAY_OPTIONS& aDisplayOptions ) : GAL( aDisplayOptions )
|
||||||
CAIRO_GAL_BASE::CAIRO_GAL_BASE( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
|
||||||
GAL( aDisplayOptions )
|
|
||||||
{
|
{
|
||||||
// Initialise grouping
|
// Initialise grouping
|
||||||
isGrouping = false;
|
isGrouping = false;
|
||||||
isElementAdded = false;
|
isElementAdded = false;
|
||||||
groupCounter = 0;
|
groupCounter = 0;
|
||||||
currentGroup = nullptr;
|
currentGroup = nullptr;
|
||||||
|
|
||||||
lineWidth = 1.0;
|
lineWidth = 1.0;
|
||||||
linePixelWidth = 1.0;
|
linePixelWidth = 1.0;
|
||||||
|
@ -62,9 +61,9 @@ CAIRO_GAL_BASE::CAIRO_GAL_BASE( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||||
|
|
||||||
// Initialise Cairo state
|
// Initialise Cairo state
|
||||||
cairo_matrix_init_identity( &cairoWorldScreenMatrix );
|
cairo_matrix_init_identity( &cairoWorldScreenMatrix );
|
||||||
currentContext = nullptr;
|
currentContext = nullptr;
|
||||||
context = nullptr;
|
context = nullptr;
|
||||||
surface = nullptr;
|
surface = nullptr;
|
||||||
|
|
||||||
// Grid color settings are different in Cairo and OpenGL
|
// Grid color settings are different in Cairo and OpenGL
|
||||||
SetGridColor( COLOR4D( 0.1, 0.1, 0.1, 0.8 ) );
|
SetGridColor( COLOR4D( 0.1, 0.1, 0.1, 0.8 ) );
|
||||||
|
@ -103,6 +102,7 @@ void CAIRO_GAL_BASE::endDrawing()
|
||||||
Flush();
|
Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::updateWorldScreenMatrix()
|
void CAIRO_GAL_BASE::updateWorldScreenMatrix()
|
||||||
{
|
{
|
||||||
cairo_matrix_multiply( ¤tWorld2Screen, ¤tXform, &cairoWorldScreenMatrix );
|
cairo_matrix_multiply( ¤tWorld2Screen, ¤tXform, &cairoWorldScreenMatrix );
|
||||||
|
@ -164,8 +164,8 @@ void CAIRO_GAL_BASE::arc_angles_xform_and_normalize( double& aStartAngle, double
|
||||||
// So, if this is the case, force the aEndAngle value to draw a circle.
|
// So, if this is the case, force the aEndAngle value to draw a circle.
|
||||||
aStartAngle = angle_xform( startAngle );
|
aStartAngle = angle_xform( startAngle );
|
||||||
|
|
||||||
if( std::abs( aEndAngle - aStartAngle ) >= 2*M_PI ) // arc is a full circle
|
if( std::abs( aEndAngle - aStartAngle ) >= 2 * M_PI ) // arc is a full circle
|
||||||
aEndAngle = aStartAngle + 2*M_PI;
|
aEndAngle = aStartAngle + 2 * M_PI;
|
||||||
else
|
else
|
||||||
aEndAngle = angle_xform( endAngle );
|
aEndAngle = angle_xform( endAngle );
|
||||||
}
|
}
|
||||||
|
@ -210,9 +210,9 @@ void CAIRO_GAL_BASE::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::syncLineWidth( bool aForceWidth, double aWidth )
|
void CAIRO_GAL_BASE::syncLineWidth( bool aForceWidth, double aWidth )
|
||||||
{
|
{
|
||||||
auto w = floor( xform( aForceWidth ? aWidth : lineWidth ) + 0.5 );
|
auto w = floor( xform( aForceWidth ? aWidth : lineWidth ) + 0.5 );
|
||||||
|
|
||||||
if (w <= 1.0)
|
if( w <= 1.0 )
|
||||||
{
|
{
|
||||||
w = 1.0;
|
w = 1.0;
|
||||||
cairo_set_line_join( currentContext, CAIRO_LINE_JOIN_MITER );
|
cairo_set_line_join( currentContext, CAIRO_LINE_JOIN_MITER );
|
||||||
|
@ -225,7 +225,7 @@ void CAIRO_GAL_BASE::syncLineWidth( bool aForceWidth, double aWidth )
|
||||||
cairo_set_line_join( currentContext, CAIRO_LINE_JOIN_ROUND );
|
cairo_set_line_join( currentContext, CAIRO_LINE_JOIN_ROUND );
|
||||||
cairo_set_line_cap( currentContext, CAIRO_LINE_CAP_ROUND );
|
cairo_set_line_cap( currentContext, CAIRO_LINE_CAP_ROUND );
|
||||||
cairo_set_line_width( currentContext, w );
|
cairo_set_line_width( currentContext, w );
|
||||||
lineWidthIsOdd = ((int)w % 2) == 1;
|
lineWidthIsOdd = ( (int) w % 2 ) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lineWidthInPixels = w;
|
lineWidthInPixels = w;
|
||||||
|
@ -233,7 +233,7 @@ void CAIRO_GAL_BASE::syncLineWidth( bool aForceWidth, double aWidth )
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
|
||||||
double aWidth )
|
double aWidth )
|
||||||
{
|
{
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
{
|
{
|
||||||
|
@ -255,20 +255,21 @@ void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& a
|
||||||
|
|
||||||
// Outline mode for tracks
|
// Outline mode for tracks
|
||||||
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
VECTOR2D startEndVector = aEndPoint - aStartPoint;
|
||||||
double lineAngle = atan2( startEndVector.y, startEndVector.x );
|
double lineAngle = atan2( startEndVector.y, startEndVector.x );
|
||||||
|
|
||||||
double sa = sin( lineAngle + M_PI / 2.0 );
|
double sa = sin( lineAngle + M_PI / 2.0 );
|
||||||
double ca = cos( lineAngle + M_PI / 2.0 );
|
double ca = cos( lineAngle + M_PI / 2.0 );
|
||||||
|
|
||||||
auto pa0 = xform ( aStartPoint + VECTOR2D(aWidth * ca, aWidth * sa ) );
|
auto pa0 = xform( aStartPoint + VECTOR2D( aWidth * ca, aWidth * sa ) );
|
||||||
auto pa1 = xform ( aStartPoint - VECTOR2D(aWidth * ca, aWidth * sa ) );
|
auto pa1 = xform( aStartPoint - VECTOR2D( aWidth * ca, aWidth * sa ) );
|
||||||
auto pb0 = xform ( aEndPoint + VECTOR2D(aWidth * ca, aWidth * sa ) );
|
auto pb0 = xform( aEndPoint + VECTOR2D( aWidth * ca, aWidth * sa ) );
|
||||||
auto pb1 = xform ( aEndPoint - VECTOR2D(aWidth * ca, aWidth * sa ) );
|
auto pb1 = xform( aEndPoint - VECTOR2D( aWidth * ca, aWidth * sa ) );
|
||||||
auto pa = xform( aStartPoint );
|
auto pa = xform( aStartPoint );
|
||||||
auto pb = xform( aEndPoint );
|
auto pb = xform( aEndPoint );
|
||||||
auto rb = (pa0 - pa).EuclideanNorm();
|
auto rb = ( pa0 - pa ).EuclideanNorm();
|
||||||
|
|
||||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||||
|
strokeColor.a );
|
||||||
|
|
||||||
cairo_move_to( currentContext, pa0.x, pa0.y );
|
cairo_move_to( currentContext, pa0.x, pa0.y );
|
||||||
cairo_line_to( currentContext, pb0.x, pb0.y );
|
cairo_line_to( currentContext, pb0.x, pb0.y );
|
||||||
|
@ -277,7 +278,8 @@ void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& a
|
||||||
cairo_line_to( currentContext, pb1.x, pb1.y );
|
cairo_line_to( currentContext, pb1.x, pb1.y );
|
||||||
|
|
||||||
cairo_arc( currentContext, pb.x, pb.y, rb, lineAngle - M_PI / 2.0, lineAngle + M_PI / 2.0 );
|
cairo_arc( currentContext, pb.x, pb.y, rb, lineAngle - M_PI / 2.0, lineAngle + M_PI / 2.0 );
|
||||||
cairo_arc( currentContext, pa.x, pa.y, rb, lineAngle + M_PI / 2.0, lineAngle + 3.0 * M_PI / 2.0 );
|
cairo_arc( currentContext, pa.x, pa.y, rb, lineAngle + M_PI / 2.0,
|
||||||
|
lineAngle + 3.0 * M_PI / 2.0 );
|
||||||
|
|
||||||
flushPath();
|
flushPath();
|
||||||
}
|
}
|
||||||
|
@ -303,7 +305,7 @@ void CAIRO_GAL_BASE::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
||||||
double aEndAngle )
|
double aEndAngle )
|
||||||
{
|
{
|
||||||
syncLineWidth();
|
syncLineWidth();
|
||||||
|
|
||||||
|
@ -338,8 +340,8 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
|
void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||||
double aEndAngle, double aWidth )
|
double aStartAngle, double aEndAngle, double aWidth )
|
||||||
{
|
{
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
{
|
{
|
||||||
|
@ -368,14 +370,15 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||||
// whole arc to change position/size
|
// whole arc to change position/size
|
||||||
lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
lineWidthIsOdd = !( static_cast<int>( aRadius ) % 2 );
|
||||||
|
|
||||||
auto mid = roundp( xform( aCenterPoint ) );
|
auto mid = roundp( xform( aCenterPoint ) );
|
||||||
double width = xform( aWidth / 2.0 );
|
double width = xform( aWidth / 2.0 );
|
||||||
auto startPointS = VECTOR2D( r, 0.0 ).Rotate( startAngleS );
|
auto startPointS = VECTOR2D( r, 0.0 ).Rotate( startAngleS );
|
||||||
auto endPointS = VECTOR2D( r, 0.0 ).Rotate( endAngleS );
|
auto endPointS = VECTOR2D( r, 0.0 ).Rotate( endAngleS );
|
||||||
|
|
||||||
cairo_save( currentContext );
|
cairo_save( currentContext );
|
||||||
|
|
||||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||||
|
strokeColor.a );
|
||||||
|
|
||||||
cairo_translate( currentContext, mid.x, mid.y );
|
cairo_translate( currentContext, mid.x, mid.y );
|
||||||
|
|
||||||
|
@ -386,7 +389,8 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||||
cairo_arc( currentContext, 0, 0, r + width, startAngleS, endAngleS );
|
cairo_arc( currentContext, 0, 0, r + width, startAngleS, endAngleS );
|
||||||
|
|
||||||
cairo_new_sub_path( currentContext );
|
cairo_new_sub_path( currentContext );
|
||||||
cairo_arc_negative( currentContext, startPointS.x, startPointS.y, width, startAngleS, startAngleS + M_PI );
|
cairo_arc_negative( currentContext, startPointS.x, startPointS.y, width, startAngleS,
|
||||||
|
startAngleS + M_PI );
|
||||||
|
|
||||||
cairo_new_sub_path( currentContext );
|
cairo_new_sub_path( currentContext );
|
||||||
cairo_arc( currentContext, endPointS.x, endPointS.y, width, endAngleS, endAngleS + M_PI );
|
cairo_arc( currentContext, endPointS.x, endPointS.y, width, endAngleS, endAngleS + M_PI );
|
||||||
|
@ -477,12 +481,12 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap )
|
||||||
cairo_surface_flush( image );
|
cairo_surface_flush( image );
|
||||||
|
|
||||||
unsigned char* pix_buffer = cairo_image_surface_get_data( image );
|
unsigned char* pix_buffer = cairo_image_surface_get_data( image );
|
||||||
|
|
||||||
// The pixel buffer of the initial bitmap:
|
// The pixel buffer of the initial bitmap:
|
||||||
const wxImage& bm_pix_buffer = *aBitmap.GetImageData();
|
const wxImage& bm_pix_buffer = *aBitmap.GetImageData();
|
||||||
|
|
||||||
uint32_t mask_color = ( bm_pix_buffer.GetMaskRed() << 16 ) +
|
uint32_t mask_color = ( bm_pix_buffer.GetMaskRed() << 16 )
|
||||||
( bm_pix_buffer.GetMaskGreen() << 8 ) +
|
+ ( bm_pix_buffer.GetMaskGreen() << 8 ) + ( bm_pix_buffer.GetMaskBlue() );
|
||||||
( bm_pix_buffer.GetMaskBlue() );
|
|
||||||
|
|
||||||
// Copy the source bitmap to the cairo bitmap buffer.
|
// Copy the source bitmap to the cairo bitmap buffer.
|
||||||
// In cairo bitmap buffer, a ARGB32 bitmap is an ARGB pixel packed into a uint_32
|
// In cairo bitmap buffer, a ARGB32 bitmap is an ARGB pixel packed into a uint_32
|
||||||
|
@ -639,12 +643,9 @@ void CAIRO_GAL_BASE::Transform( const MATRIX3x3D& aTransformation )
|
||||||
{
|
{
|
||||||
cairo_matrix_t cairoTransformation, newXform;
|
cairo_matrix_t cairoTransformation, newXform;
|
||||||
|
|
||||||
cairo_matrix_init( &cairoTransformation,
|
cairo_matrix_init( &cairoTransformation, aTransformation.m_data[0][0],
|
||||||
aTransformation.m_data[0][0],
|
aTransformation.m_data[1][0], aTransformation.m_data[0][1],
|
||||||
aTransformation.m_data[1][0],
|
aTransformation.m_data[1][1], aTransformation.m_data[0][2],
|
||||||
aTransformation.m_data[0][1],
|
|
||||||
aTransformation.m_data[1][1],
|
|
||||||
aTransformation.m_data[0][2],
|
|
||||||
aTransformation.m_data[1][2] );
|
aTransformation.m_data[1][2] );
|
||||||
|
|
||||||
cairo_matrix_multiply( &newXform, ¤tXform, &cairoTransformation );
|
cairo_matrix_multiply( &newXform, ¤tXform, &cairoTransformation );
|
||||||
|
@ -686,7 +687,7 @@ void CAIRO_GAL_BASE::Translate( const VECTOR2D& aTranslation )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cairo_matrix_translate ( ¤tXform, aTranslation.x, aTranslation.y );
|
cairo_matrix_translate( ¤tXform, aTranslation.x, aTranslation.y );
|
||||||
updateWorldScreenMatrix();
|
updateWorldScreenMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -759,10 +760,10 @@ int CAIRO_GAL_BASE::BeginGroup()
|
||||||
storePath();
|
storePath();
|
||||||
|
|
||||||
GROUP group;
|
GROUP group;
|
||||||
int groupNumber = getNewGroupNumber();
|
int groupNumber = getNewGroupNumber();
|
||||||
groups.insert( std::make_pair( groupNumber, group ) );
|
groups.insert( std::make_pair( groupNumber, group ) );
|
||||||
currentGroup = &groups[groupNumber];
|
currentGroup = &groups[groupNumber];
|
||||||
isGrouping = true;
|
isGrouping = true;
|
||||||
|
|
||||||
return groupNumber;
|
return groupNumber;
|
||||||
}
|
}
|
||||||
|
@ -782,8 +783,7 @@ void CAIRO_GAL_BASE::DrawGroup( int aGroupNumber )
|
||||||
|
|
||||||
storePath();
|
storePath();
|
||||||
|
|
||||||
for( GROUP::iterator it = groups[aGroupNumber].begin();
|
for( GROUP::iterator it = groups[aGroupNumber].begin(); it != groups[aGroupNumber].end(); ++it )
|
||||||
it != groups[aGroupNumber].end(); ++it )
|
|
||||||
{
|
{
|
||||||
switch( it->command )
|
switch( it->command )
|
||||||
{
|
{
|
||||||
|
@ -796,34 +796,36 @@ void CAIRO_GAL_BASE::DrawGroup( int aGroupNumber )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_FILLCOLOR:
|
case CMD_SET_FILLCOLOR:
|
||||||
fillColor = COLOR4D( it->argument.dblArg[0], it->argument.dblArg[1], it->argument.dblArg[2],
|
fillColor = COLOR4D( it->argument.dblArg[0], it->argument.dblArg[1],
|
||||||
it->argument.dblArg[3] );
|
it->argument.dblArg[2], it->argument.dblArg[3] );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_STROKECOLOR:
|
case CMD_SET_STROKECOLOR:
|
||||||
strokeColor = COLOR4D( it->argument.dblArg[0], it->argument.dblArg[1], it->argument.dblArg[2],
|
strokeColor = COLOR4D( it->argument.dblArg[0], it->argument.dblArg[1],
|
||||||
it->argument.dblArg[3] );
|
it->argument.dblArg[2], it->argument.dblArg[3] );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SET_LINE_WIDTH:
|
case CMD_SET_LINE_WIDTH:
|
||||||
{
|
{
|
||||||
// Make lines appear at least 1 pixel wide, no matter of zoom
|
// Make lines appear at least 1 pixel wide, no matter of zoom
|
||||||
double x = 1.0, y = 1.0;
|
double x = 1.0, y = 1.0;
|
||||||
cairo_device_to_user_distance( currentContext, &x, &y );
|
cairo_device_to_user_distance( currentContext, &x, &y );
|
||||||
double minWidth = std::min( fabs( x ), fabs( y ) );
|
double minWidth = std::min( fabs( x ), fabs( y ) );
|
||||||
cairo_set_line_width( currentContext, std::max( it->argument.dblArg[0], minWidth ) );
|
cairo_set_line_width( currentContext, std::max( it->argument.dblArg[0], minWidth ) );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case CMD_STROKE_PATH:
|
case CMD_STROKE_PATH:
|
||||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||||
|
strokeColor.a );
|
||||||
cairo_append_path( currentContext, it->cairoPath );
|
cairo_append_path( currentContext, it->cairoPath );
|
||||||
cairo_stroke( currentContext );
|
cairo_stroke( currentContext );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FILL_PATH:
|
case CMD_FILL_PATH:
|
||||||
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, strokeColor.a );
|
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b,
|
||||||
|
strokeColor.a );
|
||||||
cairo_append_path( currentContext, it->cairoPath );
|
cairo_append_path( currentContext, it->cairoPath );
|
||||||
cairo_fill( currentContext );
|
cairo_fill( currentContext );
|
||||||
break;
|
break;
|
||||||
|
@ -869,8 +871,7 @@ void CAIRO_GAL_BASE::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColo
|
||||||
{
|
{
|
||||||
storePath();
|
storePath();
|
||||||
|
|
||||||
for( GROUP::iterator it = groups[aGroupNumber].begin();
|
for( GROUP::iterator it = groups[aGroupNumber].begin(); it != groups[aGroupNumber].end(); ++it )
|
||||||
it != groups[aGroupNumber].end(); ++it )
|
|
||||||
{
|
{
|
||||||
if( it->command == CMD_SET_FILLCOLOR || it->command == CMD_SET_STROKECOLOR )
|
if( it->command == CMD_SET_FILLCOLOR || it->command == CMD_SET_STROKECOLOR )
|
||||||
{
|
{
|
||||||
|
@ -972,10 +973,10 @@ void CAIRO_GAL_BASE::drawAxes( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
||||||
|
|
||||||
auto p0 = roundp( xform( aStartPoint ) );
|
auto p0 = roundp( xform( aStartPoint ) );
|
||||||
auto p1 = roundp( xform( aEndPoint ) );
|
auto p1 = roundp( xform( aEndPoint ) );
|
||||||
auto org = roundp( xform( VECTOR2D( 0.0, 0.0 ) ) ); // Axis origin = 0,0 coord
|
auto org = roundp( xform( VECTOR2D( 0.0, 0.0 ) ) ); // Axis origin = 0,0 coord
|
||||||
|
|
||||||
cairo_set_source_rgba( currentContext, axesColor.r, axesColor.g, axesColor.b, axesColor.a );
|
cairo_set_source_rgba( currentContext, axesColor.r, axesColor.g, axesColor.b, axesColor.a );
|
||||||
cairo_move_to( currentContext, p0.x, org.y);
|
cairo_move_to( currentContext, p0.x, org.y );
|
||||||
cairo_line_to( currentContext, p1.x, org.y );
|
cairo_line_to( currentContext, p1.x, org.y );
|
||||||
cairo_move_to( currentContext, org.x, p0.y );
|
cairo_move_to( currentContext, org.x, p0.y );
|
||||||
cairo_line_to( currentContext, org.x, p1.y );
|
cairo_line_to( currentContext, org.x, p1.y );
|
||||||
|
@ -1000,7 +1001,7 @@ void CAIRO_GAL_BASE::drawGridCross( const VECTOR2D& aPoint )
|
||||||
{
|
{
|
||||||
syncLineWidth();
|
syncLineWidth();
|
||||||
VECTOR2D offset( 0, 0 );
|
VECTOR2D offset( 0, 0 );
|
||||||
double size = 2.0 * lineWidthInPixels + 0.5;
|
double size = 2.0 * lineWidthInPixels + 0.5;
|
||||||
|
|
||||||
VECTOR2D p0 = roundp( xform( aPoint ) ) - VECTOR2D( size, 0 ) + offset;
|
VECTOR2D p0 = roundp( xform( aPoint ) ) - VECTOR2D( size, 0 ) + offset;
|
||||||
VECTOR2D p1 = roundp( xform( aPoint ) ) + VECTOR2D( size, 0 ) + offset;
|
VECTOR2D p1 = roundp( xform( aPoint ) ) + VECTOR2D( size, 0 ) + offset;
|
||||||
|
@ -1025,30 +1026,30 @@ void CAIRO_GAL_BASE::drawGridPoint( const VECTOR2D& aPoint, double aWidth, doubl
|
||||||
|
|
||||||
cairo_set_source_rgba( currentContext, gridColor.r, gridColor.g, gridColor.b, gridColor.a );
|
cairo_set_source_rgba( currentContext, gridColor.r, gridColor.g, gridColor.b, gridColor.a );
|
||||||
cairo_rectangle( currentContext, p.x - std::floor( sw / 2 ) - 0.5,
|
cairo_rectangle( currentContext, p.x - std::floor( sw / 2 ) - 0.5,
|
||||||
p.y - std::floor( sh / 2 ) - 0.5, sw, sh );
|
p.y - std::floor( sh / 2 ) - 0.5, sw, sh );
|
||||||
|
|
||||||
cairo_fill( currentContext );
|
cairo_fill( currentContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL_BASE::flushPath()
|
void CAIRO_GAL_BASE::flushPath()
|
||||||
{
|
{
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
{
|
{
|
||||||
cairo_set_source_rgba( currentContext,
|
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||||
fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
|
||||||
|
|
||||||
if( isStrokeEnabled )
|
if( isStrokeEnabled )
|
||||||
cairo_fill_preserve( currentContext );
|
cairo_fill_preserve( currentContext );
|
||||||
else
|
else
|
||||||
cairo_fill( currentContext );
|
cairo_fill( currentContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isStrokeEnabled )
|
if( isStrokeEnabled )
|
||||||
{
|
{
|
||||||
cairo_set_source_rgba( currentContext,
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||||
strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
strokeColor.a );
|
||||||
cairo_stroke( currentContext );
|
cairo_stroke( currentContext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1062,14 +1063,15 @@ void CAIRO_GAL_BASE::storePath()
|
||||||
{
|
{
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
{
|
{
|
||||||
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b,
|
||||||
|
fillColor.a );
|
||||||
cairo_fill_preserve( currentContext );
|
cairo_fill_preserve( currentContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isStrokeEnabled )
|
if( isStrokeEnabled )
|
||||||
{
|
{
|
||||||
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g,
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g, strokeColor.b,
|
||||||
strokeColor.b, strokeColor.a );
|
strokeColor.a );
|
||||||
cairo_stroke_preserve( currentContext );
|
cairo_stroke_preserve( currentContext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1082,7 +1084,7 @@ void CAIRO_GAL_BASE::storePath()
|
||||||
{
|
{
|
||||||
GROUP_ELEMENT groupElement;
|
GROUP_ELEMENT groupElement;
|
||||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||||
groupElement.command = CMD_STROKE_PATH;
|
groupElement.command = CMD_STROKE_PATH;
|
||||||
currentGroup->push_back( groupElement );
|
currentGroup->push_back( groupElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,7 +1092,7 @@ void CAIRO_GAL_BASE::storePath()
|
||||||
{
|
{
|
||||||
GROUP_ELEMENT groupElement;
|
GROUP_ELEMENT groupElement;
|
||||||
groupElement.cairoPath = cairo_copy_path( currentContext );
|
groupElement.cairoPath = cairo_copy_path( currentContext );
|
||||||
groupElement.command = CMD_FILL_PATH;
|
groupElement.command = CMD_FILL_PATH;
|
||||||
currentGroup->push_back( groupElement );
|
currentGroup->push_back( groupElement );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1108,10 +1110,10 @@ void CAIRO_GAL_BASE::blitCursor( wxMemoryDC& clientDC )
|
||||||
auto p = ToScreen( cursorPosition );
|
auto p = ToScreen( cursorPosition );
|
||||||
|
|
||||||
const auto cColor = getCursorColor();
|
const auto cColor = getCursorColor();
|
||||||
const int cursorSize = fullscreenCursor ? 8000 : 80;
|
const int cursorSize = fullscreenCursor ? 8000 : 80;
|
||||||
|
|
||||||
wxColour color( cColor.r * cColor.a * 255, cColor.g * cColor.a * 255,
|
wxColour color( cColor.r * cColor.a * 255, cColor.g * cColor.a * 255, cColor.b * cColor.a * 255,
|
||||||
cColor.b * cColor.a * 255, 255 );
|
255 );
|
||||||
clientDC.SetPen( wxPen( color ) );
|
clientDC.SetPen( wxPen( color ) );
|
||||||
clientDC.DrawLine( p.x - cursorSize / 2, p.y, p.x + cursorSize / 2, p.y );
|
clientDC.DrawLine( p.x - cursorSize / 2, p.y, p.x + cursorSize / 2, p.y );
|
||||||
clientDC.DrawLine( p.x, p.y - cursorSize / 2, p.x, p.y + cursorSize / 2 );
|
clientDC.DrawLine( p.x, p.y - cursorSize / 2, p.x, p.y + cursorSize / 2 );
|
||||||
|
@ -1179,13 +1181,13 @@ void CAIRO_GAL_BASE::drawPoly( const SHAPE_LINE_CHAIN& aLineChain )
|
||||||
numPoints += 1;
|
numPoints += 1;
|
||||||
|
|
||||||
const VECTOR2I start = aLineChain.CPoint( 0 );
|
const VECTOR2I start = aLineChain.CPoint( 0 );
|
||||||
const auto p = roundp( xform( start.x, start.y ) );
|
const auto p = roundp( xform( start.x, start.y ) );
|
||||||
cairo_move_to( currentContext, p.x, p.y );
|
cairo_move_to( currentContext, p.x, p.y );
|
||||||
|
|
||||||
for( int i = 1; i < numPoints; ++i )
|
for( int i = 1; i < numPoints; ++i )
|
||||||
{
|
{
|
||||||
const VECTOR2I& pw = aLineChain.CPoint( i );
|
const VECTOR2I& pw = aLineChain.CPoint( i );
|
||||||
const auto ps = roundp( xform( pw.x, pw.y ) );
|
const auto ps = roundp( xform( pw.x, pw.y ) );
|
||||||
cairo_line_to( currentContext, ps.x, ps.y );
|
cairo_line_to( currentContext, ps.x, ps.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,42 +1208,42 @@ unsigned int CAIRO_GAL_BASE::getNewGroupNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||||
wxWindow* aParent, wxEvtHandler* aMouseListener,
|
wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
|
||||||
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
const wxString& aName ) :
|
||||||
CAIRO_GAL_BASE( aDisplayOptions ),
|
CAIRO_GAL_BASE( aDisplayOptions ),
|
||||||
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
|
wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
|
||||||
{
|
{
|
||||||
// Initialise compositing state
|
// Initialise compositing state
|
||||||
mainBuffer = 0;
|
mainBuffer = 0;
|
||||||
overlayBuffer = 0;
|
overlayBuffer = 0;
|
||||||
validCompositor = false;
|
validCompositor = false;
|
||||||
SetTarget( TARGET_NONCACHED );
|
SetTarget( TARGET_NONCACHED );
|
||||||
|
|
||||||
bitmapBuffer = nullptr;
|
bitmapBuffer = nullptr;
|
||||||
wxOutput = nullptr;
|
wxOutput = nullptr;
|
||||||
|
|
||||||
parentWindow = aParent;
|
parentWindow = aParent;
|
||||||
mouseListener = aMouseListener;
|
mouseListener = aMouseListener;
|
||||||
paintListener = aPaintListener;
|
paintListener = aPaintListener;
|
||||||
|
|
||||||
// Connecting the event handlers
|
// Connecting the event handlers
|
||||||
Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) );
|
Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) );
|
||||||
|
|
||||||
// Mouse events are skipped to the parent
|
// Mouse events are skipped to the parent
|
||||||
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_MOTION, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_LEFT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_MIDDLE_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_MIDDLE_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_MIDDLE_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_RIGHT_DCLICK, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
#if defined _WIN32 || defined _WIN64
|
#if defined _WIN32 || defined _WIN64
|
||||||
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SetSize( aParent->GetClientSize() );
|
SetSize( aParent->GetClientSize() );
|
||||||
|
@ -1286,21 +1288,22 @@ void CAIRO_GAL::endDrawing()
|
||||||
// by cairo into a format understood by wxImage.
|
// by cairo into a format understood by wxImage.
|
||||||
|
|
||||||
pixman_image_t* dstImg = pixman_image_create_bits(
|
pixman_image_t* dstImg = pixman_image_create_bits(
|
||||||
wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8 :
|
wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8
|
||||||
PIXMAN_r8g8b8,
|
: PIXMAN_r8g8b8,
|
||||||
screenSize.x, screenSize.y, (uint32_t*) wxOutput, wxBufferWidth * 3 );
|
screenSize.x, screenSize.y, (uint32_t*) wxOutput, wxBufferWidth * 3 );
|
||||||
pixman_image_t* srcImg = pixman_image_create_bits( PIXMAN_a8r8g8b8, screenSize.x, screenSize.y,
|
pixman_image_t* srcImg =
|
||||||
(uint32_t*) bitmapBuffer, wxBufferWidth * 4 );
|
pixman_image_create_bits( PIXMAN_a8r8g8b8, screenSize.x, screenSize.y,
|
||||||
|
(uint32_t*) bitmapBuffer, wxBufferWidth * 4 );
|
||||||
|
|
||||||
pixman_image_composite( PIXMAN_OP_SRC, srcImg, NULL, dstImg,
|
pixman_image_composite( PIXMAN_OP_SRC, srcImg, NULL, dstImg, 0, 0, 0, 0, 0, 0, screenSize.x,
|
||||||
0, 0, 0, 0, 0, 0, screenSize.x, screenSize.y );
|
screenSize.y );
|
||||||
|
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
pixman_image_unref( srcImg );
|
pixman_image_unref( srcImg );
|
||||||
pixman_image_unref( dstImg );
|
pixman_image_unref( dstImg );
|
||||||
|
|
||||||
wxImage img( wxBufferWidth, screenSize.y, wxOutput, true );
|
wxImage img( wxBufferWidth, screenSize.y, wxOutput, true );
|
||||||
wxBitmap bmp( img );
|
wxBitmap bmp( img );
|
||||||
wxMemoryDC mdc( bmp );
|
wxMemoryDC mdc( bmp );
|
||||||
wxClientDC clientDC( this );
|
wxClientDC clientDC( this );
|
||||||
|
|
||||||
|
@ -1379,13 +1382,9 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case TARGET_CACHED:
|
case TARGET_CACHED:
|
||||||
case TARGET_NONCACHED:
|
case TARGET_NONCACHED: compositor->SetBuffer( mainBuffer ); break;
|
||||||
compositor->SetBuffer( mainBuffer );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TARGET_OVERLAY:
|
case TARGET_OVERLAY: compositor->SetBuffer( overlayBuffer ); break;
|
||||||
compositor->SetBuffer( overlayBuffer );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTarget = aTarget;
|
currentTarget = aTarget;
|
||||||
|
@ -1408,13 +1407,8 @@ void CAIRO_GAL::ClearTarget( RENDER_TARGET aTarget )
|
||||||
// Cached and noncached items are rendered to the same buffer
|
// Cached and noncached items are rendered to the same buffer
|
||||||
default:
|
default:
|
||||||
case TARGET_CACHED:
|
case TARGET_CACHED:
|
||||||
case TARGET_NONCACHED:
|
case TARGET_NONCACHED: compositor->SetBuffer( mainBuffer ); break;
|
||||||
compositor->SetBuffer( mainBuffer );
|
case TARGET_OVERLAY: compositor->SetBuffer( overlayBuffer ); break;
|
||||||
break;
|
|
||||||
|
|
||||||
case TARGET_OVERLAY:
|
|
||||||
compositor->SetBuffer( overlayBuffer );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compositor->ClearBuffer( COLOR4D::BLACK );
|
compositor->ClearBuffer( COLOR4D::BLACK );
|
||||||
|
@ -1429,8 +1423,8 @@ void CAIRO_GAL::initSurface()
|
||||||
if( isInitialized )
|
if( isInitialized )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
surface = cairo_image_surface_create_for_data( bitmapBuffer, GAL_FORMAT,
|
surface = cairo_image_surface_create_for_data( bitmapBuffer, GAL_FORMAT, wxBufferWidth,
|
||||||
wxBufferWidth, screenSize.y, stride );
|
screenSize.y, stride );
|
||||||
|
|
||||||
context = cairo_create( surface );
|
context = cairo_create( surface );
|
||||||
|
|
||||||
|
@ -1438,6 +1432,7 @@ void CAIRO_GAL::initSurface()
|
||||||
cairo_status_t status = cairo_status( context );
|
cairo_status_t status = cairo_status( context );
|
||||||
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
|
wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT( "Cairo context creation error" ) );
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
currentContext = context;
|
currentContext = context;
|
||||||
|
|
||||||
isInitialized = true;
|
isInitialized = true;
|
||||||
|
@ -1461,10 +1456,12 @@ void CAIRO_GAL::deinitSurface()
|
||||||
void CAIRO_GAL::allocateBitmaps()
|
void CAIRO_GAL::allocateBitmaps()
|
||||||
{
|
{
|
||||||
wxBufferWidth = screenSize.x;
|
wxBufferWidth = screenSize.x;
|
||||||
while( ( ( wxBufferWidth * 3 ) % 4 ) != 0 ) wxBufferWidth++;
|
|
||||||
|
while( ( ( wxBufferWidth * 3 ) % 4 ) != 0 )
|
||||||
|
wxBufferWidth++;
|
||||||
|
|
||||||
// Create buffer, use the system independent Cairo context backend
|
// Create buffer, use the system independent Cairo context backend
|
||||||
stride = cairo_format_stride_for_width( GAL_FORMAT, wxBufferWidth );
|
stride = cairo_format_stride_for_width( GAL_FORMAT, wxBufferWidth );
|
||||||
bufferSize = stride * screenSize.y;
|
bufferSize = stride * screenSize.y;
|
||||||
|
|
||||||
wxASSERT( bitmapBuffer == nullptr );
|
wxASSERT( bitmapBuffer == nullptr );
|
||||||
|
@ -1520,7 +1517,6 @@ bool CAIRO_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
|
||||||
|
|
||||||
if( validCompositor && aOptions.cairo_antialiasing_mode != compositor->GetAntialiasingMode() )
|
if( validCompositor && aOptions.cairo_antialiasing_mode != compositor->GetAntialiasingMode() )
|
||||||
{
|
{
|
||||||
|
|
||||||
compositor->SetAntialiasingMode( options.cairo_antialiasing_mode );
|
compositor->SetAntialiasingMode( options.cairo_antialiasing_mode );
|
||||||
validCompositor = false;
|
validCompositor = false;
|
||||||
deinitSurface();
|
deinitSurface();
|
||||||
|
@ -1546,7 +1542,7 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
// For the drawing the start points, end points and increments have
|
// For the drawing the start points, end points and increments have
|
||||||
// to be calculated in world coordinates
|
// to be calculated in world coordinates
|
||||||
VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 );
|
VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 );
|
||||||
VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize );
|
VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize );
|
||||||
|
|
||||||
// Compute the line marker or point radius of the grid
|
// Compute the line marker or point radius of the grid
|
||||||
// Note: generic grids can't handle sub-pixel lines without
|
// Note: generic grids can't handle sub-pixel lines without
|
||||||
|
@ -1574,7 +1570,7 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
|
|
||||||
// If we cannot display the grid density, scale down by a tick size and
|
// If we cannot display the grid density, scale down by a tick size and
|
||||||
// try again. Eventually, we get some representation of the grid
|
// try again. Eventually, we get some representation of the grid
|
||||||
while( std::min( gridScreenSize.x, gridScreenSize.y ) <= gridThreshold )
|
while( std::min( gridScreenSize.x, gridScreenSize.y ) <= gridThreshold )
|
||||||
{
|
{
|
||||||
gridScreenSize = gridScreenSize * static_cast<double>( gridTick );
|
gridScreenSize = gridScreenSize * static_cast<double>( gridTick );
|
||||||
}
|
}
|
||||||
|
@ -1583,9 +1579,9 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
// visible screen area
|
// visible screen area
|
||||||
// Note: later any point coordinate will be offsetted by gridOrigin
|
// Note: later any point coordinate will be offsetted by gridOrigin
|
||||||
int gridStartX = KiROUND( ( worldStartPoint.x - gridOrigin.x ) / gridScreenSize.x );
|
int gridStartX = KiROUND( ( worldStartPoint.x - gridOrigin.x ) / gridScreenSize.x );
|
||||||
int gridEndX = KiROUND( ( worldEndPoint.x - gridOrigin.x ) / gridScreenSize.x );
|
int gridEndX = KiROUND( ( worldEndPoint.x - gridOrigin.x ) / gridScreenSize.x );
|
||||||
int gridStartY = KiROUND( ( worldStartPoint.y - gridOrigin.y ) / gridScreenSize.y );
|
int gridStartY = KiROUND( ( worldStartPoint.y - gridOrigin.y ) / gridScreenSize.y );
|
||||||
int gridEndY = KiROUND( ( worldEndPoint.y - gridOrigin.y ) / gridScreenSize.y );
|
int gridEndY = KiROUND( ( worldEndPoint.y - gridOrigin.y ) / gridScreenSize.y );
|
||||||
|
|
||||||
// Ensure start coordinate > end coordinate
|
// Ensure start coordinate > end coordinate
|
||||||
|
|
||||||
|
@ -1593,8 +1589,10 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
SWAP( gridStartY, >, gridEndY );
|
SWAP( gridStartY, >, gridEndY );
|
||||||
|
|
||||||
// Ensure the grid fills the screen
|
// Ensure the grid fills the screen
|
||||||
--gridStartX; ++gridEndX;
|
--gridStartX;
|
||||||
--gridStartY; ++gridEndY;
|
++gridEndX;
|
||||||
|
--gridStartY;
|
||||||
|
++gridEndY;
|
||||||
|
|
||||||
// Draw the grid behind all other layers
|
// Draw the grid behind all other layers
|
||||||
SetLayerDepth( depthRange.y * 0.75 );
|
SetLayerDepth( depthRange.y * 0.75 );
|
||||||
|
@ -1627,10 +1625,9 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
SetLineWidth( ( i % gridTick ) ? marker : doubleMarker );
|
SetLineWidth( ( i % gridTick ) ? marker : doubleMarker );
|
||||||
drawGridLine( VECTOR2D( x, gridStartY * gridScreenSize.y + gridOrigin.y ),
|
drawGridLine( VECTOR2D( x, gridStartY * gridScreenSize.y + gridOrigin.y ),
|
||||||
VECTOR2D( x, gridEndY * gridScreenSize.y + gridOrigin.y ) );
|
VECTOR2D( x, gridEndY * gridScreenSize.y + gridOrigin.y ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Dots or Crosses grid
|
else // Dots or Crosses grid
|
||||||
{
|
{
|
||||||
lineWidthIsOdd = true;
|
lineWidthIsOdd = true;
|
||||||
isStrokeEnabled = true;
|
isStrokeEnabled = true;
|
||||||
|
@ -1640,7 +1637,7 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
|
|
||||||
for( int i = gridStartX; i <= gridEndX; i++ )
|
for( int i = gridStartX; i <= gridEndX; i++ )
|
||||||
{
|
{
|
||||||
bool tickX = ( i % gridTick == 0 );
|
bool tickX = ( i % gridTick == 0 );
|
||||||
VECTOR2D pos{ i * gridScreenSize.x + gridOrigin.x,
|
VECTOR2D pos{ i * gridScreenSize.x + gridOrigin.x,
|
||||||
j * gridScreenSize.y + gridOrigin.y };
|
j * gridScreenSize.y + gridOrigin.y };
|
||||||
|
|
||||||
|
@ -1653,10 +1650,9 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||||
{
|
{
|
||||||
double doubleGridLineWidth = gridLineWidth * 2.0f;
|
double doubleGridLineWidth = gridLineWidth * 2.0f;
|
||||||
drawGridPoint( pos, ( tickX ) ? doubleGridLineWidth : gridLineWidth,
|
drawGridPoint( pos, ( tickX ) ? doubleGridLineWidth : gridLineWidth,
|
||||||
( tickY ) ? doubleGridLineWidth : gridLineWidth );
|
( tickY ) ? doubleGridLineWidth : gridLineWidth );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
|
* Copyright (C) 2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
* Author: Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -25,10 +27,10 @@
|
||||||
#include <wx/dcmemory.h>
|
#include <wx/dcmemory.h>
|
||||||
#include <wx/dcprint.h>
|
#include <wx/dcprint.h>
|
||||||
|
|
||||||
#ifdef NOMINMAX /* workaround for gdiplus.h */
|
#ifdef NOMINMAX /* workaround for gdiplus.h */
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
using std::min;
|
|
||||||
using std::max;
|
using std::max;
|
||||||
|
using std::min;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
|
@ -45,8 +47,10 @@ using std::max;
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
CAIRO_PRINT_CTX::CAIRO_PRINT_CTX( wxDC* aDC )
|
CAIRO_PRINT_CTX::CAIRO_PRINT_CTX( wxDC* aDC ) :
|
||||||
: m_gcdc( nullptr ), m_ctx( nullptr ), m_surface( nullptr )
|
m_gcdc( nullptr ),
|
||||||
|
m_ctx( nullptr ),
|
||||||
|
m_surface( nullptr )
|
||||||
{
|
{
|
||||||
if( wxPrinterDC* printerDC = dynamic_cast<wxPrinterDC*>( aDC ) )
|
if( wxPrinterDC* printerDC = dynamic_cast<wxPrinterDC*>( aDC ) )
|
||||||
m_gcdc = new wxGCDC( *printerDC );
|
m_gcdc = new wxGCDC( *printerDC );
|
||||||
|
@ -69,15 +73,18 @@ CAIRO_PRINT_CTX::CAIRO_PRINT_CTX( wxDC* aDC )
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
m_ctx = static_cast<cairo_t*>( gctx->GetNativeContext() );
|
m_ctx = static_cast<cairo_t*>( gctx->GetNativeContext() );
|
||||||
m_surface = cairo_get_target( m_ctx );
|
m_surface = cairo_get_target( m_ctx );
|
||||||
// On linux, cairo printers have 72 DPI by default.
|
|
||||||
// This is an unusable resolution for us.
|
// On linux, cairo printers have 72 DPI by default.
|
||||||
// A better resolution could be 4800 DPI (at 600 DPI, we still have minor
|
// This is an unusable resolution for us.
|
||||||
// but visible artifacts, for instance with arcs, but not at 4800 DPI)
|
// A better resolution could be 4800 DPI (at 600 DPI, we still have minor
|
||||||
// so modify the default:
|
// but visible artifacts, for instance with arcs, but not at 4800 DPI)
|
||||||
#define DEFAULT_DPI 72.0
|
// so modify the default:
|
||||||
#define KICAD_PRINTER_DPI 4800.0
|
#define DEFAULT_DPI 72.0
|
||||||
|
#define KICAD_PRINTER_DPI 4800.0
|
||||||
|
|
||||||
// our device scale is DEFAULT_DPI / KICAD_PRINTER_DPI
|
// our device scale is DEFAULT_DPI / KICAD_PRINTER_DPI
|
||||||
cairo_surface_set_device_scale( m_surface, DEFAULT_DPI/KICAD_PRINTER_DPI, DEFAULT_DPI/KICAD_PRINTER_DPI );
|
cairo_surface_set_device_scale( m_surface, DEFAULT_DPI / KICAD_PRINTER_DPI,
|
||||||
|
DEFAULT_DPI / KICAD_PRINTER_DPI );
|
||||||
m_dpi = KICAD_PRINTER_DPI;
|
m_dpi = KICAD_PRINTER_DPI;
|
||||||
#endif /* __WXGTK__ */
|
#endif /* __WXGTK__ */
|
||||||
|
|
||||||
|
@ -90,7 +97,7 @@ CAIRO_PRINT_CTX::CAIRO_PRINT_CTX( wxDC* aDC )
|
||||||
#endif /* __WXMSW__ */
|
#endif /* __WXMSW__ */
|
||||||
|
|
||||||
#ifdef __WXMAC__
|
#ifdef __WXMAC__
|
||||||
wxSize size = m_gcdc->GetSize();
|
wxSize size = m_gcdc->GetSize();
|
||||||
CGContextRef cg = (CGContextRef) gctx->GetNativeContext();
|
CGContextRef cg = (CGContextRef) gctx->GetNativeContext();
|
||||||
m_surface = cairo_quartz_surface_create_for_cg_context( cg, size.x, size.y );
|
m_surface = cairo_quartz_surface_create_for_cg_context( cg, size.x, size.y );
|
||||||
m_ctx = cairo_create( m_surface );
|
m_ctx = cairo_create( m_surface );
|
||||||
|
@ -124,9 +131,9 @@ CAIRO_PRINT_CTX::~CAIRO_PRINT_CTX()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CAIRO_PRINT_GAL::CAIRO_PRINT_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
CAIRO_PRINT_GAL::CAIRO_PRINT_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
||||||
std::unique_ptr<CAIRO_PRINT_CTX> aContext )
|
std::unique_ptr<CAIRO_PRINT_CTX> aContext ) :
|
||||||
: CAIRO_GAL_BASE( aDisplayOptions )
|
CAIRO_GAL_BASE( aDisplayOptions )
|
||||||
{
|
{
|
||||||
m_printCtx = std::move( aContext );
|
m_printCtx = std::move( aContext );
|
||||||
context = currentContext = m_printCtx->GetContext();
|
context = currentContext = m_printCtx->GetContext();
|
||||||
|
@ -144,7 +151,8 @@ CAIRO_PRINT_GAL::CAIRO_PRINT_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions,
|
||||||
void CAIRO_PRINT_GAL::ComputeWorldScreenMatrix()
|
void CAIRO_PRINT_GAL::ComputeWorldScreenMatrix()
|
||||||
{
|
{
|
||||||
worldScale = screenDPI * worldUnitLength * zoomFactor;
|
worldScale = screenDPI * worldUnitLength * zoomFactor;
|
||||||
const auto paperSizeIU = VECTOR2D( m_nativePaperSize.y, m_nativePaperSize.x ) /* inches */ / worldUnitLength; /* 1 inch in IU */
|
const auto paperSizeIU = VECTOR2D( m_nativePaperSize.y, m_nativePaperSize.x ) /* inches */
|
||||||
|
/ worldUnitLength; /* 1 inch in IU */
|
||||||
const auto paperSizeIUTransposed = VECTOR2D( paperSizeIU.y, paperSizeIU.x );
|
const auto paperSizeIUTransposed = VECTOR2D( paperSizeIU.y, paperSizeIU.x );
|
||||||
|
|
||||||
MATRIX3x3D scale, translation, flip, rotate, lookat;
|
MATRIX3x3D scale, translation, flip, rotate, lookat;
|
||||||
|
@ -192,7 +200,7 @@ void CAIRO_PRINT_GAL::SetSheetSize( const VECTOR2D& aSize )
|
||||||
{
|
{
|
||||||
// Convert aSize (inches) to pixels
|
// Convert aSize (inches) to pixels
|
||||||
SetScreenSize( VECTOR2I( std::ceil( aSize.x * screenDPI ) * 2,
|
SetScreenSize( VECTOR2I( std::ceil( aSize.x * screenDPI ) * 2,
|
||||||
std::ceil( aSize.y * screenDPI ) * 2 ) );
|
std::ceil( aSize.y * screenDPI ) * 2 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2016-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
* as published by the Free Software Foundation; either version 2
|
* as published by the Free Software Foundation; either version 2
|
||||||
* of the License, or (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, you may find one here:
|
* along with this program; if not, you may find one here:
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
* 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 search the http://www.gnu.org website for the version 2 license,
|
||||||
* or you may write to the Free Software Foundation, Inc.,
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gal/opengl/antialiasing.h>
|
#include <gal/opengl/antialiasing.h>
|
||||||
#include <gal/opengl/opengl_compositor.h>
|
#include <gal/opengl/opengl_compositor.h>
|
||||||
|
@ -39,8 +39,8 @@ using namespace KIGFX;
|
||||||
// ANTIALIASING_NONE
|
// ANTIALIASING_NONE
|
||||||
// =========================
|
// =========================
|
||||||
|
|
||||||
ANTIALIASING_NONE::ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor )
|
ANTIALIASING_NONE::ANTIALIASING_NONE( OPENGL_COMPOSITOR* aCompositor ) :
|
||||||
: compositor( aCompositor )
|
compositor( aCompositor )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,49 +88,49 @@ unsigned int ANTIALIASING_NONE::CreateBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
void draw_fullscreen_primitive()
|
void draw_fullscreen_primitive()
|
||||||
{
|
{
|
||||||
glMatrixMode( GL_MODELVIEW );
|
glMatrixMode( GL_MODELVIEW );
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glMatrixMode( GL_PROJECTION );
|
glMatrixMode( GL_PROJECTION );
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
|
|
||||||
glBegin( GL_TRIANGLES );
|
glBegin( GL_TRIANGLES );
|
||||||
glTexCoord2f( 0.0f, 1.0f );
|
glTexCoord2f( 0.0f, 1.0f );
|
||||||
glVertex2f( -1.0f, 1.0f );
|
glVertex2f( -1.0f, 1.0f );
|
||||||
glTexCoord2f( 0.0f, 0.0f );
|
glTexCoord2f( 0.0f, 0.0f );
|
||||||
glVertex2f( -1.0f, -1.0f );
|
glVertex2f( -1.0f, -1.0f );
|
||||||
glTexCoord2f( 1.0f, 1.0f );
|
glTexCoord2f( 1.0f, 1.0f );
|
||||||
glVertex2f( 1.0f, 1.0f );
|
glVertex2f( 1.0f, 1.0f );
|
||||||
|
|
||||||
glTexCoord2f( 1.0f, 1.0f );
|
glTexCoord2f( 1.0f, 1.0f );
|
||||||
glVertex2f( 1.0f, 1.0f );
|
glVertex2f( 1.0f, 1.0f );
|
||||||
glTexCoord2f( 0.0f, 0.0f );
|
glTexCoord2f( 0.0f, 0.0f );
|
||||||
glVertex2f( -1.0f, -1.0f );
|
glVertex2f( -1.0f, -1.0f );
|
||||||
glTexCoord2f( 1.0f, 0.0f );
|
glTexCoord2f( 1.0f, 0.0f );
|
||||||
glVertex2f( 1.0f, -1.0f );
|
glVertex2f( 1.0f, -1.0f );
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glPopMatrix();
|
|
||||||
glMatrixMode( GL_MODELVIEW );
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
glMatrixMode( GL_MODELVIEW );
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// ANTIALIASING_SUPERSAMPLING
|
// ANTIALIASING_SUPERSAMPLING
|
||||||
// =========================
|
// =========================
|
||||||
|
|
||||||
ANTIALIASING_SUPERSAMPLING::ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor,
|
ANTIALIASING_SUPERSAMPLING::ANTIALIASING_SUPERSAMPLING( OPENGL_COMPOSITOR* aCompositor,
|
||||||
SUPERSAMPLING_MODE aMode )
|
SUPERSAMPLING_MODE aMode ) :
|
||||||
: compositor( aCompositor ), mode( aMode ), ssaaMainBuffer( 0 ),
|
compositor( aCompositor ),
|
||||||
areBuffersCreated( false ), areShadersCreated( false )
|
mode( aMode ), ssaaMainBuffer( 0 ), areBuffersCreated( false ), areShadersCreated( false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,17 +139,23 @@ bool ANTIALIASING_SUPERSAMPLING::Init()
|
||||||
{
|
{
|
||||||
if( mode == SUPERSAMPLING_MODE::X4 && !areShadersCreated )
|
if( mode == SUPERSAMPLING_MODE::X4 && !areShadersCreated )
|
||||||
{
|
{
|
||||||
x4_shader = std::make_unique<SHADER>( );
|
x4_shader = std::make_unique<SHADER>();
|
||||||
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, BUILTIN_SHADERS::ssaa_x4_vertex_shader );
|
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX,
|
||||||
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, BUILTIN_SHADERS::ssaa_x4_fragment_shader );
|
BUILTIN_SHADERS::ssaa_x4_vertex_shader );
|
||||||
|
x4_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT,
|
||||||
|
BUILTIN_SHADERS::ssaa_x4_fragment_shader );
|
||||||
x4_shader->Link();
|
x4_shader->Link();
|
||||||
checkGlError( "linking supersampling x4 shader" );
|
checkGlError( "linking supersampling x4 shader" );
|
||||||
|
|
||||||
GLint source_parameter = x4_shader->AddParameter( "source" ); checkGlError( "getting pass 1 colorTex" );
|
GLint source_parameter = x4_shader->AddParameter( "source" );
|
||||||
|
checkGlError( "getting pass 1 colorTex" );
|
||||||
|
|
||||||
x4_shader->Use(); checkGlError( "using pass 1 shader" );
|
x4_shader->Use();
|
||||||
x4_shader->SetParameter( source_parameter, 0 ); checkGlError( "setting colorTex uniform" );
|
checkGlError( "using pass 1 shader" );
|
||||||
x4_shader->Deactivate(); checkGlError( "deactivating pass 2 shader" );
|
x4_shader->SetParameter( source_parameter, 0 );
|
||||||
|
checkGlError( "setting colorTex uniform" );
|
||||||
|
x4_shader->Deactivate();
|
||||||
|
checkGlError( "deactivating pass 2 shader" );
|
||||||
|
|
||||||
areShadersCreated = true;
|
areShadersCreated = true;
|
||||||
}
|
}
|
||||||
|
@ -232,9 +238,11 @@ unsigned int ANTIALIASING_SUPERSAMPLING::CreateBuffer()
|
||||||
// ANTIALIASING_SMAA
|
// ANTIALIASING_SMAA
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
ANTIALIASING_SMAA::ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality )
|
ANTIALIASING_SMAA::ANTIALIASING_SMAA( OPENGL_COMPOSITOR* aCompositor, SMAA_QUALITY aQuality ) :
|
||||||
: areBuffersInitialized( false ), shadersLoaded( false ),
|
areBuffersInitialized( false ),
|
||||||
quality( aQuality ), compositor( aCompositor )
|
shadersLoaded( false ),
|
||||||
|
quality( aQuality ),
|
||||||
|
compositor( aCompositor )
|
||||||
{
|
{
|
||||||
smaaBaseBuffer = 0;
|
smaaBaseBuffer = 0;
|
||||||
smaaEdgesBuffer = 0;
|
smaaEdgesBuffer = 0;
|
||||||
|
@ -266,7 +274,8 @@ void ANTIALIASING_SMAA::loadShaders()
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT, 0, GL_RG, GL_UNSIGNED_BYTE, areaTexBytes );
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT, 0, GL_RG,
|
||||||
|
GL_UNSIGNED_BYTE, areaTexBytes );
|
||||||
checkGlError( "loading smaa area tex" );
|
checkGlError( "loading smaa area tex" );
|
||||||
|
|
||||||
glGenTextures( 1, &smaaSearchTex );
|
glGenTextures( 1, &smaaSearchTex );
|
||||||
|
@ -275,7 +284,8 @@ void ANTIALIASING_SMAA::loadShaders()
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
||||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 0, GL_RED, GL_UNSIGNED_BYTE, searchTexBytes );
|
glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, 0, GL_RED,
|
||||||
|
GL_UNSIGNED_BYTE, searchTexBytes );
|
||||||
checkGlError( "loading smaa search tex" );
|
checkGlError( "loading smaa search tex" );
|
||||||
|
|
||||||
std::string quality_string;
|
std::string quality_string;
|
||||||
|
@ -307,70 +317,93 @@ uniform vec4 SMAA_RT_METRICS;
|
||||||
uniform vec4 SMAA_RT_METRICS;
|
uniform vec4 SMAA_RT_METRICS;
|
||||||
)SHADER" );
|
)SHADER" );
|
||||||
|
|
||||||
std::string smaa_source =
|
std::string smaa_source = std::string( BUILTIN_SHADERS::smaa_base_shader_p1 )
|
||||||
std::string( BUILTIN_SHADERS::smaa_base_shader_p1 )
|
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p2 )
|
||||||
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p2 )
|
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p3 )
|
||||||
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p3 )
|
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p4 );
|
||||||
+ std::string( BUILTIN_SHADERS::smaa_base_shader_p4 );
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up pass 1 Shader
|
// Set up pass 1 Shader
|
||||||
//
|
//
|
||||||
pass_1_shader = std::make_unique<SHADER>( );
|
pass_1_shader = std::make_unique<SHADER>();
|
||||||
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
|
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble, quality_string,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_vertex_shader );
|
smaa_source, BUILTIN_SHADERS::smaa_pass_1_vertex_shader );
|
||||||
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
pass_1_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_1_fragment_shader );
|
quality_string, smaa_source,
|
||||||
|
BUILTIN_SHADERS::smaa_pass_1_fragment_shader );
|
||||||
pass_1_shader->Link();
|
pass_1_shader->Link();
|
||||||
checkGlError( "linking pass 1 shader" );
|
checkGlError( "linking pass 1 shader" );
|
||||||
|
|
||||||
GLint smaaColorTexParameter = pass_1_shader->AddParameter( "colorTex" ); checkGlError( "pass1: getting colorTex uniform" );
|
GLint smaaColorTexParameter = pass_1_shader->AddParameter( "colorTex" );
|
||||||
pass_1_metrics = pass_1_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass1: getting metrics uniform" );
|
checkGlError( "pass1: getting colorTex uniform" );
|
||||||
|
pass_1_metrics = pass_1_shader->AddParameter( "SMAA_RT_METRICS" );
|
||||||
|
checkGlError( "pass1: getting metrics uniform" );
|
||||||
|
|
||||||
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
|
pass_1_shader->Use();
|
||||||
pass_1_shader->SetParameter( smaaColorTexParameter, 0 ); checkGlError( "pass1: setting colorTex uniform" );
|
checkGlError( "pass1: using shader" );
|
||||||
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
|
pass_1_shader->SetParameter( smaaColorTexParameter, 0 );
|
||||||
|
checkGlError( "pass1: setting colorTex uniform" );
|
||||||
|
pass_1_shader->Deactivate();
|
||||||
|
checkGlError( "pass1: deactivating shader" );
|
||||||
|
|
||||||
//
|
//
|
||||||
// set up pass 2 shader
|
// set up pass 2 shader
|
||||||
//
|
//
|
||||||
pass_2_shader = std::make_unique<SHADER>( );
|
pass_2_shader = std::make_unique<SHADER>();
|
||||||
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
|
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble, quality_string,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_vertex_shader );
|
smaa_source, BUILTIN_SHADERS::smaa_pass_2_vertex_shader );
|
||||||
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
pass_2_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_2_fragment_shader );
|
quality_string, smaa_source,
|
||||||
|
BUILTIN_SHADERS::smaa_pass_2_fragment_shader );
|
||||||
pass_2_shader->Link();
|
pass_2_shader->Link();
|
||||||
checkGlError( "linking pass 2 shader" );
|
checkGlError( "linking pass 2 shader" );
|
||||||
|
|
||||||
GLint smaaEdgesTexParameter = pass_2_shader->AddParameter( "edgesTex" ); checkGlError( "pass2: getting colorTex uniform" );
|
GLint smaaEdgesTexParameter = pass_2_shader->AddParameter( "edgesTex" );
|
||||||
GLint smaaAreaTexParameter = pass_2_shader->AddParameter( "areaTex" ); checkGlError( "pass2: getting areaTex uniform" );
|
checkGlError( "pass2: getting colorTex uniform" );
|
||||||
GLint smaaSearchTexParameter = pass_2_shader->AddParameter( "searchTex" ); checkGlError( "pass2: getting searchTex uniform" );
|
GLint smaaAreaTexParameter = pass_2_shader->AddParameter( "areaTex" );
|
||||||
pass_2_metrics = pass_2_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass2: getting metrics uniform" );
|
checkGlError( "pass2: getting areaTex uniform" );
|
||||||
|
GLint smaaSearchTexParameter = pass_2_shader->AddParameter( "searchTex" );
|
||||||
|
checkGlError( "pass2: getting searchTex uniform" );
|
||||||
|
pass_2_metrics = pass_2_shader->AddParameter( "SMAA_RT_METRICS" );
|
||||||
|
checkGlError( "pass2: getting metrics uniform" );
|
||||||
|
|
||||||
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
|
pass_2_shader->Use();
|
||||||
pass_2_shader->SetParameter( smaaEdgesTexParameter, 0 ); checkGlError( "pass2: setting colorTex uniform" );
|
checkGlError( "pass2: using shader" );
|
||||||
pass_2_shader->SetParameter( smaaAreaTexParameter, 1 ); checkGlError( "pass2: setting areaTex uniform" );
|
pass_2_shader->SetParameter( smaaEdgesTexParameter, 0 );
|
||||||
pass_2_shader->SetParameter( smaaSearchTexParameter, 3 ); checkGlError( "pass2: setting searchTex uniform" );
|
checkGlError( "pass2: setting colorTex uniform" );
|
||||||
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
|
pass_2_shader->SetParameter( smaaAreaTexParameter, 1 );
|
||||||
|
checkGlError( "pass2: setting areaTex uniform" );
|
||||||
|
pass_2_shader->SetParameter( smaaSearchTexParameter, 3 );
|
||||||
|
checkGlError( "pass2: setting searchTex uniform" );
|
||||||
|
pass_2_shader->Deactivate();
|
||||||
|
checkGlError( "pass2: deactivating shader" );
|
||||||
|
|
||||||
//
|
//
|
||||||
// set up pass 3 shader
|
// set up pass 3 shader
|
||||||
//
|
//
|
||||||
pass_3_shader = std::make_unique<SHADER>( );
|
pass_3_shader = std::make_unique<SHADER>();
|
||||||
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble,
|
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, vert_preamble, quality_string,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_vertex_shader );
|
smaa_source, BUILTIN_SHADERS::smaa_pass_3_vertex_shader );
|
||||||
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
pass_3_shader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, frag_preamble,
|
||||||
quality_string, smaa_source, BUILTIN_SHADERS::smaa_pass_3_fragment_shader );
|
quality_string, smaa_source,
|
||||||
|
BUILTIN_SHADERS::smaa_pass_3_fragment_shader );
|
||||||
pass_3_shader->Link();
|
pass_3_shader->Link();
|
||||||
|
|
||||||
GLint smaaP3ColorTexParameter = pass_3_shader->AddParameter( "colorTex" ); checkGlError( "pass3: getting colorTex uniform" );
|
GLint smaaP3ColorTexParameter = pass_3_shader->AddParameter( "colorTex" );
|
||||||
GLint smaaBlendTexParameter = pass_3_shader->AddParameter( "blendTex" ); checkGlError( "pass3: getting blendTex uniform" );
|
checkGlError( "pass3: getting colorTex uniform" );
|
||||||
pass_3_metrics = pass_3_shader->AddParameter( "SMAA_RT_METRICS" ); checkGlError( "pass3: getting metrics uniform" );
|
GLint smaaBlendTexParameter = pass_3_shader->AddParameter( "blendTex" );
|
||||||
|
checkGlError( "pass3: getting blendTex uniform" );
|
||||||
|
pass_3_metrics = pass_3_shader->AddParameter( "SMAA_RT_METRICS" );
|
||||||
|
checkGlError( "pass3: getting metrics uniform" );
|
||||||
|
|
||||||
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
|
pass_3_shader->Use();
|
||||||
pass_3_shader->SetParameter( smaaP3ColorTexParameter, 0 ); checkGlError( "pass3: setting colorTex uniform" );
|
checkGlError( "pass3: using shader" );
|
||||||
pass_3_shader->SetParameter( smaaBlendTexParameter, 1 ); checkGlError( "pass3: setting blendTex uniform" );
|
pass_3_shader->SetParameter( smaaP3ColorTexParameter, 0 );
|
||||||
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
|
checkGlError( "pass3: setting colorTex uniform" );
|
||||||
|
pass_3_shader->SetParameter( smaaBlendTexParameter, 1 );
|
||||||
|
checkGlError( "pass3: setting blendTex uniform" );
|
||||||
|
pass_3_shader->Deactivate();
|
||||||
|
checkGlError( "pass3: deactivating shader" );
|
||||||
|
|
||||||
shadersLoaded = true;
|
shadersLoaded = true;
|
||||||
}
|
}
|
||||||
|
@ -380,20 +413,29 @@ void ANTIALIASING_SMAA::updateUniforms()
|
||||||
{
|
{
|
||||||
auto dims = compositor->GetScreenSize();
|
auto dims = compositor->GetScreenSize();
|
||||||
|
|
||||||
pass_1_shader->Use(); checkGlError( "pass1: using shader" );
|
pass_1_shader->Use();
|
||||||
pass_1_shader->SetParameter( pass_1_metrics,
|
checkGlError( "pass1: using shader" );
|
||||||
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass1: setting metrics uniform" );
|
pass_1_shader->SetParameter( pass_1_metrics, 1.f / float( dims.x ), 1.f / float( dims.y ),
|
||||||
pass_1_shader->Deactivate(); checkGlError( "pass1: deactivating shader" );
|
float( dims.x ), float( dims.y ) );
|
||||||
|
checkGlError( "pass1: setting metrics uniform" );
|
||||||
|
pass_1_shader->Deactivate();
|
||||||
|
checkGlError( "pass1: deactivating shader" );
|
||||||
|
|
||||||
pass_2_shader->Use(); checkGlError( "pass2: using shader" );
|
pass_2_shader->Use();
|
||||||
pass_2_shader->SetParameter( pass_2_metrics,
|
checkGlError( "pass2: using shader" );
|
||||||
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass2: setting metrics uniform" );
|
pass_2_shader->SetParameter( pass_2_metrics, 1.f / float( dims.x ), 1.f / float( dims.y ),
|
||||||
pass_2_shader->Deactivate(); checkGlError( "pass2: deactivating shader" );
|
float( dims.x ), float( dims.y ) );
|
||||||
|
checkGlError( "pass2: setting metrics uniform" );
|
||||||
|
pass_2_shader->Deactivate();
|
||||||
|
checkGlError( "pass2: deactivating shader" );
|
||||||
|
|
||||||
pass_3_shader->Use(); checkGlError( "pass3: using shader" );
|
pass_3_shader->Use();
|
||||||
pass_3_shader->SetParameter( pass_3_metrics,
|
checkGlError( "pass3: using shader" );
|
||||||
1.f / float( dims.x ), 1.f / float( dims.y ), float( dims.x ), float( dims.y ) ); checkGlError( "pass3: setting metrics uniform" );
|
pass_3_shader->SetParameter( pass_3_metrics, 1.f / float( dims.x ), 1.f / float( dims.y ),
|
||||||
pass_3_shader->Deactivate(); checkGlError( "pass3: deactivating shader" );
|
float( dims.x ), float( dims.y ) );
|
||||||
|
checkGlError( "pass3: setting metrics uniform" );
|
||||||
|
pass_3_shader->Deactivate();
|
||||||
|
checkGlError( "pass3: deactivating shader" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -451,30 +493,31 @@ void ANTIALIASING_SMAA::Begin()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
void draw_fullscreen_triangle()
|
{
|
||||||
{
|
void draw_fullscreen_triangle()
|
||||||
glMatrixMode( GL_MODELVIEW );
|
{
|
||||||
glPushMatrix();
|
glMatrixMode( GL_MODELVIEW );
|
||||||
glLoadIdentity();
|
glPushMatrix();
|
||||||
glMatrixMode( GL_PROJECTION );
|
glLoadIdentity();
|
||||||
glPushMatrix();
|
glMatrixMode( GL_PROJECTION );
|
||||||
glLoadIdentity();
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
glBegin( GL_TRIANGLES );
|
glBegin( GL_TRIANGLES );
|
||||||
glTexCoord2f( 0.0f, 1.0f );
|
glTexCoord2f( 0.0f, 1.0f );
|
||||||
glVertex2f( -1.0f, 1.0f );
|
glVertex2f( -1.0f, 1.0f );
|
||||||
glTexCoord2f( 0.0f, -1.0f );
|
glTexCoord2f( 0.0f, -1.0f );
|
||||||
glVertex2f( -1.0f, -3.0f );
|
glVertex2f( -1.0f, -3.0f );
|
||||||
glTexCoord2f( 2.0f, 1.0f );
|
glTexCoord2f( 2.0f, 1.0f );
|
||||||
glVertex2f( 3.0f, 1.0f );
|
glVertex2f( 3.0f, 1.0f );
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
glMatrixMode( GL_MODELVIEW );
|
glMatrixMode( GL_MODELVIEW );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
void ANTIALIASING_SMAA::Present()
|
void ANTIALIASING_SMAA::Present()
|
||||||
|
@ -492,8 +535,10 @@ void ANTIALIASING_SMAA::Present()
|
||||||
compositor->ClearBuffer( COLOR4D::BLACK );
|
compositor->ClearBuffer( COLOR4D::BLACK );
|
||||||
|
|
||||||
glActiveTexture( GL_TEXTURE0 );
|
glActiveTexture( GL_TEXTURE0 );
|
||||||
glBindTexture( GL_TEXTURE_2D, sourceTexture ); checkGlError( "binding colorTex" );
|
glBindTexture( GL_TEXTURE_2D, sourceTexture );
|
||||||
pass_1_shader->Use(); checkGlError( "using smaa pass 1 shader" );
|
checkGlError( "binding colorTex" );
|
||||||
|
pass_1_shader->Use();
|
||||||
|
checkGlError( "using smaa pass 1 shader" );
|
||||||
draw_fullscreen_triangle();
|
draw_fullscreen_triangle();
|
||||||
pass_1_shader->Deactivate();
|
pass_1_shader->Deactivate();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright 2013-2017 CERN
|
* Copyright 2013-2017 CERN
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -48,7 +48,11 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
CACHED_CONTAINER::CACHED_CONTAINER( unsigned int aSize ) :
|
CACHED_CONTAINER::CACHED_CONTAINER( unsigned int aSize ) :
|
||||||
VERTEX_CONTAINER( aSize ), m_item( NULL ), m_chunkSize( 0 ), m_chunkOffset( 0 ), m_maxIndex( 0 )
|
VERTEX_CONTAINER( aSize ),
|
||||||
|
m_item( NULL ),
|
||||||
|
m_chunkSize( 0 ),
|
||||||
|
m_chunkOffset( 0 ),
|
||||||
|
m_maxIndex( 0 )
|
||||||
{
|
{
|
||||||
// In the beginning there is only free space
|
// In the beginning there is only free space
|
||||||
m_freeChunks.insert( std::make_pair( aSize, 0 ) );
|
m_freeChunks.insert( std::make_pair( aSize, 0 ) );
|
||||||
|
@ -60,7 +64,7 @@ void CACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
|
||||||
assert( aItem != NULL );
|
assert( aItem != NULL );
|
||||||
|
|
||||||
unsigned int itemSize = aItem->GetSize();
|
unsigned int itemSize = aItem->GetSize();
|
||||||
m_item = aItem;
|
m_item = aItem;
|
||||||
m_chunkSize = itemSize;
|
m_chunkSize = itemSize;
|
||||||
|
|
||||||
// Get the previously set offset if the item was stored previously
|
// Get the previously set offset if the item was stored previously
|
||||||
|
@ -149,7 +153,7 @@ void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
|
||||||
int size = aItem->GetSize();
|
int size = aItem->GetSize();
|
||||||
|
|
||||||
if( size == 0 )
|
if( size == 0 )
|
||||||
return; // Item is not stored here
|
return; // Item is not stored here
|
||||||
|
|
||||||
int offset = aItem->GetOffset();
|
int offset = aItem->GetOffset();
|
||||||
|
|
||||||
|
@ -236,7 +240,7 @@ bool CACHED_CONTAINER::reallocate( unsigned int aSize )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameters of the allocated chunk
|
// Parameters of the allocated chunk
|
||||||
unsigned int newChunkSize = getChunkSize( *newChunk );
|
unsigned int newChunkSize = getChunkSize( *newChunk );
|
||||||
unsigned int newChunkOffset = getChunkOffset( *newChunk );
|
unsigned int newChunkOffset = getChunkOffset( *newChunk );
|
||||||
|
|
||||||
assert( newChunkSize >= aSize );
|
assert( newChunkSize >= aSize );
|
||||||
|
@ -269,12 +273,12 @@ void CACHED_CONTAINER::defragment( VERTEX* aTarget )
|
||||||
{
|
{
|
||||||
// Defragmentation
|
// Defragmentation
|
||||||
ITEMS::iterator it, it_end;
|
ITEMS::iterator it, it_end;
|
||||||
int newOffset = 0;
|
int newOffset = 0;
|
||||||
|
|
||||||
for( VERTEX_ITEM* item : m_items )
|
for( VERTEX_ITEM* item : m_items )
|
||||||
{
|
{
|
||||||
int itemOffset = item->GetOffset();
|
int itemOffset = item->GetOffset();
|
||||||
int itemSize = item->GetSize();
|
int itemSize = item->GetSize();
|
||||||
|
|
||||||
// Move an item to the new container
|
// Move an item to the new container
|
||||||
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VERTEX_SIZE );
|
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VERTEX_SIZE );
|
||||||
|
@ -322,8 +326,8 @@ void CACHED_CONTAINER::mergeFreeChunks()
|
||||||
freeChunks.sort();
|
freeChunks.sort();
|
||||||
|
|
||||||
std::list<CHUNK>::const_iterator itf, itf_end;
|
std::list<CHUNK>::const_iterator itf, itf_end;
|
||||||
unsigned int offset = freeChunks.front().first;
|
unsigned int offset = freeChunks.front().first;
|
||||||
unsigned int size = freeChunks.front().second;
|
unsigned int size = freeChunks.front().second;
|
||||||
freeChunks.pop_front();
|
freeChunks.pop_front();
|
||||||
|
|
||||||
for( itf = freeChunks.begin(), itf_end = freeChunks.end(); itf != itf_end; ++itf )
|
for( itf = freeChunks.begin(), itf_end = freeChunks.end(); itf != itf_end; ++itf )
|
||||||
|
@ -340,8 +344,7 @@ void CACHED_CONTAINER::mergeFreeChunks()
|
||||||
m_freeChunks.insert( std::make_pair( size, offset ) );
|
m_freeChunks.insert( std::make_pair( size, offset ) );
|
||||||
// and let's check the next chunk
|
// and let's check the next chunk
|
||||||
offset = itf->first;
|
offset = itf->first;
|
||||||
size = itf->second;
|
size = itf->second;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +381,7 @@ void CACHED_CONTAINER::test()
|
||||||
{
|
{
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
// Free space check
|
// Free space check
|
||||||
unsigned int freeSpace = 0;
|
unsigned int freeSpace = 0;
|
||||||
FREE_CHUNK_MAP::iterator itf;
|
FREE_CHUNK_MAP::iterator itf;
|
||||||
|
|
||||||
for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
|
for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
|
||||||
|
@ -387,8 +390,9 @@ void CACHED_CONTAINER::test()
|
||||||
assert( freeSpace == m_freeSpace );
|
assert( freeSpace == m_freeSpace );
|
||||||
|
|
||||||
// Used space check
|
// Used space check
|
||||||
unsigned int used_space = 0;
|
unsigned int used_space = 0;
|
||||||
ITEMS::iterator itr;
|
ITEMS::iterator itr;
|
||||||
|
|
||||||
for( itr = m_items.begin(); itr != m_items.end(); ++itr )
|
for( itr = m_items.begin(); itr != m_items.end(); ++itr )
|
||||||
used_space += ( *itr )->GetSize();
|
used_space += ( *itr )->GetSize();
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright 2013-2017 CERN
|
* Copyright 2013-2017 CERN
|
||||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
|
@ -30,25 +30,26 @@
|
||||||
#include <gal/opengl/shader.h>
|
#include <gal/opengl/shader.h>
|
||||||
#include <gal/opengl/utils.h>
|
#include <gal/opengl/utils.h>
|
||||||
|
|
||||||
|
#include <wx/log.h>
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
#include <wx/log.h>
|
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
CACHED_CONTAINER_GPU::CACHED_CONTAINER_GPU( unsigned int aSize ) :
|
CACHED_CONTAINER_GPU::CACHED_CONTAINER_GPU( unsigned int aSize ) :
|
||||||
CACHED_CONTAINER( aSize ), m_isMapped( false ), m_glBufferHandle( -1 )
|
CACHED_CONTAINER( aSize ), m_isMapped( false ), m_glBufferHandle( -1 )
|
||||||
{
|
{
|
||||||
m_useCopyBuffer = GLEW_ARB_copy_buffer;
|
m_useCopyBuffer = GLEW_ARB_copy_buffer;
|
||||||
|
|
||||||
wxString vendor( glGetString(GL_VENDOR) );
|
wxString vendor( glGetString( GL_VENDOR ) );
|
||||||
|
|
||||||
// workaround for intel GPU drivers: disable glCopyBuffer, causes crashes/freezes on
|
// workaround for intel GPU drivers: disable glCopyBuffer, causes crashes/freezes on
|
||||||
// certain driver versions
|
// certain driver versions
|
||||||
if( vendor.Contains ( "Intel " ) || vendor.Contains ( "etnaviv" ) )
|
if( vendor.Contains( "Intel " ) || vendor.Contains( "etnaviv" ) )
|
||||||
{
|
{
|
||||||
m_useCopyBuffer = false;
|
m_useCopyBuffer = false;
|
||||||
}
|
}
|
||||||
|
@ -92,6 +93,8 @@ void CACHED_CONTAINER_GPU::Unmap()
|
||||||
{
|
{
|
||||||
wxCHECK( IsMapped(), /*void*/ );
|
wxCHECK( IsMapped(), /*void*/ );
|
||||||
|
|
||||||
|
// This gets called from ~CACHED_CONTAINER_GPU. To avoid throwing an exception from
|
||||||
|
// the dtor, catch it here instead.
|
||||||
glUnmapBuffer( GL_ARRAY_BUFFER );
|
glUnmapBuffer( GL_ARRAY_BUFFER );
|
||||||
checkGlError( "unmapping vertices buffer" );
|
checkGlError( "unmapping vertices buffer" );
|
||||||
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||||
|
@ -110,7 +113,8 @@ bool CACHED_CONTAINER_GPU::defragmentResize( unsigned int aNewSize )
|
||||||
wxCHECK( IsMapped(), false );
|
wxCHECK( IsMapped(), false );
|
||||||
|
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
||||||
wxT( "Resizing & defragmenting container from %d to %d" ), m_currentSize, aNewSize );
|
wxT( "Resizing & defragmenting container from %d to %d" ), m_currentSize,
|
||||||
|
aNewSize );
|
||||||
|
|
||||||
// No shrinking if we cannot fit all the data
|
// No shrinking if we cannot fit all the data
|
||||||
if( usedSpace() > aNewSize )
|
if( usedSpace() > aNewSize )
|
||||||
|
@ -140,18 +144,18 @@ bool CACHED_CONTAINER_GPU::defragmentResize( unsigned int aNewSize )
|
||||||
checkGlError( "creating buffer during defragmentation" );
|
checkGlError( "creating buffer during defragmentation" );
|
||||||
|
|
||||||
ITEMS::iterator it, it_end;
|
ITEMS::iterator it, it_end;
|
||||||
int newOffset = 0;
|
int newOffset = 0;
|
||||||
|
|
||||||
// Defragmentation
|
// Defragmentation
|
||||||
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
|
for( it = m_items.begin(), it_end = m_items.end(); it != it_end; ++it )
|
||||||
{
|
{
|
||||||
VERTEX_ITEM* item = *it;
|
VERTEX_ITEM* item = *it;
|
||||||
int itemOffset = item->GetOffset();
|
int itemOffset = item->GetOffset();
|
||||||
int itemSize = item->GetSize();
|
int itemSize = item->GetSize();
|
||||||
|
|
||||||
// Move an item to the new container
|
// Move an item to the new container
|
||||||
glCopyBufferSubData( GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
|
glCopyBufferSubData( GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, itemOffset * VERTEX_SIZE,
|
||||||
itemOffset * VERTEX_SIZE, newOffset * VERTEX_SIZE, itemSize * VERTEX_SIZE );
|
newOffset * VERTEX_SIZE, itemSize * VERTEX_SIZE );
|
||||||
|
|
||||||
// Update new offset
|
// Update new offset
|
||||||
item->setOffset( newOffset );
|
item->setOffset( newOffset );
|
||||||
|
@ -164,8 +168,8 @@ bool CACHED_CONTAINER_GPU::defragmentResize( unsigned int aNewSize )
|
||||||
if( m_item->GetSize() > 0 )
|
if( m_item->GetSize() > 0 )
|
||||||
{
|
{
|
||||||
glCopyBufferSubData( GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
|
glCopyBufferSubData( GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
|
||||||
m_item->GetOffset() * VERTEX_SIZE, newOffset * VERTEX_SIZE,
|
m_item->GetOffset() * VERTEX_SIZE, newOffset * VERTEX_SIZE,
|
||||||
m_item->GetSize() * VERTEX_SIZE );
|
m_item->GetSize() * VERTEX_SIZE );
|
||||||
|
|
||||||
m_item->setOffset( newOffset );
|
m_item->setOffset( newOffset );
|
||||||
m_chunkOffset = newOffset;
|
m_chunkOffset = newOffset;
|
||||||
|
@ -188,8 +192,7 @@ bool CACHED_CONTAINER_GPU::defragmentResize( unsigned int aNewSize )
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
totalTime.Stop();
|
totalTime.Stop();
|
||||||
|
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
wxLogTrace( "GAL_CACHED_CONTAINER_GPU", "Defragmented container storing %d vertices / %.1f ms",
|
||||||
"Defragmented container storing %d vertices / %.1f ms",
|
|
||||||
m_currentSize - m_freeSpace, totalTime.msecs() );
|
m_currentSize - m_freeSpace, totalTime.msecs() );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
|
@ -209,8 +212,8 @@ bool CACHED_CONTAINER_GPU::defragmentResizeMemcpy( unsigned int aNewSize )
|
||||||
wxCHECK( IsMapped(), false );
|
wxCHECK( IsMapped(), false );
|
||||||
|
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
||||||
wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ),
|
wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ), m_currentSize,
|
||||||
m_currentSize, aNewSize );
|
aNewSize );
|
||||||
|
|
||||||
// No shrinking if we cannot fit all the data
|
// No shrinking if we cannot fit all the data
|
||||||
if( usedSpace() > aNewSize )
|
if( usedSpace() > aNewSize )
|
||||||
|
@ -220,7 +223,7 @@ bool CACHED_CONTAINER_GPU::defragmentResizeMemcpy( unsigned int aNewSize )
|
||||||
PROF_COUNTER totalTime;
|
PROF_COUNTER totalTime;
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
GLuint newBuffer;
|
GLuint newBuffer;
|
||||||
VERTEX* newBufferMem;
|
VERTEX* newBufferMem;
|
||||||
|
|
||||||
// Create the destination buffer
|
// Create the destination buffer
|
||||||
|
@ -254,8 +257,7 @@ bool CACHED_CONTAINER_GPU::defragmentResizeMemcpy( unsigned int aNewSize )
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
totalTime.Stop();
|
totalTime.Stop();
|
||||||
|
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER_GPU",
|
wxLogTrace( "GAL_CACHED_CONTAINER_GPU", "Defragmented container storing %d vertices / %.1f ms",
|
||||||
"Defragmented container storing %d vertices / %.1f ms",
|
|
||||||
m_currentSize - m_freeSpace, totalTime.msecs() );
|
m_currentSize - m_freeSpace, totalTime.msecs() );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright 2013-2017 CERN
|
* Copyright 2013-2017 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -40,7 +42,8 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
CACHED_CONTAINER_RAM::CACHED_CONTAINER_RAM( unsigned int aSize ) :
|
CACHED_CONTAINER_RAM::CACHED_CONTAINER_RAM( unsigned int aSize ) :
|
||||||
CACHED_CONTAINER( aSize ), m_verticesBuffer( 0 )
|
CACHED_CONTAINER( aSize ),
|
||||||
|
m_verticesBuffer( 0 )
|
||||||
{
|
{
|
||||||
glGenBuffers( 1, &m_verticesBuffer );
|
glGenBuffers( 1, &m_verticesBuffer );
|
||||||
checkGlError( "generating vertices buffer" );
|
checkGlError( "generating vertices buffer" );
|
||||||
|
@ -76,8 +79,8 @@ void CACHED_CONTAINER_RAM::Unmap()
|
||||||
bool CACHED_CONTAINER_RAM::defragmentResize( unsigned int aNewSize )
|
bool CACHED_CONTAINER_RAM::defragmentResize( unsigned int aNewSize )
|
||||||
{
|
{
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER",
|
wxLogTrace( "GAL_CACHED_CONTAINER",
|
||||||
wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ),
|
wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ), m_currentSize,
|
||||||
m_currentSize, aNewSize );
|
aNewSize );
|
||||||
|
|
||||||
// No shrinking if we cannot fit all the data
|
// No shrinking if we cannot fit all the data
|
||||||
if( usedSpace() > aNewSize )
|
if( usedSpace() > aNewSize )
|
||||||
|
@ -101,8 +104,7 @@ bool CACHED_CONTAINER_RAM::defragmentResize( unsigned int aNewSize )
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
totalTime.Stop();
|
totalTime.Stop();
|
||||||
|
|
||||||
wxLogTrace( "GAL_CACHED_CONTAINER",
|
wxLogTrace( "GAL_CACHED_CONTAINER", "Defragmented container storing %d vertices / %.1f ms",
|
||||||
"Defragmented container storing %d vertices / %.1f ms",
|
|
||||||
m_currentSize - m_freeSpace, totalTime.msecs() );
|
m_currentSize - m_freeSpace, totalTime.msecs() );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright 2013-2017 CERN
|
* Copyright 2013-2017 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -49,7 +51,11 @@ GPU_MANAGER* GPU_MANAGER::MakeManager( VERTEX_CONTAINER* aContainer )
|
||||||
|
|
||||||
|
|
||||||
GPU_MANAGER::GPU_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
GPU_MANAGER::GPU_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
||||||
m_isDrawing( false ), m_container( aContainer ), m_shader( NULL ), m_shaderAttrib( 0 ), m_enableDepthTest( true )
|
m_isDrawing( false ),
|
||||||
|
m_container( aContainer ),
|
||||||
|
m_shader( NULL ),
|
||||||
|
m_shaderAttrib( 0 ),
|
||||||
|
m_enableDepthTest( true )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +79,12 @@ void GPU_MANAGER::SetShader( SHADER& aShader )
|
||||||
|
|
||||||
// Cached manager
|
// Cached manager
|
||||||
GPU_CACHED_MANAGER::GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
GPU_CACHED_MANAGER::GPU_CACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
||||||
GPU_MANAGER( aContainer ), m_buffersInitialized( false ), m_indicesPtr( NULL ),
|
GPU_MANAGER( aContainer ),
|
||||||
m_indicesBuffer( 0 ), m_indicesSize( 0 ), m_indicesCapacity( 0 )
|
m_buffersInitialized( false ),
|
||||||
|
m_indicesPtr( NULL ),
|
||||||
|
m_indicesBuffer( 0 ),
|
||||||
|
m_indicesSize( 0 ),
|
||||||
|
m_indicesCapacity( 0 )
|
||||||
{
|
{
|
||||||
// Allocate the biggest possible buffer for indices
|
// Allocate the biggest possible buffer for indices
|
||||||
resizeIndices( aContainer->GetSize() );
|
resizeIndices( aContainer->GetSize() );
|
||||||
|
@ -122,7 +132,8 @@ void GPU_CACHED_MANAGER::DrawIndices( unsigned int aOffset, unsigned int aSize )
|
||||||
wxASSERT( m_isDrawing );
|
wxASSERT( m_isDrawing );
|
||||||
|
|
||||||
// Copy indices of items that should be drawn to GPU memory
|
// Copy indices of items that should be drawn to GPU memory
|
||||||
for( unsigned int i = aOffset; i < aOffset + aSize; *m_indicesPtr++ = i++ );
|
for( unsigned int i = aOffset; i < aOffset + aSize; *m_indicesPtr++ = i++ )
|
||||||
|
;
|
||||||
|
|
||||||
m_indicesSize += aSize;
|
m_indicesSize += aSize;
|
||||||
}
|
}
|
||||||
|
@ -132,7 +143,8 @@ void GPU_CACHED_MANAGER::DrawAll()
|
||||||
{
|
{
|
||||||
wxASSERT( m_isDrawing );
|
wxASSERT( m_isDrawing );
|
||||||
|
|
||||||
for( unsigned int i = 0; i < m_indicesSize; *m_indicesPtr++ = i++ );
|
for( unsigned int i = 0; i < m_indicesSize; *m_indicesPtr++ = i++ )
|
||||||
|
;
|
||||||
|
|
||||||
m_indicesSize = m_container->GetSize();
|
m_indicesSize = m_container->GetSize();
|
||||||
}
|
}
|
||||||
|
@ -171,17 +183,17 @@ void GPU_CACHED_MANAGER::EndDrawing()
|
||||||
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, (GLvoid*) COORD_OFFSET );
|
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, (GLvoid*) COORD_OFFSET );
|
||||||
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, (GLvoid*) COLOR_OFFSET );
|
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, (GLvoid*) COLOR_OFFSET );
|
||||||
|
|
||||||
if( m_shader != NULL ) // Use shader if applicable
|
if( m_shader != NULL ) // Use shader if applicable
|
||||||
{
|
{
|
||||||
m_shader->Use();
|
m_shader->Use();
|
||||||
glEnableVertexAttribArray( m_shaderAttrib );
|
glEnableVertexAttribArray( m_shaderAttrib );
|
||||||
glVertexAttribPointer( m_shaderAttrib, SHADER_STRIDE, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer( m_shaderAttrib, SHADER_STRIDE, GL_FLOAT, GL_FALSE, VERTEX_SIZE,
|
||||||
VERTEX_SIZE, (GLvoid*) SHADER_OFFSET );
|
(GLvoid*) SHADER_OFFSET );
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer );
|
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer );
|
||||||
glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indicesSize * sizeof(int),
|
glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indicesSize * sizeof( int ), (GLvoid*) m_indices.get(),
|
||||||
(GLvoid*) m_indices.get(), GL_DYNAMIC_DRAW );
|
GL_DYNAMIC_DRAW );
|
||||||
|
|
||||||
glDrawElements( GL_TRIANGLES, m_indicesSize, GL_UNSIGNED_INT, 0 );
|
glDrawElements( GL_TRIANGLES, m_indicesSize, GL_UNSIGNED_INT, 0 );
|
||||||
|
|
||||||
|
@ -207,8 +219,8 @@ void GPU_CACHED_MANAGER::EndDrawing()
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
totalRealTime.Stop();
|
totalRealTime.Stop();
|
||||||
wxLogTrace( "GAL_PROFILE",
|
wxLogTrace( "GAL_PROFILE", wxT( "GPU_CACHED_MANAGER::EndDrawing(): %.1f ms" ),
|
||||||
wxT( "GPU_CACHED_MANAGER::EndDrawing(): %.1f ms" ), totalRealTime.msecs() );
|
totalRealTime.msecs() );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +237,7 @@ void GPU_CACHED_MANAGER::resizeIndices( unsigned int aNewSize )
|
||||||
|
|
||||||
// Noncached manager
|
// Noncached manager
|
||||||
GPU_NONCACHED_MANAGER::GPU_NONCACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
GPU_NONCACHED_MANAGER::GPU_NONCACHED_MANAGER( VERTEX_CONTAINER* aContainer ) :
|
||||||
GPU_MANAGER( aContainer )
|
GPU_MANAGER( aContainer )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,9 +270,9 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
|
||||||
if( m_container->GetSize() == 0 )
|
if( m_container->GetSize() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VERTEX* vertices = m_container->GetAllVertices();
|
VERTEX* vertices = m_container->GetAllVertices();
|
||||||
GLfloat* coordinates = (GLfloat*) ( vertices );
|
GLfloat* coordinates = (GLfloat*) ( vertices );
|
||||||
GLubyte* colors = (GLubyte*) ( vertices ) + COLOR_OFFSET;
|
GLubyte* colors = (GLubyte*) ( vertices ) + COLOR_OFFSET;
|
||||||
|
|
||||||
if( m_enableDepthTest )
|
if( m_enableDepthTest )
|
||||||
glEnable( GL_DEPTH_TEST );
|
glEnable( GL_DEPTH_TEST );
|
||||||
|
@ -274,14 +286,14 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
|
||||||
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, coordinates );
|
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, coordinates );
|
||||||
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, colors );
|
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, colors );
|
||||||
|
|
||||||
if( m_shader != NULL ) // Use shader if applicable
|
if( m_shader != NULL ) // Use shader if applicable
|
||||||
{
|
{
|
||||||
GLfloat* shaders = (GLfloat*) ( vertices ) + SHADER_OFFSET / sizeof(GLfloat);
|
GLfloat* shaders = (GLfloat*) ( vertices ) + SHADER_OFFSET / sizeof( GLfloat );
|
||||||
|
|
||||||
m_shader->Use();
|
m_shader->Use();
|
||||||
glEnableVertexAttribArray( m_shaderAttrib );
|
glEnableVertexAttribArray( m_shaderAttrib );
|
||||||
glVertexAttribPointer( m_shaderAttrib, SHADER_STRIDE, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer( m_shaderAttrib, SHADER_STRIDE, GL_FLOAT, GL_FALSE, VERTEX_SIZE,
|
||||||
VERTEX_SIZE, shaders );
|
shaders );
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays( GL_TRIANGLES, 0, m_container->GetSize() );
|
glDrawArrays( GL_TRIANGLES, 0, m_container->GetSize() );
|
||||||
|
@ -304,8 +316,8 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
totalRealTime.Stop();
|
totalRealTime.Stop();
|
||||||
wxLogTrace( "GAL_PROFILE",
|
wxLogTrace( "GAL_PROFILE", wxT( "GPU_NONCACHED_MANAGER::EndDrawing(): %.1f ms" ),
|
||||||
wxT( "GPU_NONCACHED_MANAGER::EndDrawing(): %.1f ms" ), totalRealTime.msecs() );
|
totalRealTime.msecs() );
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -35,7 +37,8 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
NONCACHED_CONTAINER::NONCACHED_CONTAINER( unsigned int aSize ) :
|
NONCACHED_CONTAINER::NONCACHED_CONTAINER( unsigned int aSize ) :
|
||||||
VERTEX_CONTAINER( aSize ), m_freePtr( 0 )
|
VERTEX_CONTAINER( aSize ),
|
||||||
|
m_freePtr( 0 )
|
||||||
{
|
{
|
||||||
m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
|
m_vertices = static_cast<VERTEX*>( malloc( aSize * sizeof( VERTEX ) ) );
|
||||||
memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
|
memset( m_vertices, 0x00, aSize * sizeof( VERTEX ) );
|
||||||
|
@ -60,14 +63,13 @@ VERTEX* NONCACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
if( m_freeSpace < aSize )
|
if( m_freeSpace < aSize )
|
||||||
{
|
{
|
||||||
// Double the space
|
// Double the space
|
||||||
VERTEX* newVertices = static_cast<VERTEX*>( realloc( m_vertices,
|
VERTEX* newVertices =
|
||||||
m_currentSize * 2 *
|
static_cast<VERTEX*>( realloc( m_vertices, m_currentSize * 2 * sizeof( VERTEX ) ) );
|
||||||
sizeof(VERTEX) ) );
|
|
||||||
|
|
||||||
if( newVertices != NULL )
|
if( newVertices != NULL )
|
||||||
{
|
{
|
||||||
m_vertices = newVertices;
|
m_vertices = newVertices;
|
||||||
m_freeSpace += m_currentSize;
|
m_freeSpace += m_currentSize;
|
||||||
m_currentSize *= 2;
|
m_currentSize *= 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -79,7 +81,7 @@ VERTEX* NONCACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
VERTEX* freeVertex = &m_vertices[m_freePtr];
|
VERTEX* freeVertex = &m_vertices[m_freePtr];
|
||||||
|
|
||||||
// Move to the next free chunk
|
// Move to the next free chunk
|
||||||
m_freePtr += aSize;
|
m_freePtr += aSize;
|
||||||
m_freeSpace -= aSize;
|
m_freeSpace -= aSize;
|
||||||
|
|
||||||
return freeVertex;
|
return freeVertex;
|
||||||
|
@ -88,6 +90,6 @@ VERTEX* NONCACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
|
|
||||||
void NONCACHED_CONTAINER::Clear()
|
void NONCACHED_CONTAINER::Clear()
|
||||||
{
|
{
|
||||||
m_freePtr = 0;
|
m_freePtr = 0;
|
||||||
m_freeSpace = m_currentSize;
|
m_freeSpace = m_currentSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2017 CERN
|
* Copyright (C) 2013-2017 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -40,9 +42,12 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
|
OPENGL_COMPOSITOR::OPENGL_COMPOSITOR() :
|
||||||
m_initialized( false ), m_curBuffer( 0 ),
|
m_initialized( false ),
|
||||||
m_mainFbo( 0 ), m_depthBuffer( 0 ), m_curFbo( DIRECT_RENDERING ),
|
m_curBuffer( 0 ),
|
||||||
m_currentAntialiasingMode( OPENGL_ANTIALIASING_MODE::NONE )
|
m_mainFbo( 0 ),
|
||||||
|
m_depthBuffer( 0 ),
|
||||||
|
m_curFbo( DIRECT_RENDERING ),
|
||||||
|
m_currentAntialiasingMode( OPENGL_ANTIALIASING_MODE::NONE )
|
||||||
{
|
{
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_NONE>( this );
|
m_antialiasing = std::make_unique<ANTIALIASING_NONE>( this );
|
||||||
}
|
}
|
||||||
|
@ -77,21 +82,23 @@ void OPENGL_COMPOSITOR::Initialize()
|
||||||
|
|
||||||
switch( m_currentAntialiasingMode )
|
switch( m_currentAntialiasingMode )
|
||||||
{
|
{
|
||||||
case OPENGL_ANTIALIASING_MODE::NONE:
|
case OPENGL_ANTIALIASING_MODE::NONE:
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_NONE>( this );
|
m_antialiasing = std::make_unique<ANTIALIASING_NONE>( this );
|
||||||
break;
|
break;
|
||||||
case OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH:
|
case OPENGL_ANTIALIASING_MODE::SUBSAMPLE_HIGH:
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_SMAA>( this, SMAA_QUALITY::HIGH );
|
m_antialiasing = std::make_unique<ANTIALIASING_SMAA>( this, SMAA_QUALITY::HIGH );
|
||||||
break;
|
break;
|
||||||
case OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA:
|
case OPENGL_ANTIALIASING_MODE::SUBSAMPLE_ULTRA:
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_SMAA>( this, SMAA_QUALITY::ULTRA );
|
m_antialiasing = std::make_unique<ANTIALIASING_SMAA>( this, SMAA_QUALITY::ULTRA );
|
||||||
break;
|
break;
|
||||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2:
|
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2:
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_SUPERSAMPLING>( this, SUPERSAMPLING_MODE::X2 );
|
m_antialiasing =
|
||||||
break;
|
std::make_unique<ANTIALIASING_SUPERSAMPLING>( this, SUPERSAMPLING_MODE::X2 );
|
||||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4:
|
break;
|
||||||
m_antialiasing = std::make_unique<ANTIALIASING_SUPERSAMPLING>( this, SUPERSAMPLING_MODE::X4 );
|
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4:
|
||||||
break;
|
m_antialiasing =
|
||||||
|
std::make_unique<ANTIALIASING_SUPERSAMPLING>( this, SUPERSAMPLING_MODE::X4 );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2U dims = m_antialiasing->GetInternalBufferSize();
|
VECTOR2U dims = m_antialiasing->GetInternalBufferSize();
|
||||||
|
@ -139,7 +146,7 @@ void OPENGL_COMPOSITOR::Resize( unsigned int aWidth, unsigned int aHeight )
|
||||||
|
|
||||||
m_antialiasing->OnLostBuffers();
|
m_antialiasing->OnLostBuffers();
|
||||||
|
|
||||||
m_width = aWidth;
|
m_width = aWidth;
|
||||||
m_height = aHeight;
|
m_height = aHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +168,10 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||||
|
|
||||||
if( (int) usedBuffers() >= maxBuffers )
|
if( (int) usedBuffers() >= maxBuffers )
|
||||||
{
|
{
|
||||||
throw std::runtime_error( "Cannot create more framebuffers. OpenGL rendering "
|
throw std::runtime_error(
|
||||||
"backend requires at least 3 framebuffers. You may try to update/change "
|
"Cannot create more framebuffers. OpenGL rendering "
|
||||||
"your graphic drivers." );
|
"backend requires at least 3 framebuffers. You may try to update/change "
|
||||||
|
"your graphic drivers." );
|
||||||
}
|
}
|
||||||
|
|
||||||
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*) &maxTextureSize );
|
glGetIntegerv( GL_MAX_TEXTURE_SIZE, (GLint*) &maxTextureSize );
|
||||||
|
@ -171,7 +179,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||||
if( maxTextureSize < (int) aDimensions.x || maxTextureSize < (int) aDimensions.y )
|
if( maxTextureSize < (int) aDimensions.x || maxTextureSize < (int) aDimensions.y )
|
||||||
{
|
{
|
||||||
throw std::runtime_error( "Requested texture size is not supported. "
|
throw std::runtime_error( "Requested texture size is not supported. "
|
||||||
"Could not create a buffer." );
|
"Could not create a buffer." );
|
||||||
}
|
}
|
||||||
|
|
||||||
// GL_COLOR_ATTACHMENTn are consecutive integers
|
// GL_COLOR_ATTACHMENTn are consecutive integers
|
||||||
|
@ -195,8 +203,8 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||||
|
|
||||||
// Bind the texture to the specific attachment point, clear and rebind the screen
|
// Bind the texture to the specific attachment point, clear and rebind the screen
|
||||||
bindFb( m_mainFbo );
|
bindFb( m_mainFbo );
|
||||||
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint,
|
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint, GL_TEXTURE_2D, textureTarget,
|
||||||
GL_TEXTURE_2D, textureTarget, 0 );
|
0 );
|
||||||
|
|
||||||
// Check the status, exit if the framebuffer can't be created
|
// Check the status, exit if the framebuffer can't be created
|
||||||
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
||||||
|
@ -215,7 +223,7 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||||
throw std::runtime_error( "The framebuffer does not have at least one "
|
throw std::runtime_error( "The framebuffer does not have at least one "
|
||||||
"image attached to it." );
|
"image attached to it." );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||||
|
@ -223,13 +231,14 @@ unsigned int OPENGL_COMPOSITOR::CreateBuffer( VECTOR2U aDimensions )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||||
throw std::runtime_error( "The combination of internal formats of the attached "
|
throw std::runtime_error(
|
||||||
|
"The combination of internal formats of the attached "
|
||||||
"images violates an implementation-dependent set of restrictions." );
|
"images violates an implementation-dependent set of restrictions." );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
||||||
throw std::runtime_error( "GL_RENDERBUFFER_SAMPLES is not the same for "
|
throw std::runtime_error( "GL_RENDERBUFFER_SAMPLES is not the same for "
|
||||||
"all attached renderbuffers" );
|
"all attached renderbuffers" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
|
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
|
||||||
|
@ -283,8 +292,8 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
|
||||||
glDrawBuffer( m_buffers[m_curBuffer].attachmentPoint );
|
glDrawBuffer( m_buffers[m_curBuffer].attachmentPoint );
|
||||||
checkGlError( "setting draw buffer" );
|
checkGlError( "setting draw buffer" );
|
||||||
|
|
||||||
glViewport( 0, 0,
|
glViewport( 0, 0, m_buffers[m_curBuffer].dimensions.x,
|
||||||
m_buffers[m_curBuffer].dimensions.x, m_buffers[m_curBuffer].dimensions.y );
|
m_buffers[m_curBuffer].dimensions.y );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -327,7 +336,7 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aSourceHandle, unsigned int aDe
|
||||||
assert( aDestHandle <= usedBuffers() );
|
assert( aDestHandle <= usedBuffers() );
|
||||||
|
|
||||||
// Switch to the destination buffer and blit the scene
|
// Switch to the destination buffer and blit the scene
|
||||||
SetBuffer ( aDestHandle );
|
SetBuffer( aDestHandle );
|
||||||
|
|
||||||
// Depth test has to be disabled to make transparency working
|
// Depth test has to be disabled to make transparency working
|
||||||
glDisable( GL_DEPTH_TEST );
|
glDisable( GL_DEPTH_TEST );
|
||||||
|
@ -346,19 +355,19 @@ void OPENGL_COMPOSITOR::DrawBuffer( unsigned int aSourceHandle, unsigned int aDe
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glBegin( GL_TRIANGLES );
|
glBegin( GL_TRIANGLES );
|
||||||
glTexCoord2f( 0.0f, 1.0f );
|
glTexCoord2f( 0.0f, 1.0f );
|
||||||
glVertex2f ( -1.0f, 1.0f );
|
glVertex2f( -1.0f, 1.0f );
|
||||||
glTexCoord2f( 0.0f, 0.0f );
|
glTexCoord2f( 0.0f, 0.0f );
|
||||||
glVertex2f ( -1.0f, -1.0f );
|
glVertex2f( -1.0f, -1.0f );
|
||||||
glTexCoord2f( 1.0f, 1.0f );
|
glTexCoord2f( 1.0f, 1.0f );
|
||||||
glVertex2f ( 1.0f, 1.0f );
|
glVertex2f( 1.0f, 1.0f );
|
||||||
|
|
||||||
glTexCoord2f( 1.0f, 1.0f );
|
glTexCoord2f( 1.0f, 1.0f );
|
||||||
glVertex2f ( 1.0f, 1.0f );
|
glVertex2f( 1.0f, 1.0f );
|
||||||
glTexCoord2f( 0.0f, 0.0f );
|
glTexCoord2f( 0.0f, 0.0f );
|
||||||
glVertex2f ( -1.0f, -1.0f );
|
glVertex2f( -1.0f, -1.0f );
|
||||||
glTexCoord2f( 1.0f, 0.0f );
|
glTexCoord2f( 1.0f, 0.0f );
|
||||||
glVertex2f ( 1.0f, -1.0f );
|
glVertex2f( 1.0f, -1.0f );
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
@ -414,11 +423,8 @@ int OPENGL_COMPOSITOR::GetAntialiasSupersamplingFactor() const
|
||||||
{
|
{
|
||||||
switch( m_currentAntialiasingMode )
|
switch( m_currentAntialiasingMode )
|
||||||
{
|
{
|
||||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2:
|
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X2: return 2;
|
||||||
return 2;
|
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4: return 4;
|
||||||
case OPENGL_ANTIALIASING_MODE::SUPERSAMPLING_X4:
|
default: return 1;
|
||||||
return 4;
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||||
* Copyright (C) 2012-2020 Kicad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2012-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* Graphics Abstraction Layer (GAL) for OpenGL
|
* Graphics Abstraction Layer (GAL) for OpenGL
|
||||||
*
|
*
|
||||||
|
@ -39,12 +39,12 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
SHADER::SHADER() :
|
SHADER::SHADER() :
|
||||||
isProgramCreated( false ),
|
isProgramCreated( false ),
|
||||||
isShaderLinked( false ),
|
isShaderLinked( false ),
|
||||||
active( false ),
|
active( false ),
|
||||||
maximumVertices( 4 ),
|
maximumVertices( 4 ),
|
||||||
geomInputType( GL_LINES ),
|
geomInputType( GL_LINES ),
|
||||||
geomOutputType( GL_LINES )
|
geomOutputType( GL_LINES )
|
||||||
|
|
||||||
{
|
{
|
||||||
// Do not have uninitialized members:
|
// Do not have uninitialized members:
|
||||||
|
@ -63,7 +63,7 @@ SHADER::~SHADER()
|
||||||
{
|
{
|
||||||
// Delete the shaders and the program
|
// Delete the shaders and the program
|
||||||
for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end();
|
for( std::deque<GLuint>::iterator it = shaderNumbers.begin(); it != shaderNumbers.end();
|
||||||
++it )
|
++it )
|
||||||
{
|
{
|
||||||
GLuint shader = *it;
|
GLuint shader = *it;
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ void SHADER::ConfigureGeometryShader( GLuint maxVertices, GLuint geometryInputTy
|
||||||
GLuint geometryOutputType )
|
GLuint geometryOutputType )
|
||||||
{
|
{
|
||||||
maximumVertices = maxVertices;
|
maximumVertices = maxVertices;
|
||||||
geomInputType = geometryInputType;
|
geomInputType = geometryInputType;
|
||||||
geomOutputType = geometryOutputType;
|
geomOutputType = geometryOutputType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,14 +156,14 @@ void SHADER::SetParameter( int parameterNumber, int value ) const
|
||||||
|
|
||||||
void SHADER::SetParameter( int parameterNumber, float f0, float f1, float f2, float f3 ) const
|
void SHADER::SetParameter( int parameterNumber, float f0, float f1, float f2, float f3 ) const
|
||||||
{
|
{
|
||||||
assert( (unsigned)parameterNumber < parameterLocation.size() );
|
assert( (unsigned) parameterNumber < parameterLocation.size() );
|
||||||
float arr[4] = { f0, f1, f2, f3 };
|
float arr[4] = { f0, f1, f2, f3 };
|
||||||
glUniform4fv( parameterLocation[parameterNumber], 1, arr );
|
glUniform4fv( parameterLocation[parameterNumber], 1, arr );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHADER::SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const
|
void SHADER::SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const
|
||||||
{
|
{
|
||||||
assert( (unsigned)aParameterNumber < parameterLocation.size() );
|
assert( (unsigned) aParameterNumber < parameterLocation.size() );
|
||||||
glUniform2f( parameterLocation[aParameterNumber], aValue.x, aValue.y );
|
glUniform2f( parameterLocation[aParameterNumber], aValue.x, aValue.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ int SHADER::GetAttribute( const std::string& aAttributeName ) const
|
||||||
void SHADER::programInfo( GLuint aProgram )
|
void SHADER::programInfo( GLuint aProgram )
|
||||||
{
|
{
|
||||||
GLint glInfoLogLength = 0;
|
GLint glInfoLogLength = 0;
|
||||||
GLint writtenChars = 0;
|
GLint writtenChars = 0;
|
||||||
|
|
||||||
// Get the length of the info string
|
// Get the length of the info string
|
||||||
glGetProgramiv( aProgram, GL_INFO_LOG_LENGTH, &glInfoLogLength );
|
glGetProgramiv( aProgram, GL_INFO_LOG_LENGTH, &glInfoLogLength );
|
||||||
|
@ -196,7 +196,7 @@ void SHADER::programInfo( GLuint aProgram )
|
||||||
void SHADER::shaderInfo( GLuint aShader )
|
void SHADER::shaderInfo( GLuint aShader )
|
||||||
{
|
{
|
||||||
GLint glInfoLogLength = 0;
|
GLint glInfoLogLength = 0;
|
||||||
GLint writtenChars = 0;
|
GLint writtenChars = 0;
|
||||||
|
|
||||||
// Get the length of the info string
|
// Get the length of the info string
|
||||||
glGetShaderiv( aShader, GL_INFO_LOG_LENGTH, &glInfoLogLength );
|
glGetShaderiv( aShader, GL_INFO_LOG_LENGTH, &glInfoLogLength );
|
||||||
|
@ -216,7 +216,7 @@ std::string SHADER::ReadSource( const std::string& aShaderSourceName )
|
||||||
{
|
{
|
||||||
// Open the shader source for reading
|
// Open the shader source for reading
|
||||||
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
|
std::ifstream inputFile( aShaderSourceName.c_str(), std::ifstream::in );
|
||||||
std::string shaderSource;
|
std::string shaderSource;
|
||||||
|
|
||||||
if( !inputFile )
|
if( !inputFile )
|
||||||
throw std::runtime_error( "Can't read the shader source: " + aShaderSourceName );
|
throw std::runtime_error( "Can't read the shader source: " + aShaderSourceName );
|
||||||
|
@ -234,15 +234,14 @@ std::string SHADER::ReadSource( const std::string& aShaderSourceName )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char** aArray,
|
bool SHADER::loadShaderFromStringArray( SHADER_TYPE aShaderType, const char** aArray, size_t aSize )
|
||||||
size_t aSize )
|
|
||||||
{
|
{
|
||||||
assert( !isShaderLinked );
|
assert( !isShaderLinked );
|
||||||
|
|
||||||
// Create the program
|
// Create the program
|
||||||
if( !isProgramCreated )
|
if( !isProgramCreated )
|
||||||
{
|
{
|
||||||
programNumber = glCreateProgram();
|
programNumber = glCreateProgram();
|
||||||
isProgramCreated = true;
|
isProgramCreated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2017 CERN
|
* Copyright (C) 2016-2017 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -22,93 +24,105 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <confirm.h> // DisplayError
|
#include <confirm.h> // DisplayError
|
||||||
|
|
||||||
#include <gal/opengl/kiglew.h> // Must be included first
|
#include <gal/opengl/kiglew.h> // Must be included first
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <wx/log.h> // wxLogDebug
|
#include <wx/log.h> // wxLogDebug
|
||||||
|
|
||||||
|
|
||||||
int checkGlError( const std::string& aInfo, bool aThrow )
|
int checkGlError( const std::string& aInfo, bool aThrow )
|
||||||
{
|
{
|
||||||
int result = glGetError();
|
int result = glGetError();
|
||||||
wxString errorMsg;
|
wxString errorMsg;
|
||||||
|
|
||||||
switch( result )
|
switch( result )
|
||||||
{
|
{
|
||||||
case GL_NO_ERROR:
|
case GL_NO_ERROR:
|
||||||
// all good
|
// all good
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_INVALID_ENUM:
|
case GL_INVALID_ENUM:
|
||||||
errorMsg = wxString::Format( "Error: %s: invalid enum", aInfo );
|
errorMsg = wxString::Format( "Error: %s: invalid enum", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_INVALID_VALUE:
|
case GL_INVALID_VALUE:
|
||||||
errorMsg = wxString::Format( "Error: %s: invalid value", aInfo );
|
errorMsg = wxString::Format( "Error: %s: invalid value", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_INVALID_OPERATION:
|
case GL_INVALID_OPERATION:
|
||||||
errorMsg = wxString::Format( "Error: %s: invalid operation", aInfo );
|
errorMsg = wxString::Format( "Error: %s: invalid operation", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
{
|
||||||
|
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
||||||
|
|
||||||
|
if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
|
||||||
{
|
{
|
||||||
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
|
switch( status )
|
||||||
|
|
||||||
if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
|
|
||||||
{
|
{
|
||||||
switch( status )
|
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||||
{
|
errorMsg = "The framebuffer attachment points are incomplete.";
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
break;
|
||||||
errorMsg = "The framebuffer attachment points are incomplete.";
|
|
||||||
break;
|
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
errorMsg = "No images attached to the framebuffer.";
|
||||||
errorMsg = "No images attached to the framebuffer.";
|
break;
|
||||||
break;
|
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||||
errorMsg = "The framebuffer does not have at least one image attached to it.";
|
errorMsg = "The framebuffer does not have at least one image attached to it.";
|
||||||
break;
|
break;
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
|
||||||
errorMsg = "The framebuffer read buffer is incomplete.";
|
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||||
break;
|
errorMsg = "The framebuffer read buffer is incomplete.";
|
||||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
break;
|
||||||
errorMsg = "The combination of internal formats of the attached images violates an implementation-dependent set of restrictions.";
|
|
||||||
break;
|
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
errorMsg = "The combination of internal formats of the attached images violates an "
|
||||||
errorMsg = "GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers.";
|
"implementation dependent set of restrictions.";
|
||||||
break;
|
break;
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
|
|
||||||
errorMsg = "Framebuffer incomplete layer targets errors.";
|
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
|
||||||
break;
|
errorMsg =
|
||||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
"GL_RENDERBUFFER_SAMPLES is not the same for all attached render buffers.";
|
||||||
errorMsg = "Framebuffer attachments have different dimensions";
|
break;
|
||||||
break;
|
|
||||||
default:
|
case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
|
||||||
errorMsg.Printf( "Unknown incomplete framebuffer error id %X", status );
|
errorMsg = "Framebuffer incomplete layer targets errors.";
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||||
|
errorMsg = "Framebuffer attachments have different dimensions";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errorMsg.Printf( "Unknown incomplete framebuffer error id %X", status );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
errorMsg = wxString::Format( "Error: %s: invalid framebuffer operation", aInfo );
|
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
errorMsg = wxString::Format( "Error: %s: invalid framebuffer operation", aInfo );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GL_OUT_OF_MEMORY:
|
case GL_OUT_OF_MEMORY:
|
||||||
errorMsg = wxString::Format( "Error: %s: out of memory", aInfo );
|
errorMsg = wxString::Format( "Error: %s: out of memory", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_STACK_UNDERFLOW:
|
case GL_STACK_UNDERFLOW:
|
||||||
errorMsg = wxString::Format( "Error: %s: stack underflow", aInfo );
|
errorMsg = wxString::Format( "Error: %s: stack underflow", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_STACK_OVERFLOW:
|
case GL_STACK_OVERFLOW:
|
||||||
errorMsg = wxString::Format( "Error: %s: stack overflow", aInfo );
|
errorMsg = wxString::Format( "Error: %s: stack overflow", aInfo );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
errorMsg = wxString::Format( "Error: %s: unknown error", aInfo );
|
errorMsg = wxString::Format( "Error: %s: unknown error", aInfo );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( result != GL_NO_ERROR )
|
if( result != GL_NO_ERROR )
|
||||||
|
@ -125,15 +139,16 @@ int checkGlError( const std::string& aInfo, bool aThrow )
|
||||||
|
|
||||||
// debugMsgCallback is a callback function for glDebugMessageCallback.
|
// debugMsgCallback is a callback function for glDebugMessageCallback.
|
||||||
// It must have the right type ( GLAPIENTRY )
|
// It must have the right type ( GLAPIENTRY )
|
||||||
static void GLAPIENTRY debugMsgCallback( GLenum aSource, GLenum aType, GLuint aId,
|
static void GLAPIENTRY debugMsgCallback( GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity,
|
||||||
GLenum aSeverity, GLsizei aLength, const GLchar* aMessage, const void* aUserParam )
|
GLsizei aLength, const GLchar* aMessage,
|
||||||
|
const void* aUserParam )
|
||||||
{
|
{
|
||||||
switch( aSeverity )
|
switch( aSeverity )
|
||||||
{
|
{
|
||||||
case GL_DEBUG_SEVERITY_HIGH: wxLogDebug( "OpenGL ERROR: " ); break;
|
case GL_DEBUG_SEVERITY_HIGH: wxLogDebug( "OpenGL ERROR: " ); break;
|
||||||
case GL_DEBUG_SEVERITY_MEDIUM: wxLogDebug( "OpenGL WARNING: " ); break;
|
case GL_DEBUG_SEVERITY_MEDIUM: wxLogDebug( "OpenGL WARNING: " ); break;
|
||||||
case GL_DEBUG_SEVERITY_LOW: wxLogDebug( "OpenGL INFO: " ); break;
|
case GL_DEBUG_SEVERITY_LOW: wxLogDebug( "OpenGL INFO: " ); break;
|
||||||
case GL_DEBUG_SEVERITY_NOTIFICATION: return;
|
case GL_DEBUG_SEVERITY_NOTIFICATION: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxLogDebug( "%s\n", aMessage );
|
wxLogDebug( "%s\n", aMessage );
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -56,8 +58,12 @@ VERTEX_CONTAINER* VERTEX_CONTAINER::MakeContainer( bool aCached )
|
||||||
|
|
||||||
|
|
||||||
VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
|
VERTEX_CONTAINER::VERTEX_CONTAINER( unsigned int aSize ) :
|
||||||
m_freeSpace( aSize ), m_currentSize( aSize ), m_initialSize( aSize ),
|
m_freeSpace( aSize ),
|
||||||
m_vertices( NULL ), m_failed( false ), m_dirty( true )
|
m_currentSize( aSize ),
|
||||||
|
m_initialSize( aSize ),
|
||||||
|
m_vertices( NULL ),
|
||||||
|
m_failed( false ),
|
||||||
|
m_dirty( true )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -34,7 +36,9 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
VERTEX_ITEM::VERTEX_ITEM( const VERTEX_MANAGER& aManager ) :
|
VERTEX_ITEM::VERTEX_ITEM( const VERTEX_MANAGER& aManager ) :
|
||||||
m_manager( aManager ), m_offset( 0 ), m_size( 0 )
|
m_manager( aManager ),
|
||||||
|
m_offset( 0 ),
|
||||||
|
m_size( 0 )
|
||||||
{
|
{
|
||||||
// As the item is created, we are going to modify it, so call to SetItem() is needed
|
// As the item is created, we are going to modify it, so call to SetItem() is needed
|
||||||
m_manager.SetItem( *this );
|
m_manager.SetItem( *this );
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013-2016 CERN
|
* Copyright (C) 2013-2016 CERN
|
||||||
|
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -38,7 +40,10 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) :
|
VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) :
|
||||||
m_noTransform( true ), m_transform( 1.0f ), m_reserved( NULL ), m_reservedSpace( 0 )
|
m_noTransform( true ),
|
||||||
|
m_transform( 1.0f ),
|
||||||
|
m_reserved( NULL ),
|
||||||
|
m_reservedSpace( 0 )
|
||||||
{
|
{
|
||||||
m_container.reset( VERTEX_CONTAINER::MakeContainer( aCached ) );
|
m_container.reset( VERTEX_CONTAINER::MakeContainer( aCached ) );
|
||||||
m_gpu.reset( GPU_MANAGER::MakeManager( m_container.get() ) );
|
m_gpu.reset( GPU_MANAGER::MakeManager( m_container.get() ) );
|
||||||
|
@ -174,7 +179,7 @@ void VERTEX_MANAGER::FreeItem( VERTEX_ITEM& aItem ) const
|
||||||
|
|
||||||
void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
|
void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
|
||||||
{
|
{
|
||||||
unsigned int size = aItem.GetSize();
|
unsigned int size = aItem.GetSize();
|
||||||
unsigned int offset = aItem.GetOffset();
|
unsigned int offset = aItem.GetOffset();
|
||||||
|
|
||||||
VERTEX* vertex = m_container->GetVertices( offset );
|
VERTEX* vertex = m_container->GetVertices( offset );
|
||||||
|
@ -194,7 +199,7 @@ void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& a
|
||||||
|
|
||||||
void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
|
void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
|
||||||
{
|
{
|
||||||
unsigned int size = aItem.GetSize();
|
unsigned int size = aItem.GetSize();
|
||||||
unsigned int offset = aItem.GetOffset();
|
unsigned int offset = aItem.GetOffset();
|
||||||
|
|
||||||
VERTEX* vertex = m_container->GetVertices( offset );
|
VERTEX* vertex = m_container->GetVertices( offset );
|
||||||
|
|
Loading…
Reference in New Issue