diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp
index 2796cef8f9..1e8d154146 100644
--- a/common/draw_panel_gal.cpp
+++ b/common/draw_panel_gal.cpp
@@ -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
diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp
index cd6f8f3d80..dfef4ee1e6 100644
--- a/common/gal/cairo/cairo_gal.cpp
+++ b/common/gal/cairo/cairo_gal.cpp
@@ -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
diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h
index 1736d8af42..2e2438605e 100644
--- a/include/gal/cairo/cairo_gal.h
+++ b/include/gal/cairo/cairo_gal.h
@@ -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
diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h
index c4d1cb36c8..8b92fa7fcd 100644
--- a/include/gal/graphics_abstraction_layer.h
+++ b/include/gal/graphics_abstraction_layer.h
@@ -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