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_package( Cairo 1.8.8 REQUIRED )
|
||||
find_package( Pixman 1.0 REQUIRED )
|
||||
|
||||
#
|
||||
# Find Boost library, required.
|
||||
|
|
|
@ -4,6 +4,7 @@ include_directories(
|
|||
./widgets
|
||||
./dialog_about
|
||||
${CAIRO_INCLUDE_DIR}
|
||||
${PIXMAN_INCLUDE_DIR}
|
||||
${GLEW_INCLUDE_DIR}
|
||||
${GLM_INCLUDE_DIR}
|
||||
${CURL_INCLUDE_DIRS}
|
||||
|
|
|
@ -89,7 +89,7 @@ unsigned int CAIRO_COMPOSITOR::CreateBuffer()
|
|||
#endif /* __WXDEBUG__ */
|
||||
|
||||
// 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_cap( context, CAIRO_LINE_CAP_ROUND );
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
#include <pixman.h>
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
|
||||
const float CAIRO_GAL::LAYER_ALPHA = 0.8;
|
||||
|
||||
|
||||
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||
wxEvtHandler* aPaintListener, const wxString& aName ) :
|
||||
|
@ -111,46 +111,94 @@ void CAIRO_GAL::BeginDrawing()
|
|||
compositor->SetBuffer( mainBuffer );
|
||||
|
||||
// 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()
|
||||
{
|
||||
|
||||
printf("EndDRAW!\n\n\n");
|
||||
// Force remaining objects to be drawn
|
||||
Flush();
|
||||
|
||||
// Cairo grouping prevents display of overlapping items on the same layer in the lighter color
|
||||
cairo_pop_group_to_source( currentContext );
|
||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
//cairo_pop_group_to_source( currentContext );
|
||||
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
|
||||
// Merge buffers on the screen
|
||||
PROF_COUNTER comp("cairo-comp");
|
||||
compositor->DrawBuffer( mainBuffer );
|
||||
compositor->DrawBuffer( overlayBuffer );
|
||||
comp.show();
|
||||
|
||||
// This code was taken from the wxCairo example - it's not the most efficient one
|
||||
// Here is a good place for optimizations
|
||||
|
||||
// Now translate the raw context data from the format stored
|
||||
// by cairo into a format understood by wxImage.
|
||||
|
||||
PROF_COUNTER draw("cairo-draw");
|
||||
|
||||
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];
|
||||
*wxOutputPtr++ = ( value >> 16 ) & 0xff; // Red pixel
|
||||
*wxOutputPtr++ = ( value >> 8 ) & 0xff; // Green 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 );
|
||||
wxClientDC client_dc( this );
|
||||
wxBufferedDC dc;
|
||||
dc.Init( &client_dc, bmp );
|
||||
wxd2.show();
|
||||
PROF_COUNTER wxd3("wx-draw2");
|
||||
|
||||
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
|
||||
blitCursor( dc );
|
||||
|
||||
deinitSurface();
|
||||
}
|
||||
|
@ -158,8 +206,12 @@ void CAIRO_GAL::EndDrawing()
|
|||
|
||||
void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
|
||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.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;
|
||||
}
|
||||
|
||||
|
@ -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_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
|
||||
{
|
||||
|
@ -197,6 +251,7 @@ void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPo
|
|||
cairo_line_to( currentContext, lineLength, -aWidth / 2.0 );
|
||||
|
||||
cairo_restore( currentContext );
|
||||
flushPath();
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
// A circle is drawn using an arc
|
||||
cairo_new_sub_path( currentContext );
|
||||
cairo_arc( currentContext, aCenterPoint.x, aCenterPoint.y, aRadius, 0.0, 2 * M_PI );
|
||||
|
||||
flushPath();
|
||||
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_close_path( currentContext );
|
||||
}
|
||||
flushPath();
|
||||
|
||||
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, diagonalPointB.x, diagonalPointB.y );
|
||||
cairo_close_path( currentContext );
|
||||
flushPath();
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
@ -263,6 +319,7 @@ void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControl
|
|||
aControlPointB.y, aEndPoint.x, aEndPoint.y );
|
||||
cairo_line_to( currentContext, aEndPoint.x, aEndPoint.y );
|
||||
|
||||
flushPath();
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
@ -408,10 +465,10 @@ void CAIRO_GAL::SetLayerDepth( double aLayerDepth )
|
|||
{
|
||||
storePath();
|
||||
|
||||
cairo_pop_group_to_source( currentContext );
|
||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
//cairo_pop_group_to_source( currentContext );
|
||||
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
|
||||
cairo_push_group( currentContext );
|
||||
//cairo_push_group( currentContext );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -593,7 +650,7 @@ void CAIRO_GAL::DrawGroup( int aGroupNumber )
|
|||
case CMD_STROKE_PATH:
|
||||
cairo_set_source_rgb( currentContext, strokeColor.r, strokeColor.g, strokeColor.b );
|
||||
cairo_append_path( currentContext, it->cairoPath );
|
||||
cairo_stroke( currentContext );
|
||||
cairo_stroke( currentContext );
|
||||
break;
|
||||
|
||||
case CMD_FILL_PATH:
|
||||
|
@ -734,8 +791,8 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
|||
{
|
||||
storePath();
|
||||
|
||||
cairo_pop_group_to_source( currentContext );
|
||||
cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
//cairo_pop_group_to_source( currentContext );
|
||||
//cairo_paint_with_alpha( currentContext, LAYER_ALPHA );
|
||||
}
|
||||
|
||||
switch( aTarget )
|
||||
|
@ -751,8 +808,8 @@ void CAIRO_GAL::SetTarget( RENDER_TARGET aTarget )
|
|||
break;
|
||||
}
|
||||
|
||||
if( isInitialized )
|
||||
cairo_push_group( currentContext );
|
||||
//if( isInitialized )
|
||||
//cairo_push_group( currentContext );
|
||||
|
||||
currentTarget = aTarget;
|
||||
}
|
||||
|
@ -799,21 +856,36 @@ void CAIRO_GAL::SetCursorSize( unsigned int aCursorSize )
|
|||
|
||||
void CAIRO_GAL::DrawCursor( const VECTOR2D& aCursorPosition )
|
||||
{
|
||||
// Now we should only store the position of the mouse cursor
|
||||
// The real drawing routines are in blitCursor()
|
||||
cursorPosition = VECTOR2D( aCursorPosition.x - cursorSize / 2,
|
||||
aCursorPosition.y - cursorSize / 2 );
|
||||
cursorPosition = aCursorPosition;
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||
{
|
||||
cairo_move_to( currentContext, aStartPoint.x, aStartPoint.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 );
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -902,47 +974,32 @@ void CAIRO_GAL::initCursor()
|
|||
}
|
||||
|
||||
|
||||
void CAIRO_GAL::blitCursor( wxBufferedDC& clientDC )
|
||||
void CAIRO_GAL::blitCursor( wxMemoryDC& clientDC )
|
||||
{
|
||||
if( !isCursorEnabled )
|
||||
return;
|
||||
|
||||
wxMemoryDC cursorSave( *cursorPixelsSaved );
|
||||
wxMemoryDC cursorShape( *cursorPixels );
|
||||
auto p = ToScreen( cursorPosition );
|
||||
|
||||
if( !isDeleteSavedPixels )
|
||||
{
|
||||
// Restore pixels that were overpainted by the previous cursor
|
||||
clientDC.Blit( savedCursorPosition.x, savedCursorPosition.y,
|
||||
cursorSize, cursorSize, &cursorSave, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
isDeleteSavedPixels = false;
|
||||
}
|
||||
clientDC.SetPen( *wxWHITE_PEN );
|
||||
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 );
|
||||
|
||||
// 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()
|
||||
{
|
||||
wxBufferWidth = screenSize.x;
|
||||
while( ((wxBufferWidth * 3) % 4) != 0 ) wxBufferWidth++;
|
||||
|
||||
// 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;
|
||||
|
||||
bitmapBuffer = 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
|
||||
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 );
|
||||
#ifdef __WXDEBUG__
|
||||
cairo_status_t status = cairo_status( context );
|
||||
|
@ -969,7 +1026,7 @@ void CAIRO_GAL::initSurface()
|
|||
#endif /* __WXDEBUG__ */
|
||||
currentContext = context;
|
||||
|
||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_SUBPIXEL );
|
||||
cairo_set_antialias( context, CAIRO_ANTIALIAS_NONE );
|
||||
|
||||
// Clear the screen
|
||||
ClearScreen( backgroundColor );
|
||||
|
@ -1037,6 +1094,9 @@ void CAIRO_GAL::drawPoly( const std::deque<VECTOR2D>& aPointList )
|
|||
cairo_line_to( currentContext, it->x, it->y );
|
||||
}
|
||||
|
||||
flushPath();
|
||||
//cairo_fill( currentContext );
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
@ -1054,6 +1114,8 @@ void CAIRO_GAL::drawPoly( const VECTOR2D aPointList[], int aListSize )
|
|||
cairo_line_to( currentContext, ptr->x, ptr->y );
|
||||
}
|
||||
|
||||
flushPath();
|
||||
|
||||
isElementAdded = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,8 +151,6 @@ void GAL::DrawGrid()
|
|||
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
||||
int gridStartY = KiROUND( worldStartPoint.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
|
||||
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||
|
@ -160,6 +158,9 @@ void GAL::DrawGrid()
|
|||
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 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
|
||||
SetLayerDepth( depthRange.y * 0.75 );
|
||||
|
||||
|
|
|
@ -878,8 +878,6 @@ void OPENGL_GAL::DrawGrid()
|
|||
int gridEndX = KiROUND( worldEndPoint.x / gridSize.x );
|
||||
int gridStartY = KiROUND( worldStartPoint.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
|
||||
gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1;
|
||||
|
@ -887,6 +885,9 @@ void OPENGL_GAL::DrawGrid()
|
|||
gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 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_TEXTURE_2D );
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ VIEW::VIEW( bool aIsDynamic ) :
|
|||
m_dynamic( aIsDynamic )
|
||||
{
|
||||
m_boundary.SetMaximum();
|
||||
m_needsUpdate.reserve( 32768 );
|
||||
m_allItems.reserve( 32768 );
|
||||
|
||||
// Redraw everything at the beginning
|
||||
MarkDirty();
|
||||
|
@ -310,6 +310,8 @@ void VIEW::Add( VIEW_ITEM* aItem )
|
|||
aItem->ViewGetLayers( layers, layers_count );
|
||||
aItem->viewPrivData()->saveLayers( layers, layers_count );
|
||||
|
||||
m_allItems.push_back(aItem);
|
||||
|
||||
for( int i = 0; i < layers_count; ++i )
|
||||
{
|
||||
VIEW_LAYER& l = m_layers[layers[i]];
|
||||
|
@ -326,21 +328,18 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
|||
{
|
||||
if ( !aItem )
|
||||
return;
|
||||
|
||||
auto viewData = aItem->viewPrivData();
|
||||
|
||||
if ( !viewData )
|
||||
return;
|
||||
|
||||
if( viewData->requiredUpdate() != NONE ) // prevent from updating a removed item
|
||||
{
|
||||
std::vector<VIEW_ITEM*>::iterator item = std::find( m_needsUpdate.begin(),
|
||||
m_needsUpdate.end(), aItem );
|
||||
auto item = std::find( m_allItems.begin(), m_allItems.end(), aItem );
|
||||
|
||||
if( item != m_needsUpdate.end() )
|
||||
{
|
||||
m_needsUpdate.erase( item );
|
||||
viewData->clearUpdateFlags();
|
||||
}
|
||||
if( item != m_allItems.end() )
|
||||
{
|
||||
m_allItems.erase( item );
|
||||
viewData->clearUpdateFlags();
|
||||
}
|
||||
|
||||
int layers[VIEW::VIEW_MAX_LAYERS], layers_count;
|
||||
|
@ -360,6 +359,7 @@ void VIEW::Remove( VIEW_ITEM* aItem )
|
|||
}
|
||||
|
||||
viewData->deleteGroups();
|
||||
|
||||
aItem->m_viewPrivData = nullptr;
|
||||
}
|
||||
|
||||
|
@ -946,10 +946,7 @@ void VIEW::Clear()
|
|||
|
||||
r.SetMaximum();
|
||||
|
||||
for( VIEW_ITEM* item : m_needsUpdate )
|
||||
item->viewPrivData()->clearUpdateFlags();
|
||||
|
||||
m_needsUpdate.clear();
|
||||
m_allItems.clear();
|
||||
|
||||
for( LAYER_MAP_ITER i = m_layers.begin(); i != m_layers.end(); ++i )
|
||||
{
|
||||
|
@ -1237,16 +1234,16 @@ void VIEW::UpdateItems()
|
|||
{
|
||||
m_gal->BeginUpdate();
|
||||
|
||||
for( VIEW_ITEM* item : m_needsUpdate )
|
||||
for( VIEW_ITEM* item : m_allItems )
|
||||
{
|
||||
auto viewData = item->viewPrivData();
|
||||
assert( viewData->m_requiredUpdate != NONE );
|
||||
|
||||
invalidateItem( item, viewData->m_requiredUpdate );
|
||||
if ( viewData->m_requiredUpdate != NONE )
|
||||
invalidateItem( item, viewData->m_requiredUpdate );
|
||||
viewData->m_requiredUpdate = NONE;
|
||||
}
|
||||
|
||||
m_gal->EndUpdate();
|
||||
m_needsUpdate.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1341,31 +1338,10 @@ void VIEW::Update( VIEW_ITEM *aItem, int aUpdateFlags )
|
|||
|
||||
assert( aUpdateFlags != NONE );
|
||||
|
||||
bool firstTime = (viewData->m_requiredUpdate == NONE);
|
||||
|
||||
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;
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -118,7 +118,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
|
|||
|
||||
for( int i = 0; i < layers_count; i++ )
|
||||
{
|
||||
if( aView->IsCached( layers[i] ) && aView->IsLayerVisible( layers[i] ) )
|
||||
if( aView->IsLayerVisible( layers[i] ) )
|
||||
{
|
||||
gal->AdvanceDepth();
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
* Switches method of rendering graphics.
|
||||
* @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
|
||||
|
|
|
@ -346,6 +346,9 @@ private:
|
|||
bool isInitialized; ///< Are Cairo image & surface ready to use
|
||||
COLOR4D backgroundColor; ///< Background color
|
||||
|
||||
int wxBufferWidth;
|
||||
|
||||
void flushPath();
|
||||
// Methods
|
||||
void storePath(); ///< Store the actual path
|
||||
|
||||
|
@ -372,7 +375,7 @@ private:
|
|||
/**
|
||||
* @brief Blits cursor into the current screen.
|
||||
*/
|
||||
virtual void blitCursor( wxBufferedDC& clientDC );
|
||||
virtual void blitCursor( wxMemoryDC& clientDC );
|
||||
|
||||
/// Prepare Cairo surfaces for drawing
|
||||
void initSurface();
|
||||
|
|
|
@ -119,7 +119,9 @@ public:
|
|||
{
|
||||
stop();
|
||||
fprintf(stderr,"%s took %.1f milliseconds.\n", m_name.c_str(), (double)m_cnt.msecs());
|
||||
start();
|
||||
}
|
||||
|
||||
double msecs() const {
|
||||
return m_cnt.msecs();
|
||||
}
|
||||
|
|
|
@ -751,8 +751,8 @@ private:
|
|||
/// Rendering order modifier for layers that are marked as top layers
|
||||
static const int TOP_LAYER_MODIFIER;
|
||||
|
||||
/// Items to be updated
|
||||
std::vector<VIEW_ITEM*> m_needsUpdate;
|
||||
/// Flat list of all items
|
||||
std::vector<VIEW_ITEM*> m_allItems;
|
||||
};
|
||||
} // 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()
|
||||
{
|
||||
|
@ -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->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( GRID_VISIBLE ) );
|
||||
m_view->SetLayerDisplayOnly( ITEM_GAL_LAYER( DRC_VISIBLE ) );
|
||||
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
///> @copydoc EDA_DRAW_PANEL_GAL::OnShow()
|
||||
void OnShow() override;
|
||||
|
||||
bool SwitchBackend( GAL_TYPE aGalType ) override;
|
||||
|
||||
protected:
|
||||
///> Reassigns layer order to the initial settings.
|
||||
void setDefaultLayerOrder();
|
||||
|
|
Loading…
Reference in New Issue