diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp
index db020ec9af..a9a749c661 100644
--- a/common/gal/opengl/opengl_gal.cpp
+++ b/common/gal/opengl/opengl_gal.cpp
@@ -1417,9 +1417,7 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet,
 
     if( aStrokeTriangulation )
     {
-        COLOR4D oldStrokeColor = m_strokeColor;
-        double  oldLayerDepth = m_layerDepth;
-
+        GAL_SCOPED_ATTRS( *this, GAL_SCOPED_ATTRS::STROKE_COLOR | GAL_SCOPED_ATTRS::LAYER_DEPTH );
         SetLayerDepth( m_layerDepth - 1 );
 
         for( unsigned int j = 0; j < aPolySet.TriangulatedPolyCount(); ++j )
@@ -1435,9 +1433,6 @@ void OPENGL_GAL::drawTriangulatedPolyset( const SHAPE_POLY_SET& aPolySet,
                 DrawLine( c, a );
             }
         }
-
-        SetStrokeColor( oldStrokeColor );
-        SetLayerDepth( oldLayerDepth );
     }
 }
 
diff --git a/common/preview_items/preview_utils.cpp b/common/preview_items/preview_utils.cpp
index ea2bbed1eb..e203be5c7a 100644
--- a/common/preview_items/preview_utils.cpp
+++ b/common/preview_items/preview_utils.cpp
@@ -122,7 +122,7 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView, const VECTOR2D& a
 {
     KIGFX::GAL*      gal = aView->GetGAL();
 
-    GAL_SCOPED_ATTRS settings( *gal );
+    GAL_SCOPED_ATTRS settings( *gal, GAL_SCOPED_ATTRS::STROKE_FILL );
 
     KIFONT::FONT*    font = KIFONT::FONT::GetFont();
 
diff --git a/common/preview_items/ruler_item.cpp b/common/preview_items/ruler_item.cpp
index 31e3bf9335..1ac150dba1 100644
--- a/common/preview_items/ruler_item.cpp
+++ b/common/preview_items/ruler_item.cpp
@@ -306,7 +306,7 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
     RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings();
     bool             drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
 
-    gal->PushDepth();
+    GAL_SCOPED_ATTRS scopedAttrs( *gal, GAL_SCOPED_ATTRS::ALL );
     gal->SetLayerDepth( gal->GetMinDepth() );
 
     VECTOR2D origin = m_geomMgr.GetOrigin();
@@ -368,7 +368,6 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
         // draw the back of the origin "crosshair"
         gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
     }
-    gal->PopDepth();
 }
 
 
diff --git a/common/tool/edit_points.cpp b/common/tool/edit_points.cpp
index 5f45057904..62c0c7e182 100644
--- a/common/tool/edit_points.cpp
+++ b/common/tool/edit_points.cpp
@@ -278,11 +278,11 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
         highlightColor = drawColor.Brightened( 0.5 ).WithAlpha( 0.8 );
     }
 
+    KIGFX::GAL_SCOPED_ATTRS scopedAttrs( *gal, KIGFX::GAL_SCOPED_ATTRS::ALL );
     gal->SetFillColor( drawColor );
     gal->SetStrokeColor( borderColor );
     gal->SetIsFill( true );
     gal->SetIsStroke( true );
-    gal->PushDepth();
     gal->SetLayerDepth( gal->GetMinDepth() );
 
     double size       = aView->ToWorld( EDIT_POINT::POINT_SIZE ) / 2.0;
@@ -328,6 +328,4 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
             gal->DrawLine( line.GetOrigin().GetPosition(), line.GetEnd().GetPosition() );
         }
     }
-
-    gal->PopDepth();
 }
diff --git a/common/view/view_group.cpp b/common/view/view_group.cpp
index aaeefb6fc0..9237468255 100644
--- a/common/view/view_group.cpp
+++ b/common/view/view_group.cpp
@@ -145,7 +145,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
 
     // Now draw the layers in sorted order
 
-    gal->PushDepth();
+    GAL_SCOPED_ATTRS scopedAttrs( *gal, GAL_SCOPED_ATTRS::LAYER_DEPTH );
 
     for( int i = 0; i < layers_count; i++ )
     {
@@ -188,8 +188,6 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
             }
         }
     }
-
-    gal->PopDepth();
 }
 
 
diff --git a/common/view/view_overlay.cpp b/common/view/view_overlay.cpp
index 1a6044fcc0..c996ea3542 100644
--- a/common/view/view_overlay.cpp
+++ b/common/view/view_overlay.cpp
@@ -298,14 +298,13 @@ const BOX2I VIEW_OVERLAY::ViewBBox() const
 
 void VIEW_OVERLAY::ViewDraw( int aLayer, VIEW* aView ) const
 {
-    auto gal = aView->GetGAL();
-    gal->PushDepth();
-    gal->SetLayerDepth( gal->GetMinDepth() );
+    GAL& gal = *aView->GetGAL();
+
+    GAL_SCOPED_ATTRS scopedAttrs( gal, GAL_SCOPED_ATTRS::LAYER_DEPTH );
+    gal.SetLayerDepth( gal.GetMinDepth() );
 
     for( const VIEW_OVERLAY::COMMAND* cmd : m_commands )
         cmd->Execute( aView );
-
-    gal->PopDepth();
 }
 
 
diff --git a/eeschema/sch_painter.cpp b/eeschema/sch_painter.cpp
index 8e40990edc..d1a2fbaa1f 100644
--- a/eeschema/sch_painter.cpp
+++ b/eeschema/sch_painter.cpp
@@ -2283,7 +2283,7 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
         VECTOR2I pt1 = bbox.GetOrigin();
         VECTOR2I pt2 = bbox.GetEnd();
 
-        m_gal->PushDepth();
+        GAL_SCOPED_ATTRS scopedAttrs( *m_gal, GAL_SCOPED_ATTRS::ALL );
         m_gal->AdvanceDepth();
         m_gal->SetIsStroke( true );
         m_gal->SetIsFill( true );
@@ -2293,7 +2293,6 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
         m_gal->DrawSegment( pt1, pt2, strokeWidth );
         std::swap( pt1.x, pt2.x );
         m_gal->DrawSegment( pt1, pt2, strokeWidth );
-        m_gal->PopDepth();
     }
 }
 
@@ -2758,8 +2757,7 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
         VECTOR2I pt1 = bbox.GetOrigin();
         VECTOR2I pt2 = bbox.GetEnd();
 
-        m_gal->PushDepth();
-        m_gal->AdvanceDepth();
+        GAL_SCOPED_ATTRS scopedAttrs( *m_gal, GAL_SCOPED_ATTRS::ALL );
         m_gal->SetIsStroke( true );
         m_gal->SetIsFill( true );
         m_gal->SetStrokeColor( m_schSettings.GetLayerColor( layer ) );
@@ -2768,7 +2766,6 @@ void SCH_PAINTER::draw( const SCH_SHEET* aSheet, int aLayer )
         m_gal->DrawSegment( pt1, pt2, strokeWidth );
         std::swap( pt1.x, pt2.x );
         m_gal->DrawSegment( pt1, pt2, strokeWidth );
-        m_gal->PopDepth();
     }
 }
 
diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h
index 6ad3127259..85b934c249 100644
--- a/include/gal/graphics_abstraction_layer.h
+++ b/include/gal/graphics_abstraction_layer.h
@@ -379,7 +379,10 @@ public:
     /**
      * Set the depth of the layer (position on the z-axis)
      *
-     * @param aLayerDepth the layer depth for the objects.
+     * If you do this, you should consider using a GAL_SCOPED_ATTR to ensure
+     * the depth is reset to the original value.
+     *
+     * @param aLayerDepth the layer depth for the objects. Smaller is closer to the viewer.
      */
     virtual void SetLayerDepth( double aLayerDepth )
     {
@@ -389,6 +392,18 @@ public:
         m_layerDepth = aLayerDepth;
     }
 
+    /**
+     * Change the current depth to deeper, so it is possible to draw objects right beneath
+     * other.
+     *
+     * If you do this, you should consider using a GAL_SCOPED_ATTR to ensure the depth
+     * is reset to the original value.
+     */
+    inline void AdvanceDepth()
+    {
+        SetLayerDepth( m_layerDepth - 0.1 );
+    }
+
     // ----
     // Text
     // ----
@@ -945,32 +960,6 @@ public:
      */
     virtual void DrawCursor( const VECTOR2D& aCursorPosition ) {};
 
-    /**
-     * Change the current depth to deeper, so it is possible to draw objects right beneath
-     * other.
-     */
-    inline void AdvanceDepth()
-    {
-        m_layerDepth -= 0.1;
-    }
-
-    /**
-     * Store current drawing depth on the depth stack.
-     */
-    inline void PushDepth()
-    {
-        m_depthStack.push( m_layerDepth );
-    }
-
-    /**
-     * Restore previously stored drawing depth for the depth stack.
-     */
-    inline void PopDepth()
-    {
-        m_layerDepth = m_depthStack.top();
-        m_depthStack.pop();
-    }
-
     virtual void EnableDepthTest( bool aEnabled = false ) {};
 
     /**
@@ -1057,7 +1046,6 @@ 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
 
@@ -1110,7 +1098,15 @@ protected:
     KICURSOR             m_currentNativeCursor; ///< Current cursor
 
 private:
+
+    inline double getLayerDepth() const
+    {
+        return m_layerDepth;
+    }
+
     TEXT_ATTRIBUTES      m_attributes;
+
+    friend class GAL_SCOPED_ATTRS;
 };
 
 
@@ -1180,26 +1176,28 @@ public:
         IS_STROKE = 4,
         FILL_COLOR = 8,
         IS_FILL = 16,
+        LAYER_DEPTH = 32,
 
         // It is not clear to me that GAL needs to save text attributes.
         // Only BitmapText uses it, and maybe that should be passed in
         // explicitly (like for Draw) - every caller of BitmapText sets
         // the text attributes anyway.
-        // TEXT_ATTRS = 32,
+        // TEXT_ATTRS = 64,
 
+        // Convenience flags
         STROKE = STROKE_WIDTH | STROKE_COLOR | IS_STROKE,
         FILL = FILL_COLOR | IS_FILL,
+        STROKE_FILL = STROKE | FILL,
 
-        ///< Convenience flag for setting both stroke and fill
-        ALL = STROKE | FILL,
+        ALL = STROKE | FILL | LAYER_DEPTH,
     };
 
     /**
      * Instantiates a GAL_SCOPED_ATTRS object, saving the current attributes of the GAL.
      *
-     * By default, all stroke and fill attributes are saved, which is usually what you want.
+     * Specify the flags to save/restore in aFlags.
      */
-    GAL_SCOPED_ATTRS( KIGFX::GAL& aGal, int aFlags = FLAGS::ALL )
+    GAL_SCOPED_ATTRS( KIGFX::GAL& aGal, int aFlags )
         : m_gal( aGal ), m_flags( aFlags )
     {
         // Save what we need to restore later.
@@ -1209,6 +1207,7 @@ public:
         m_isStroke = aGal.GetIsStroke();
         m_fillColor = aGal.GetFillColor();
         m_isFill = aGal.GetIsFill();
+        m_layerDepth = aGal.getLayerDepth();
     }
 
     ~GAL_SCOPED_ATTRS()
@@ -1227,6 +1226,9 @@ public:
             m_gal.SetFillColor( m_fillColor );
         if( m_flags & IS_FILL )
             m_gal.SetIsFill( m_isFill );
+
+        if( m_flags & LAYER_DEPTH )
+            m_gal.SetLayerDepth( m_layerDepth );
     }
 
 private:
@@ -1239,6 +1241,8 @@ private:
 
     COLOR4D m_fillColor;
     bool    m_isFill;
+
+    double m_layerDepth;
 };