OSX: legacy canvas rendering speed improvements.

* Enables USE_WX_GRAPHICS_CONTEXT for OSX by default.  This shouldn¡¯t be a
  major change because it seems to get used on OSX behind the scenes anyway.
  As a side effect, this might improve behavior with anti-aliasing because
  KiCad shifts drawing by (0.5, 0.5) into the middle of the virtual pixels so
  things may be less blurry.  It will still build without enabling
  USE_WX_GRAPHICS_CONTEXT, but the optimizations obviously won¡¯t be used.
* The optimizations currently only are effective when USE_WX_GRAPHICS_CONTEXT
  is enabled and OSX.  They might be also good for other platforms using
  USE_WX_GRAPHICS_CONTEXT because it aggregates some drawing primitives using
  paths wxGraphicsContext provides.
* It adds some #ifdefs for disabling the wxGraphicsContext stuff when
  USE_WX_GRAPHICS_CONTEXT isn¡¯t enabled.  If you hate #ifdefs, this also
  could be dropped but then it will always check if wxGraphicsContext can be
  applied.
This commit is contained in:
Bernhard Stegmaier 2016-01-04 15:13:10 -05:00 committed by Wayne Stambaugh
parent 9ba18a4e66
commit 8c78bd5fd8
3 changed files with 145 additions and 33 deletions

View File

@ -254,7 +254,7 @@ if( KICAD_SCRIPTING_WXPYTHON )
add_definitions( -DKICAD_SCRIPTING_WXPYTHON )
endif()
if( USE_WX_GRAPHICS_CONTEXT )
if( USE_WX_GRAPHICS_CONTEXT OR APPLE )
add_definitions( -DUSE_WX_GRAPHICS_CONTEXT )
endif()

View File

@ -728,24 +728,51 @@ void EDA_DRAW_PANEL::DrawGrid( wxDC* aDC )
// high and grid is slowly drawn on some platforms. An other way using blit transfert was used,
// a long time ago, but it did not give very good results.
// The better way is highly dependent on the platform and the graphic card.
#ifndef __WXMAC__
GRSetColorPen( aDC, GetParent()->GetGridColor() );
#else
// On mac (Cocoa), a point isn't a pixel and being of size 1 don't survive to antialiasing
GRSetColorPen( aDC, GetParent()->GetGridColor(), aDC->DeviceToLogicalXRel(2) );
#endif
int xpos;
double right = ( double ) m_ClipBox.GetRight();
double bottom = ( double ) m_ClipBox.GetBottom();
for( double x = (double) org.x; x <= right; x += gridSize.x )
#if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
if( gcdc )
{
xpos = KiROUND( x );
wxGraphicsContext *gc = gcdc->GetGraphicsContext();
for( double y = (double) org.y; y <= bottom; y += gridSize.y )
// Grid point size
const int gsz = 1;
const double w = aDC->DeviceToLogicalXRel( gsz );
const double h = aDC->DeviceToLogicalYRel( gsz );
// Use our own pen
wxPen pen( MakeColour( GetParent()->GetGridColor() ), h );
pen.SetCap( wxCAP_BUTT );
gc->SetPen( pen );
// draw grid
wxGraphicsPath path = gc->CreatePath();
for( double x = (double) org.x - w/2.0; x <= right - w/2.0; x += gridSize.x )
{
aDC->DrawPoint( xpos, KiROUND( y ) );
for( double y = (double) org.y; y <= bottom; y += gridSize.y )
{
path.MoveToPoint( x, y );
path.AddLineToPoint( x+w, y );
}
}
gc->StrokePath( path );
}
else
#endif
{
GRSetColorPen( aDC, GetParent()->GetGridColor() );
for( double x = (double) org.x; x <= right; x += gridSize.x )
{
xpos = KiROUND( x );
for( double y = (double) org.y; y <= bottom; y += gridSize.y )
{
aDC->DrawPoint( xpos, KiROUND( y ) );
}
}
}
}

View File

@ -13,6 +13,9 @@
#include <bezier_curves.h>
#include <math_for_graphics.h>
#include <wx/graphics.h>
#if defined(__WXMAC__) && defined(USE_WX_GRAPHICS_CONTEXT)
#include <wx/dcgraph.h>
#endif
static const bool FILLED = true;
static const bool NOT_FILLED = false;
@ -429,17 +432,45 @@ void GRLineArray( EDA_RECT* aClipBox, wxDC* aDC, std::vector<wxPoint>& aLines,
if( aClipBox )
aClipBox->Inflate(aWidth/2);
for( unsigned i = 0; i < aLines.size(); i += 2)
#if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
if( gcdc )
{
int x1 = aLines[i].x;
int y1 = aLines[i].y;
int x2 = aLines[i+1].x;
int y2 = aLines[i+1].y;
GRLastMoveToX = x2;
GRLastMoveToY = y2;
if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
aDC->DrawLine( x1, y1, x2, y2 );
wxGraphicsContext *gc = gcdc->GetGraphicsContext();
// create path
wxGraphicsPath path = gc->CreatePath();
for( unsigned i = 0; i < aLines.size(); i += 2 )
{
int x1 = aLines[i].x;
int y1 = aLines[i].y;
int x2 = aLines[i+1].x;
int y2 = aLines[i+1].y;
if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
{
path.MoveToPoint( x1, y1 );
path.AddLineToPoint( x2, y2 );
}
}
// draw path
gc->StrokePath( path );
}
else
#endif
{
for( unsigned i = 0; i < aLines.size(); i += 2 )
{
int x1 = aLines[i].x;
int y1 = aLines[i].y;
int x2 = aLines[i+1].x;
int y2 = aLines[i+1].y;
if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
aDC->DrawLine( x1, y1, x2, y2 );
}
}
GRMoveTo( aLines[aLines.size() - 1].x, aLines[aLines.size() - 1].y );
if( aClipBox )
aClipBox->Inflate(-aWidth/2);
}
@ -626,10 +657,36 @@ static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
}
else
{
GRMoveTo( Points[0].x, Points[0].y );
for( int i = 1; i < n; ++i )
#if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
wxGCDC *gcdc = wxDynamicCast( DC, wxGCDC );
if( gcdc )
{
GRLineTo( ClipBox, DC, Points[i].x, Points[i].y, width, Color );
wxGraphicsContext *gc = gcdc->GetGraphicsContext();
// set pen
GRSetColorPen( DC, Color, width );
// create path
wxGraphicsPath path = gc->CreatePath();
path.MoveToPoint( Points[0].x, Points[0].y );
for( int i = 1; i < n; ++i )
{
path.AddLineToPoint( Points[i].x, Points[i].y );
}
// draw path
gc->StrokePath( path );
// correctly update last position
GRMoveTo( Points[n - 1].x, Points[n - 1].y );
}
else
#endif
{
GRMoveTo( Points[0].x, Points[0].y );
for( int i = 1; i < n; ++i )
{
GRLineTo( ClipBox, DC, Points[i].x, Points[i].y, width, Color );
}
}
}
}
@ -657,18 +714,46 @@ static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC,
}
else
{
GRMoveTo( aPoints[0].x, aPoints[0].y );
for( int i = 1; i < aPointCount; ++i )
#if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
if( gcdc )
{
GRLineTo( aClipBox, aDC, aPoints[i].x, aPoints[i].y, aWidth, aColor );
wxGraphicsContext *gc = gcdc->GetGraphicsContext();
// set pen
GRSetColorPen( aDC, aColor, aWidth );
// create path
wxGraphicsPath path = gc->CreatePath();
path.MoveToPoint( aPoints[0].x, aPoints[0].y );
for( int i = 1; i < aPointCount; ++i )
{
path.AddLineToPoint( aPoints[i].x, aPoints[i].y );
}
if( aPoints[aPointCount - 1] != aPoints[0] )
path.AddLineToPoint( aPoints[0].x, aPoints[0].y );
// draw path
gc->StrokePath( path );
// correctly update last position
GRMoveTo( aPoints[aPointCount - 1].x, aPoints[aPointCount - 1].y );
}
int lastpt = aPointCount - 1;
// Close the polygon
if( aPoints[lastpt] != aPoints[0] )
else
#endif
{
GRLineTo( aClipBox, aDC, aPoints[0].x, aPoints[0].y, aWidth, aColor );
GRMoveTo( aPoints[0].x, aPoints[0].y );
for( int i = 1; i < aPointCount; ++i )
{
GRLineTo( aClipBox, aDC, aPoints[i].x, aPoints[i].y, aWidth, aColor );
}
int lastpt = aPointCount - 1;
// Close the polygon
if( aPoints[lastpt] != aPoints[0] )
{
GRLineTo( aClipBox, aDC, aPoints[0].x, aPoints[0].y, aWidth, aColor );
}
}
}
}