7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-07 22:05:32 +00:00

Revert "Support hidpi in Cairo GAL canvas; performance improvements."

This reverts commit 8e90063258.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19150
This commit is contained in:
Alex Shvartzkop 2024-12-02 22:44:20 +03:00
parent e4ac4e1d34
commit 55ca13e7cf
4 changed files with 60 additions and 81 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2017 CERN
* Copyright (C) 2013-2024, 2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
@ -277,10 +277,20 @@ bool EDA_DRAW_PANEL_GAL::DoRePaint()
m_gal->SetGridColor( settings->GetGridColor() );
m_gal->SetCursorColor( settings->GetCursorColor() );
m_gal->ClearScreen();
// TODO: find why ClearScreen() must be called here in opengl mode
// and only if m_view->IsDirty() in Cairo mode to avoid display artifacts
// when moving the mouse cursor
if( m_backend == GAL_TYPE_OPENGL )
m_gal->ClearScreen();
if( m_view->IsDirty() )
{
if( m_backend != GAL_TYPE_OPENGL // Already called in opengl
&& m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) )
{
m_gal->ClearScreen();
}
m_view->ClearTargets();
// Grid has to be redrawn only when the NONCACHED target is redrawn

View File

@ -2,7 +2,7 @@
* 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-2024 Kicad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2018 CERN
*
* @author Maciej Suminski <maciej.suminski@cern.ch>
@ -29,7 +29,6 @@
#include <wx/image.h>
#include <wx/log.h>
#include <wx/rawbmp.h>
#include <gal/cairo/cairo_gal.h>
#include <gal/cairo/cairo_compositor.h>
@ -583,9 +582,6 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
void CAIRO_GAL_BASE::ResizeScreen( int aWidth, int aHeight )
{
m_screenSize = VECTOR2I( aWidth, aHeight );
m_bitmapSize = VECTOR2I( std::ceil( m_screenSize.x * getScalingFactor() ),
std::ceil( m_screenSize.y * getScalingFactor() ) );
}
@ -597,9 +593,9 @@ void CAIRO_GAL_BASE::Flush()
void CAIRO_GAL_BASE::ClearScreen()
{
cairo_set_source_rgb( m_context, m_clearColor.r, m_clearColor.g, m_clearColor.b );
cairo_rectangle( m_context, 0.0, 0.0, m_bitmapSize.x, m_bitmapSize.y );
cairo_fill( m_context );
cairo_set_source_rgb( m_currentContext, m_clearColor.r, m_clearColor.g, m_clearColor.b );
cairo_rectangle( m_currentContext, 0.0, 0.0, m_screenSize.x, m_screenSize.y );
cairo_fill( m_currentContext );
}
@ -1024,15 +1020,15 @@ void CAIRO_GAL_BASE::resetContext()
m_imageSurfaces.clear();
ClearScreen();
// Compute the world <-> screen transformations
ComputeWorldScreenMatrix();
double sf = getScalingFactor();
cairo_matrix_init( &m_cairoWorldScreenMatrix,
m_worldScreenMatrix.m_data[0][0] * sf, m_worldScreenMatrix.m_data[1][0] * sf,
m_worldScreenMatrix.m_data[0][1] * sf, m_worldScreenMatrix.m_data[1][1] * sf,
m_worldScreenMatrix.m_data[0][2] * sf, m_worldScreenMatrix.m_data[1][2] * sf );
cairo_matrix_init( &m_cairoWorldScreenMatrix, m_worldScreenMatrix.m_data[0][0],
m_worldScreenMatrix.m_data[1][0], m_worldScreenMatrix.m_data[0][1],
m_worldScreenMatrix.m_data[1][1], m_worldScreenMatrix.m_data[0][2],
m_worldScreenMatrix.m_data[1][2] );
// we work in screen-space coordinates and do the transforms outside.
cairo_identity_matrix( m_context );
@ -1340,10 +1336,8 @@ CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
m_currentTarget = TARGET_NONCACHED;
SetTarget( TARGET_NONCACHED );
SetBackgroundStyle( wxBG_STYLE_PAINT );
m_bitmapBuffer = nullptr;
m_wxBitmap = nullptr;
m_wxOutput = nullptr;
m_parentWindow = aParent;
m_mouseListener = aMouseListener;
@ -1382,6 +1376,10 @@ CAIRO_GAL::CAIRO_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
Bind( wxEVT_GESTURE_PAN, &CAIRO_GAL::skipGestureEvent, this );
SetSize( aParent->GetClientSize() );
m_screenSize = ToVECTOR2I( aParent->GetClientSize() );
// Allocate memory for pixel storage
allocateBitmaps();
m_isInitialized = false;
}
@ -1417,44 +1415,45 @@ void CAIRO_GAL::EndDrawing()
// Now translate the raw context data from the format stored
// by cairo into a format understood by wxImage.
int height = m_bitmapSize.y;
int height = m_screenSize.y;
int stride = m_stride;
unsigned char* srcRow = m_bitmapBuffer;
wxNativePixelData dstData( *m_wxBitmap );
wxNativePixelData::Iterator di( dstData );
unsigned char* dst = m_wxOutput;
for( int y = 0; y < height; y++ )
{
wxNativePixelData::Iterator rowStart = di;
for( int x = 0; x < stride; x += 4, ++di )
for( int x = 0; x < stride; x += 4 )
{
const unsigned char* src = srcRow + x;
#if defined( __BYTE_ORDER__ ) && ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
// XRGB
di.Red() = src[1];
di.Green() = src[2];
di.Blue() = src[3];
dst[0] = src[1];
dst[1] = src[2];
dst[2] = src[3];
#else
// BGRX
di.Red() = src[2];
di.Green() = src[1];
di.Blue() = src[0];
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
#endif
dst += 3;
}
srcRow += stride;
di = rowStart;
di.OffsetY( dstData, 1 );
}
deinitSurface();
wxImage img( m_wxBufferWidth, m_screenSize.y, m_wxOutput, true );
wxBitmap bmp( img );
wxMemoryDC mdc( bmp );
wxClientDC clientDC( this );
Refresh(); // Trigger repaint
// Now it is the time to blit the mouse cursor
blitCursor( mdc );
clientDC.Blit( 0, 0, m_screenSize.x, m_screenSize.y, &mdc, 0, 0, wxCOPY );
deinitSurface();
}
@ -1475,7 +1474,7 @@ void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight )
allocateBitmaps();
if( m_validCompositor )
m_compositor->Resize( m_bitmapSize.x, m_bitmapSize.y );
m_compositor->Resize( aWidth, aHeight );
m_validCompositor = false;
@ -1566,7 +1565,7 @@ void CAIRO_GAL::initSurface()
return;
m_surface = cairo_image_surface_create_for_data( m_bitmapBuffer, GAL_FORMAT, m_wxBufferWidth,
m_bitmapSize.y, m_stride );
m_screenSize.y, m_stride );
m_context = cairo_create( m_surface );
@ -1597,18 +1596,17 @@ void CAIRO_GAL::deinitSurface()
void CAIRO_GAL::allocateBitmaps()
{
m_wxBufferWidth = m_bitmapSize.x;
m_wxBufferWidth = m_screenSize.x;
// Create buffer, use the system independent Cairo context backend
m_stride = cairo_format_stride_for_width( GAL_FORMAT, m_wxBufferWidth );
m_bufferSize = m_stride * m_bitmapSize.y;
m_bufferSize = m_stride * m_screenSize.y;
wxASSERT( m_bitmapBuffer == nullptr );
m_bitmapBuffer = new unsigned char[m_bufferSize];
wxASSERT( m_wxBitmap == nullptr );
m_wxBitmap = new wxBitmap( m_wxBufferWidth, m_bitmapSize.y, 24 );
m_wxBitmap->SetScaleFactor( getScalingFactor() );
wxASSERT( m_wxOutput == nullptr );
m_wxOutput = new unsigned char[m_wxBufferWidth * 3 * m_screenSize.y];
}
@ -1617,8 +1615,8 @@ void CAIRO_GAL::deleteBitmaps()
delete[] m_bitmapBuffer;
m_bitmapBuffer = nullptr;
delete m_wxBitmap;
m_wxBitmap = nullptr;
delete[] m_wxOutput;
m_wxOutput = nullptr;
}
@ -1626,7 +1624,7 @@ void CAIRO_GAL::setCompositor()
{
// Recreate the compositor with the new Cairo context
m_compositor.reset( new CAIRO_COMPOSITOR( &m_currentContext ) );
m_compositor->Resize( m_bitmapSize.x, m_bitmapSize.y );
m_compositor->Resize( m_screenSize.x, m_screenSize.y );
m_compositor->SetAntialiasingMode( m_options.cairo_antialiasing_mode );
// Prepare buffers
@ -1640,22 +1638,7 @@ void CAIRO_GAL::setCompositor()
void CAIRO_GAL::onPaint( wxPaintEvent& aEvent )
{
// We should have the rendered image in m_wxBitmap after EDA_DRAW_PANEL_GAL::onPaint
if( !m_wxBitmap )
{
wxLogDebug( "CAIRO_GAL::onPaint null output bitmap buffer" );
return;
}
{
// Now it is the time to blit the mouse cursor
wxMemoryDC mdc( *m_wxBitmap );
blitCursor( mdc );
}
wxPaintDC paintDC( this );
paintDC.DrawBitmap( *m_wxBitmap, 0, 0 );
PostPaint( aEvent );
}
@ -1699,12 +1682,6 @@ bool CAIRO_GAL::updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions )
}
double CAIRO_GAL::getScalingFactor()
{
return GetContentScaleFactor();
};
bool CAIRO_GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
{
// Store the current cursor type and get the wxCursor for it

View File

@ -2,7 +2,7 @@
* 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-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2018 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -252,9 +252,6 @@ protected:
const VECTOR2D xform( double x, double y ); // rotation, scale and offset
const VECTOR2D xform( const VECTOR2D& aP ); // rotation, scale and offset
// Return the scaling factor for current window.
virtual double getScalingFactor() { return 1.0; }
/**
* Transform according to the rotation from m_currentWorld2Screen transform matrix.
*
@ -455,8 +452,6 @@ public:
/// @copydoc GAL::EndDrawing()
void EndDrawing() override;
protected:
/// Prepare Cairo surfaces for drawing
void initSurface();
@ -504,9 +499,6 @@ protected:
///< Cairo-specific update handlers
bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
///< For HiDPI support
double getScalingFactor() override;
protected:
// Compositor related variables
std::shared_ptr<CAIRO_COMPOSITOR> m_compositor; ///< Object for layers compositing
@ -522,7 +514,7 @@ protected:
wxEvtHandler* m_mouseListener; ///< Mouse listener
wxEvtHandler* m_paintListener; ///< Paint listener
unsigned int m_bufferSize; ///< Size of buffers cairoOutput, bitmapBuffers
wxBitmap* m_wxBitmap; ///< Output buffer bitmap
unsigned char* m_wxOutput; ///< wxImage compatible buffer
// Variables related to Cairo <-> wxWidgets
unsigned char* m_bitmapBuffer; ///< Storage of the Cairo image

View File

@ -2,7 +2,7 @@
* 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) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* Graphics Abstraction Layer (GAL) - base class
*
@ -1060,8 +1060,8 @@ protected:
GAL_DISPLAY_OPTIONS& m_options;
UTIL::LINK m_observerLink;
std::stack<double> m_depthStack; ///< Stored depth values
VECTOR2I m_screenSize; ///< Screen size in screen (wx logical) coordinates
VECTOR2I m_bitmapSize; ///< Bitmap size, in physical pixels
double m_worldUnitLength; ///< The unit length of the world coordinates [inch]
double m_screenDPI; ///< The dots per inch of the screen