Optimizations/fixes to the VIEW/GAL classes:
- much faster Cairo rendering (outperforms legacy) - improvements in VIEW update handling - fixed issue with grid rendering in flip view mode
This commit is contained in:
parent
3f7c5a0845
commit
da28e163d2
|
@ -531,6 +531,7 @@ endif()
|
||||||
# Find Cairo library, required
|
# Find Cairo library, required
|
||||||
#
|
#
|
||||||
find_package( Cairo 1.8.8 REQUIRED )
|
find_package( Cairo 1.8.8 REQUIRED )
|
||||||
|
find_package( Pixman 1.0 REQUIRED )
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find Boost library, required.
|
# Find Boost library, required.
|
||||||
|
|
|
@ -4,6 +4,7 @@ include_directories(
|
||||||
./widgets
|
./widgets
|
||||||
./dialog_about
|
./dialog_about
|
||||||
${CAIRO_INCLUDE_DIR}
|
${CAIRO_INCLUDE_DIR}
|
||||||
|
${PIXMAN_INCLUDE_DIR}
|
||||||
${GLEW_INCLUDE_DIR}
|
${GLEW_INCLUDE_DIR}
|
||||||
${GLM_INCLUDE_DIR}
|
${GLM_INCLUDE_DIR}
|
||||||
${CURL_INCLUDE_DIRS}
|
${CURL_INCLUDE_DIRS}
|
||||||
|
|
|
@ -89,7 +89,7 @@ unsigned int CAIRO_COMPOSITOR::CreateBuffer()
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
// Set default settings for the buffer
|
// Set default settings for the buffer
|
||||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
|
cairo_set_antialias( context, CAIRO_ANTIALIAS_NONE );
|
||||||
cairo_set_line_join( context, CAIRO_LINE_JOIN_ROUND );
|
cairo_set_line_join( context, CAIRO_LINE_JOIN_ROUND );
|
||||||
cairo_set_line_cap( context, CAIRO_LINE_CAP_ROUND );
|
cairo_set_line_cap( context, CAIRO_LINE_CAP_ROUND );
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
|
||||||
const float CAIRO_GAL::LAYER_ALPHA = 0.8;
|
|
||||||
|
|
||||||
|
|
||||||
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||||
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
||||||
|
@ -111,46 +111,94 @@ void CAIRO_GAL::BeginDrawing()
|
||||||
compositor->SetBuffer( mainBuffer );
|
compositor->SetBuffer( mainBuffer );
|
||||||
|
|
||||||
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
||||||
cairo_push_group( currentContext );
|
//cairo_push_group( currentContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <profile.h>
|
||||||
|
|
||||||
void CAIRO_GAL::EndDrawing()
|
void CAIRO_GAL::EndDrawing()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
printf("EndDRAW!\n\n\n");
|
||||||
// Force remaining objects to be drawn
|
// Force remaining objects to be drawn
|
||||||
Flush();
|
Flush();
|
||||||
|
|
||||||
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
||||||
cairo_pop_group_to_source( currentContext );
|
//cairo_pop_group_to_source( currentContext );
|
||||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||||
|
|
||||||
// Merge buffers on the screen
|
// Merge buffers on the screen
|
||||||
|
PROF_COUNTER comp("cairo-comp");
|
||||||
compositor->DrawBuffer( mainBuffer );
|
compositor->DrawBuffer( mainBuffer );
|
||||||
compositor->DrawBuffer( overlayBuffer );
|
compositor->DrawBuffer( overlayBuffer );
|
||||||
|
comp.show();
|
||||||
|
|
||||||
// This code was taken from the wxCairo example - it's not the most efficient one
|
// This code was taken from the wxCairo example - it's not the most efficient one
|
||||||
// Here is a good place for optimizations
|
// Here is a good place for optimizations
|
||||||
|
|
||||||
// Now translate the raw context data from the format stored
|
// Now translate the raw context data from the format stored
|
||||||
// by cairo into a format understood by wxImage.
|
// by cairo into a format understood by wxImage.
|
||||||
|
|
||||||
|
PROF_COUNTER draw("cairo-draw");
|
||||||
|
|
||||||
unsigned char* wxOutputPtr = wxOutput;
|
unsigned char* wxOutputPtr = wxOutput;
|
||||||
|
|
||||||
for( size_t count = 0; count < bufferSize; count++ )
|
printf("W %d sw %d\n", wxBufferWidth, screenSize.x);
|
||||||
|
|
||||||
|
pixman_image_t *dstImg = pixman_image_create_bits (PIXMAN_r8g8b8, screenSize.x, screenSize.y, (uint32_t*)wxOutput, wxBufferWidth * 3);
|
||||||
|
pixman_image_t *srcImg = pixman_image_create_bits (PIXMAN_a8b8g8r8, screenSize.x, screenSize.y, (uint32_t*)bitmapBuffer, wxBufferWidth * 4);
|
||||||
|
|
||||||
|
pixman_image_composite (PIXMAN_OP_SRC, srcImg, NULL, dstImg,
|
||||||
|
0, 0, 0, 0, 0, 0, screenSize.x, screenSize.y );
|
||||||
|
|
||||||
|
pixman_image_unref (srcImg);
|
||||||
|
// free (srcImg);
|
||||||
|
pixman_image_unref (dstImg);
|
||||||
|
//free (dstImg);
|
||||||
|
|
||||||
|
/*for( size_t count = 0; count < bufferSize; count++ )
|
||||||
{
|
{
|
||||||
unsigned int value = bitmapBuffer[count];
|
unsigned int value = bitmapBuffer[count];
|
||||||
*wxOutputPtr++ = ( value >> 16 ) & 0xff; // Red pixel
|
*wxOutputPtr++ = ( value >> 16 ) & 0xff; // Red pixel
|
||||||
*wxOutputPtr++ = ( value >> 8 ) & 0xff; // Green pixel
|
*wxOutputPtr++ = ( value >> 8 ) & 0xff; // Green pixel
|
||||||
*wxOutputPtr++ = value & 0xff; // Blue pixel
|
*wxOutputPtr++ = value & 0xff; // Blue pixel
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
draw.show();
|
||||||
|
|
||||||
|
PROF_COUNTER wxd1("wx-draw");
|
||||||
|
|
||||||
|
|
||||||
|
wxImage img( wxBufferWidth, screenSize.y, (unsigned char*) wxOutput, true );
|
||||||
|
wxd1.show();
|
||||||
|
|
||||||
|
PROF_COUNTER wxd2("wx-draw2");
|
||||||
|
|
||||||
wxImage img( screenSize.x, screenSize.y, (unsigned char*) wxOutput, true );
|
|
||||||
wxBitmap bmp( img );
|
wxBitmap bmp( img );
|
||||||
wxClientDC client_dc( this );
|
wxd2.show();
|
||||||
wxBufferedDC dc;
|
PROF_COUNTER wxd3("wx-draw2");
|
||||||
dc.Init( &client_dc, bmp );
|
|
||||||
|
wxMemoryDC mdc ( bmp );
|
||||||
|
wxd3.show();
|
||||||
|
PROF_COUNTER wxd("wx-drawf");
|
||||||
|
|
||||||
|
wxClientDC clientDC( this );
|
||||||
|
//wxBufferedDC dc;
|
||||||
|
//dc.Init( &client_dc, bmp );
|
||||||
|
wxd.show();
|
||||||
|
|
||||||
|
PROF_COUNTER wxb("wx-blt");
|
||||||
|
|
||||||
|
|
||||||
|
blitCursor( mdc );
|
||||||
|
|
||||||
|
clientDC.Blit( 0, 0, screenSize.x, screenSize.y, &mdc, 0, 0, wxCOPY );
|
||||||
|
wxb.show();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Now it is the time to blit the mouse cursor
|
// Now it is the time to blit the mouse cursor
|
||||||
blitCursor( dc );
|
|
||||||
|
|
||||||
deinitSurface();
|
deinitSurface();
|
||||||
}
|
}
|
||||||
|
@ -158,8 +206,12 @@ void CAIRO_GAL::EndDrawing()
|
||||||
|
|
||||||
void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||||
{
|
{
|
||||||
|
|
||||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
||||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||||
|
flushPath();
|
||||||
|
// cairo_set_source_rgb( currentContext, gridColor.r, gridColor.g, gridColor.b );
|
||||||
|
//cairo_stroke( currentContext );
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +226,8 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
|
||||||
|
|
||||||
cairo_move_to( currentContext, (double) aStartPoint.x, (double) aStartPoint.y );
|
cairo_move_to( currentContext, (double) aStartPoint.x, (double) aStartPoint.y );
|
||||||
cairo_line_to( currentContext, (double) aEndPoint.x, (double) aEndPoint.y );
|
cairo_line_to( currentContext, (double) aEndPoint.x, (double) aEndPoint.y );
|
||||||
|
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, fillColor.a);
|
||||||
|
cairo_stroke( currentContext );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -197,6 +251,7 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
|
||||||
cairo_line_to( currentContext, lineLength, -aWidth / 2.0 );
|
cairo_line_to( currentContext, lineLength, -aWidth / 2.0 );
|
||||||
|
|
||||||
cairo_restore( currentContext );
|
cairo_restore( currentContext );
|
||||||
|
flushPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
|
@ -205,10 +260,9 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
|
||||||
|
|
||||||
void CAIRO_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
void CAIRO_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||||
{
|
{
|
||||||
// A circle is drawn using an arc
|
|
||||||
cairo_new_sub_path( currentContext );
|
cairo_new_sub_path( currentContext );
|
||||||
cairo_arc( currentContext, aCenterPoint.x, aCenterPoint.y, aRadius, 0.0, 2 * M_PI );
|
cairo_arc( currentContext, aCenterPoint.x, aCenterPoint.y, aRadius, 0.0, 2 * M_PI );
|
||||||
|
flushPath();
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,6 +287,7 @@ void CAIRO_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aS
|
||||||
cairo_line_to( currentContext, endPoint.x, endPoint.y );
|
cairo_line_to( currentContext, endPoint.x, endPoint.y );
|
||||||
cairo_close_path( currentContext );
|
cairo_close_path( currentContext );
|
||||||
}
|
}
|
||||||
|
flushPath();
|
||||||
|
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
@ -250,6 +305,7 @@ void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd
|
||||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||||
cairo_line_to( currentContext, diagonalPointB.x, diagonalPointB.y );
|
cairo_line_to( currentContext, diagonalPointB.x, diagonalPointB.y );
|
||||||
cairo_close_path( currentContext );
|
cairo_close_path( currentContext );
|
||||||
|
flushPath();
|
||||||
|
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
@ -263,6 +319,7 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl
|
||||||
aControlPointB.y, aEndPoint.x, aEndPoint.y );
|
aControlPointB.y, aEndPoint.x, aEndPoint.y );
|
||||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||||
|
|
||||||
|
flushPath();
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,10 +465,10 @@ void CAIRO_GAL::SetLayerDepth( double aLayerDepth )
|
||||||
{
|
{
|
||||||
storePath();
|
storePath();
|
||||||
|
|
||||||
cairo_pop_group_to_source( currentContext );
|
//cairo_pop_group_to_source( currentContext );
|
||||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||||
|
|
||||||
cairo_push_group( currentContext );
|
//cairo_push_group( currentContext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,8 +791,8 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
||||||
{
|
{
|
||||||
storePath();
|
storePath();
|
||||||
|
|
||||||
cairo_pop_group_to_source( currentContext );
|
//cairo_pop_group_to_source( currentContext );
|
||||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( aTarget )
|
switch( aTarget )
|
||||||
|
@ -751,8 +808,8 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isInitialized )
|
//if( isInitialized )
|
||||||
cairo_push_group( currentContext );
|
//cairo_push_group( currentContext );
|
||||||
|
|
||||||
currentTarget = aTarget;
|
currentTarget = aTarget;
|
||||||
}
|
}
|
||||||
|
@ -799,21 +856,36 @@ void CAIRO_GAL::SetCursorSize( unsigned int aCursorSize )
|
||||||
|
|
||||||
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
|
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
|
||||||
{
|
{
|
||||||
// Now we should only store the position of the mouse cursor
|
cursorPosition = aCursorPosition;
|
||||||
// The real drawing routines are in blitCursor()
|
|
||||||
cursorPosition = VECTOR2D( aCursorPosition.x - cursorSize / 2,
|
|
||||||
aCursorPosition.y - cursorSize / 2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
void CAIRO_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||||
{
|
{
|
||||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.y );
|
||||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||||
cairo_set_source_rgb( currentContext, gridColor.r, gridColor.g, gridColor.b );
|
cairo_set_source_rgba( currentContext, gridColor.r, gridColor.g, gridColor.b, strokeColor.a );
|
||||||
cairo_stroke( currentContext );
|
cairo_stroke( currentContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAIRO_GAL::flushPath()
|
||||||
|
{
|
||||||
|
if( isFillEnabled )
|
||||||
|
{
|
||||||
|
cairo_set_source_rgba( currentContext, fillColor.r, fillColor.g, fillColor.b, fillColor.a );
|
||||||
|
if( isStrokeEnabled )
|
||||||
|
cairo_fill_preserve( currentContext );
|
||||||
|
else
|
||||||
|
cairo_fill( currentContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isStrokeEnabled )
|
||||||
|
{
|
||||||
|
cairo_set_source_rgba( currentContext, strokeColor.r, strokeColor.g,
|
||||||
|
strokeColor.b, strokeColor.a );
|
||||||
|
cairo_stroke( currentContext );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL::storePath()
|
void CAIRO_GAL::storePath()
|
||||||
{
|
{
|
||||||
|
@ -902,47 +974,32 @@ void CAIRO_GAL::initCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL::blitCursor( wxBufferedDC& clientDC )
|
void CAIRO_GAL::blitCursor( wxMemoryDC& clientDC )
|
||||||
{
|
{
|
||||||
if( !isCursorEnabled )
|
if( !isCursorEnabled )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxMemoryDC cursorSave( *cursorPixelsSaved );
|
auto p = ToScreen( cursorPosition );
|
||||||
wxMemoryDC cursorShape( *cursorPixels );
|
|
||||||
|
|
||||||
if( !isDeleteSavedPixels )
|
clientDC.SetPen( *wxWHITE_PEN );
|
||||||
{
|
clientDC.DrawLine ( p.x - cursorSize / 2, p.y, p.x + cursorSize / 2, p.y );
|
||||||
// Restore pixels that were overpainted by the previous cursor
|
clientDC.DrawLine ( p.x, p.y - cursorSize / 2, p.x, p.y + cursorSize / 2 );
|
||||||
clientDC.Blit( savedCursorPosition.x, savedCursorPosition.y,
|
|
||||||
cursorSize, cursorSize, &cursorSave, 0, 0 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
isDeleteSavedPixels = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store pixels that are going to be overpainted
|
|
||||||
VECTOR2D cursorScreen = ToScreen( cursorPosition ) - cursorSize / 2.0f;
|
|
||||||
cursorSave.Blit( 0, 0, cursorSize, cursorSize, &clientDC, cursorScreen.x, cursorScreen.y );
|
|
||||||
|
|
||||||
// Draw the cursor
|
|
||||||
clientDC.Blit( cursorScreen.x, cursorScreen.y, cursorSize, cursorSize,
|
|
||||||
&cursorShape, 0, 0, wxOR );
|
|
||||||
|
|
||||||
savedCursorPosition.x = (wxCoord) cursorScreen.x;
|
|
||||||
savedCursorPosition.y = (wxCoord) cursorScreen.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CAIRO_GAL::allocateBitmaps()
|
void CAIRO_GAL::allocateBitmaps()
|
||||||
{
|
{
|
||||||
|
wxBufferWidth = screenSize.x;
|
||||||
|
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, screenSize.x );
|
stride = cairo_format_stride_for_width( GAL_FORMAT, wxBufferWidth );
|
||||||
bufferSize = stride * screenSize.y;
|
bufferSize = stride * screenSize.y;
|
||||||
|
|
||||||
bitmapBuffer = new unsigned int[bufferSize];
|
bitmapBuffer = new unsigned int[bufferSize];
|
||||||
bitmapBufferBackup = new unsigned int[bufferSize];
|
bitmapBufferBackup = new unsigned int[bufferSize];
|
||||||
wxOutput = new unsigned char[bufferSize * 3];
|
wxOutput = new unsigned char[wxBufferWidth * 3 * screenSize.y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -961,7 +1018,7 @@ void CAIRO_GAL::initSurface()
|
||||||
|
|
||||||
// Create the Cairo surface
|
// Create the Cairo surface
|
||||||
surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT,
|
surface = cairo_image_surface_create_for_data( (unsigned char*) bitmapBuffer, GAL_FORMAT,
|
||||||
screenSize.x, screenSize.y, stride );
|
wxBufferWidth, screenSize.y, stride );
|
||||||
context = cairo_create( surface );
|
context = cairo_create( surface );
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
cairo_status_t status = cairo_status( context );
|
cairo_status_t status = cairo_status( context );
|
||||||
|
@ -969,7 +1026,7 @@ void CAIRO_GAL::initSurface()
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
currentContext = context;
|
currentContext = context;
|
||||||
|
|
||||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
|
cairo_set_antialias( context, CAIRO_ANTIALIAS_NONE );
|
||||||
|
|
||||||
// Clear the screen
|
// Clear the screen
|
||||||
ClearScreen( backgroundColor );
|
ClearScreen( backgroundColor );
|
||||||
|
@ -1037,6 +1094,9 @@ void CAIRO_GAL::drawPoly( const std::deque<VECTOR2D>& aPointList )
|
||||||
cairo_line_to( currentContext, it->x, it->y );
|
cairo_line_to( currentContext, it->x, it->y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flushPath();
|
||||||
|
//cairo_fill( currentContext );
|
||||||
|
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1054,6 +1114,8 @@ void CAIRO_GAL::drawPoly( const VECTOR2D aPointList[], int aListSize )
|
||||||
cairo_line_to( currentContext, ptr->x, ptr->y );
|
cairo_line_to( currentContext, ptr->x, ptr->y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flushPath();
|
||||||
|
|
||||||
isElementAdded = true;
|
isElementAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -151,8 +151,6 @@ void GAL::DrawGrid()
|
||||||
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
||||||
int gridStartY = KiROUND( worldStartPoint.y / gridSize.y );
|
int gridStartY = KiROUND( worldStartPoint.y / gridSize.y );
|
||||||
int gridEndY = KiROUND( worldEndPoint.y / gridSize.y );
|
int gridEndY = KiROUND( worldEndPoint.y / gridSize.y );
|
||||||
int dirX = gridEndX >= gridStartX ? 1 : -1;
|
|
||||||
int dirY = gridEndY >= gridStartY ? 1 : -1;
|
|
||||||
|
|
||||||
// Correct the index, else some lines are not correctly painted
|
// Correct the index, else some lines are not correctly painted
|
||||||
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||||
|
@ -160,6 +158,9 @@ void GAL::DrawGrid()
|
||||||
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 1;
|
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||||
gridEndY += std::abs( gridOrigin.y / gridSize.y ) + 1;
|
gridEndY += std::abs( gridOrigin.y / gridSize.y ) + 1;
|
||||||
|
|
||||||
|
int dirX = gridEndX >= gridStartX ? 1 : -1;
|
||||||
|
int dirY = gridEndY >= gridStartY ? 1 : -1;
|
||||||
|
|
||||||
// Draw the grid behind all other layers
|
// Draw the grid behind all other layers
|
||||||
SetLayerDepth( depthRange.y * 0.75 );
|
SetLayerDepth( depthRange.y * 0.75 );
|
||||||
|
|
||||||
|
|
|
@ -878,8 +878,6 @@ void OPENGL_GAL::DrawGrid()
|
||||||
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
||||||
int gridStartY = KiROUND( worldStartPoint.y / gridSize.y );
|
int gridStartY = KiROUND( worldStartPoint.y / gridSize.y );
|
||||||
int gridEndY = KiROUND( worldEndPoint.y / gridSize.y );
|
int gridEndY = KiROUND( worldEndPoint.y / gridSize.y );
|
||||||
int dirX = gridStartX >= gridEndX ? -1 : 1;
|
|
||||||
int dirY = gridStartY >= gridEndY ? -1 : 1;
|
|
||||||
|
|
||||||
// Correct the index, else some lines are not correctly painted
|
// Correct the index, else some lines are not correctly painted
|
||||||
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||||
|
@ -887,6 +885,9 @@ void OPENGL_GAL::DrawGrid()
|
||||||
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 1;
|
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||||
gridEndY += std::abs( gridOrigin.y / gridSize.y ) + 1;
|
gridEndY += std::abs( gridOrigin.y / gridSize.y ) + 1;
|
||||||
|
|
||||||
|
int dirX = gridStartX >= gridEndX ? -1 : 1;
|
||||||
|
int dirY = gridStartY >= gridEndY ? -1 : 1;
|
||||||
|
|
||||||
glDisable( GL_DEPTH_TEST );
|
glDisable( GL_DEPTH_TEST );
|
||||||
glDisable( GL_TEXTURE_2D );
|
glDisable( GL_TEXTURE_2D );
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,7 @@ VIEW::VIEW( bool aIsDynamic ) :
|
||||||
m_dynamic( aIsDynamic )
|
m_dynamic( aIsDynamic )
|
||||||
{
|
{
|
||||||
m_boundary.SetMaximum();
|
m_boundary.SetMaximum();
|
||||||
m_needsUpdate.reserve( 32768 );
|
m_allItems.reserve( 32768 );
|
||||||
|
|
||||||
// Redraw everything at the beginning
|
// Redraw everything at the beginning
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
|
@ -310,6 +310,8 @@ void VIEW::Add( VIEW_ITEM* aItem )
|
||||||
aItem->ViewGetLayers( layers, layers_count );
|
aItem->ViewGetLayers( layers, layers_count );
|
||||||
aItem->viewPrivData()->saveLayers( layers, layers_count );
|
aItem->viewPrivData()->saveLayers( layers, layers_count );
|
||||||
|
|
||||||
|
m_allItems.push_back(aItem);
|
||||||
|
|
||||||
for( int i = 0; i < layers_count; ++i )
|
for( int i = 0; i < layers_count; ++i )
|
||||||
{
|
{
|
||||||
VIEW_LAYER& l = m_layers[layers[i]];
|
VIEW_LAYER& l = m_layers[layers[i]];
|
||||||
|
@ -326,22 +328,19 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
||||||
{
|
{
|
||||||
if ( !aItem )
|
if ( !aItem )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto viewData = aItem->viewPrivData();
|
auto viewData = aItem->viewPrivData();
|
||||||
|
|
||||||
if ( !viewData )
|
if ( !viewData )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( viewData->requiredUpdate() != NONE ) // prevent from updating a removed item
|
auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
|
||||||
{
|
|
||||||
std::vector<VIEW_ITEM*>::iterator item = std::find( m_needsUpdate.begin(),
|
|
||||||
m_needsUpdate.end(), aItem );
|
|
||||||
|
|
||||||
if( item != m_needsUpdate.end() )
|
if( item != m_allItems.end() )
|
||||||
{
|
{
|
||||||
m_needsUpdate.erase( item );
|
m_allItems.erase( item );
|
||||||
viewData->clearUpdateFlags();
|
viewData->clearUpdateFlags();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||||
viewData->getLayers( layers, layers_count );
|
viewData->getLayers( layers, layers_count );
|
||||||
|
@ -360,6 +359,7 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
viewData->deleteGroups();
|
viewData->deleteGroups();
|
||||||
|
|
||||||
aItem->m_viewPrivData = nullptr;
|
aItem->m_viewPrivData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,10 +946,7 @@ void VIEW::Clear()
|
||||||
|
|
||||||
r.SetMaximum();
|
r.SetMaximum();
|
||||||
|
|
||||||
for( VIEW_ITEM* item : m_needsUpdate )
|
m_allItems.clear();
|
||||||
item->viewPrivData()->clearUpdateFlags();
|
|
||||||
|
|
||||||
m_needsUpdate.clear();
|
|
||||||
|
|
||||||
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
|
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||||
{
|
{
|
||||||
|
@ -1237,16 +1234,16 @@ void VIEW::UpdateItems()
|
||||||
{
|
{
|
||||||
m_gal->BeginUpdate();
|
m_gal->BeginUpdate();
|
||||||
|
|
||||||
for( VIEW_ITEM* item : m_needsUpdate )
|
for( VIEW_ITEM* item : m_allItems )
|
||||||
{
|
{
|
||||||
auto viewData = item->viewPrivData();
|
auto viewData = item->viewPrivData();
|
||||||
assert( viewData->m_requiredUpdate != NONE );
|
|
||||||
|
|
||||||
|
if ( viewData->m_requiredUpdate != NONE )
|
||||||
invalidateItem( item, viewData->m_requiredUpdate );
|
invalidateItem( item, viewData->m_requiredUpdate );
|
||||||
|
viewData->m_requiredUpdate = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gal->EndUpdate();
|
m_gal->EndUpdate();
|
||||||
m_needsUpdate.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1341,31 +1338,10 @@ void VIEW::Update( VIEW_ITEM *aItem, int aUpdateFlags )
|
||||||
|
|
||||||
assert( aUpdateFlags != NONE );
|
assert( aUpdateFlags != NONE );
|
||||||
|
|
||||||
bool firstTime = (viewData->m_requiredUpdate == NONE);
|
|
||||||
|
|
||||||
viewData->m_requiredUpdate |= aUpdateFlags;
|
viewData->m_requiredUpdate |= aUpdateFlags;
|
||||||
|
|
||||||
if( firstTime )
|
|
||||||
{
|
|
||||||
MarkForUpdate( aItem );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void VIEW::MarkForUpdate( VIEW_ITEM* aItem )
|
|
||||||
{
|
|
||||||
auto viewData = aItem->viewPrivData();
|
|
||||||
|
|
||||||
assert( viewData->m_requiredUpdate != NONE );
|
|
||||||
|
|
||||||
for ( auto item : m_needsUpdate )
|
|
||||||
assert(item != aItem);
|
|
||||||
|
|
||||||
m_needsUpdate.push_back( aItem );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
|
const int VIEW::TOP_LAYER_MODIFIER = -VIEW_MAX_LAYERS;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -118,7 +118,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
|
||||||
|
|
||||||
for( int i = 0; i < layers_count; i++ )
|
for( int i = 0; i < layers_count; i++ )
|
||||||
{
|
{
|
||||||
if( aView->IsCached( layers[i] ) && aView->IsLayerVisible( layers[i] ) )
|
if( aView->IsLayerVisible( layers[i] ) )
|
||||||
{
|
{
|
||||||
gal->AdvanceDepth();
|
gal->AdvanceDepth();
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
* Switches method of rendering graphics.
|
* Switches method of rendering graphics.
|
||||||
* @param aGalType is a type of rendering engine that you want to use.
|
* @param aGalType is a type of rendering engine that you want to use.
|
||||||
*/
|
*/
|
||||||
bool SwitchBackend( GAL_TYPE aGalType );
|
virtual bool SwitchBackend( GAL_TYPE aGalType );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetBackend
|
* Function GetBackend
|
||||||
|
|
|
@ -346,6 +346,9 @@ private:
|
||||||
bool isInitialized; ///< Are Cairo image & surface ready to use
|
bool isInitialized; ///< Are Cairo image & surface ready to use
|
||||||
COLOR4D backgroundColor; ///< Background color
|
COLOR4D backgroundColor; ///< Background color
|
||||||
|
|
||||||
|
int wxBufferWidth;
|
||||||
|
|
||||||
|
void flushPath();
|
||||||
// Methods
|
// Methods
|
||||||
void storePath(); ///< Store the actual path
|
void storePath(); ///< Store the actual path
|
||||||
|
|
||||||
|
@ -372,7 +375,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* @brief Blits cursor into the current screen.
|
* @brief Blits cursor into the current screen.
|
||||||
*/
|
*/
|
||||||
virtual void blitCursor( wxBufferedDC& clientDC );
|
virtual void blitCursor( wxMemoryDC& clientDC );
|
||||||
|
|
||||||
/// Prepare Cairo surfaces for drawing
|
/// Prepare Cairo surfaces for drawing
|
||||||
void initSurface();
|
void initSurface();
|
||||||
|
|
|
@ -119,7 +119,9 @@ public:
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
fprintf(stderr,"%s took %.1f milliseconds.\n", m_name.c_str(), (double)m_cnt.msecs());
|
fprintf(stderr,"%s took %.1f milliseconds.\n", m_name.c_str(), (double)m_cnt.msecs());
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
double msecs() const {
|
double msecs() const {
|
||||||
return m_cnt.msecs();
|
return m_cnt.msecs();
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,8 +751,8 @@ private:
|
||||||
/// Rendering order modifier for layers that are marked as top layers
|
/// Rendering order modifier for layers that are marked as top layers
|
||||||
static const int TOP_LAYER_MODIFIER;
|
static const int TOP_LAYER_MODIFIER;
|
||||||
|
|
||||||
/// Items to be updated
|
/// Flat list of all items
|
||||||
std::vector<VIEW_ITEM*> m_needsUpdate;
|
std::vector<VIEW_ITEM*> m_allItems;
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,12 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerOrder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PCB_DRAW_PANEL_GAL::SwitchBackend( GAL_TYPE aGalType )
|
||||||
|
{
|
||||||
|
bool rv = EDA_DRAW_PANEL_GAL::SwitchBackend ( aGalType );
|
||||||
|
setDefaultLayerDeps();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
||||||
{
|
{
|
||||||
|
@ -400,6 +406,13 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// caching makes no sense for Cairo and other software renderers
|
||||||
|
if ( m_backend != GAL_TYPE_OPENGL )
|
||||||
|
{
|
||||||
|
for (int i = 0; i < KIGFX::VIEW::VIEW_MAX_LAYERS; i++)
|
||||||
|
m_view->SetLayerTarget(i, KIGFX::TARGET_NONCACHED);
|
||||||
|
}
|
||||||
|
|
||||||
m_view->SetLayerTarget( ITEM_GAL_LAYER( ANCHOR_VISIBLE ), KIGFX::TARGET_NONCACHED );
|
m_view->SetLayerTarget( ITEM_GAL_LAYER( ANCHOR_VISIBLE ), KIGFX::TARGET_NONCACHED );
|
||||||
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( ANCHOR_VISIBLE ) );
|
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( ANCHOR_VISIBLE ) );
|
||||||
|
|
||||||
|
@ -438,4 +451,5 @@ void PCB_DRAW_PANEL_GAL::setDefaultLayerDeps()
|
||||||
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( WORKSHEET ) );
|
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( WORKSHEET ) );
|
||||||
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( GRID_VISIBLE ) );
|
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( GRID_VISIBLE ) );
|
||||||
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( DRC_VISIBLE ) );
|
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( DRC_VISIBLE ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,8 @@ public:
|
||||||
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
|
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
|
||||||
void OnShow() override;
|
void OnShow() override;
|
||||||
|
|
||||||
|
bool SwitchBackend( GAL_TYPE aGalType ) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
///> Reassigns layer order to the initial settings.
|
///> Reassigns layer order to the initial settings.
|
||||||
void setDefaultLayerOrder();
|
void setDefaultLayerOrder();
|
||||||
|
|
Loading…
Reference in New Issue