From da28e163d2aef547949c89809c6adbbd6e8db7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch> Date: Wed, 7 Dec 2016 10:20:31 +0100 Subject: [PATCH] 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 --- CMakeLists.txt | 1 + common/CMakeLists.txt | 1 + common/gal/cairo/cairo_compositor.cpp | 2 +- common/gal/cairo/cairo_gal.cpp | 172 +++++++++++++++------- common/gal/graphics_abstraction_layer.cpp | 5 +- common/gal/opengl/opengl_gal.cpp | 5 +- common/view/view.cpp | 54 ++----- common/view/view_group.cpp | 4 +- include/class_draw_panel_gal.h | 2 +- include/gal/cairo/cairo_gal.h | 5 +- include/profile.h | 2 + include/view/view.h | 4 +- pcbnew/pcb_draw_panel_gal.cpp | 14 ++ pcbnew/pcb_draw_panel_gal.h | 2 + 14 files changed, 168 insertions(+), 105 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 42afeabcb1..8d71af2c60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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. diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index c89470c55a..034fa552dd 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories( ./widgets ./dialog_about ${CAIRO_INCLUDE_DIR} + ${PIXMAN_INCLUDE_DIR} ${GLEW_INCLUDE_DIR} ${GLM_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} diff --git a/common/gal/cairo/cairo_compositor.cpp b/common/gal/cairo/cairo_compositor.cpp index f81cb5a0bd..813c554c76 100644 --- a/common/gal/cairo/cairo_compositor.cpp +++ b/common/gal/cairo/cairo_compositor.cpp @@ -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 ); diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 0328eccb82..89f4f97933 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -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; } diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index b6206c790e..a4432f66c7 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -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 ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 2fba9a2c2c..515050101c 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -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 ); diff --git a/common/view/view.cpp b/common/view/view.cpp index 459474fd50..3403a2afd0 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -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; - }; diff --git a/common/view/view_group.cpp b/common/view/view_group.cpp index b55b1a4dba..3926090b11 100644 --- a/common/view/view_group.cpp +++ b/common/view/view_group.cpp @@ -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(); @@ -172,5 +172,5 @@ void VIEW_GROUP::ItemsViewUpdate( VIEW_ITEM::VIEW_UPDATE_FLAGS aFlags ) void VIEW_GROUP::updateBbox() { - + } diff --git a/include/class_draw_panel_gal.h b/include/class_draw_panel_gal.h index 77133d9fcf..d7f026fd6c 100644 --- a/include/class_draw_panel_gal.h +++ b/include/class_draw_panel_gal.h @@ -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 diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 9e5f249f32..9785613d82 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -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(); diff --git a/include/profile.h b/include/profile.h index d14f29d889..780e68e826 100644 --- a/include/profile.h +++ b/include/profile.h @@ -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(); } diff --git a/include/view/view.h b/include/view/view.h index 451bc4ab01..806d875b01 100644 --- a/include/view/view.h +++ b/include/view/view.h @@ -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 diff --git a/pcbnew/pcb_draw_panel_gal.cpp b/pcbnew/pcb_draw_panel_gal.cpp index c7b37a0245..93bcf83798 100644 --- a/pcbnew/pcb_draw_panel_gal.cpp +++ b/pcbnew/pcb_draw_panel_gal.cpp @@ -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 ) ); + } diff --git a/pcbnew/pcb_draw_panel_gal.h b/pcbnew/pcb_draw_panel_gal.h index f4e397dc15..7911919ebe 100644 --- a/pcbnew/pcb_draw_panel_gal.h +++ b/pcbnew/pcb_draw_panel_gal.h @@ -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();