From 55f7a99d1bab20b408c8595bb52df2af10c90cae Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 19 Apr 2013 18:19:50 +0200 Subject: [PATCH] Cairo now renders layers properly (colors are not saturated after layer composition), but slower. --- common/gal/cairo/cairo_gal.cpp | 27 +++++++++++++++++------- common/gal/opengl/opengl_gal.cpp | 9 ++++++++ common/view/view.cpp | 2 ++ include/gal/cairo/cairo_gal.h | 6 ++++++ include/gal/graphics_abstraction_layer.h | 6 ++++++ include/gal/opengl/opengl_gal.h | 6 ++++++ 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index ff0fb47b39..5d72954acb 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -612,6 +612,21 @@ void CAIRO_GAL::Restore() } +void CAIRO_GAL::BeginLayer() +{ + cairo_push_group( cairoImage ); +} + + +void CAIRO_GAL::EndLayer() +{ + storePath(); + + cairo_pop_group_to_source( cairoImage ); + cairo_paint_with_alpha( cairoImage, fillColor.a ); +} + + int CAIRO_GAL::BeginGroup() { // If the grouping is started: the actual path is stored in the group, when @@ -693,15 +708,13 @@ void CAIRO_GAL::DrawGroup( int aGroupNumber ) break; case CMD_STROKE_PATH: - cairo_set_source_rgba( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b, - strokeColor.a ); + cairo_set_source_rgb( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b ); cairo_append_path( cairoImage, it->cairoPath ); cairo_stroke( cairoImage ); break; case CMD_FILL_PATH: - cairo_set_source_rgba( cairoImage, fillColor.r, fillColor.g, fillColor.b, - fillColor.a ); + cairo_set_source_rgb( cairoImage, fillColor.r, fillColor.g, fillColor.b ); cairo_append_path( cairoImage, it->cairoPath ); cairo_fill( cairoImage ); break; @@ -779,15 +792,13 @@ void CAIRO_GAL::storePath() { if( isFillEnabled ) { - cairo_set_source_rgba( cairoImage, fillColor.r, fillColor.g, fillColor.b, - fillColor.a ); + cairo_set_source_rgb( cairoImage, fillColor.r, fillColor.g, fillColor.b ); cairo_fill_preserve( cairoImage ); } if( isStrokeEnabled ) { - cairo_set_source_rgba( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b, - strokeColor.a ); + cairo_set_source_rgb( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b ); cairo_stroke_preserve( cairoImage ); } } diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index e75b8265bd..6a23f844d4 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -1283,6 +1283,15 @@ void OPENGL_GAL::Restore() } +void OPENGL_GAL::BeginLayer() +{ +} + +void OPENGL_GAL::EndLayer() +{ +} + + // TODO Error handling int OPENGL_GAL::BeginGroup() { diff --git a/common/view/view.cpp b/common/view/view.cpp index d91036cd30..4fc6d92968 100644 --- a/common/view/view.cpp +++ b/common/view/view.cpp @@ -419,9 +419,11 @@ void VIEW::redrawRect( const BOX2I& aRect ) { drawItem drawFunc( this, l->id ); + m_gal->BeginLayer(); m_gal->SetLayerDepth( (double) l->renderingOrder ); l->items->Query( aRect, drawFunc ); l->isDirty = false; + m_gal->EndLayer(); totalItems += drawFunc.count; totalDrawTime += drawFunc.time; diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 06db9f1f28..36cae06c6e 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -95,6 +95,12 @@ public: /// @copydoc GAL::EndDrawing() virtual void EndDrawing(); + /// @copydoc GAL::BeginLayer() + virtual void BeginLayer(); + + /// @copydoc GAL::EndLayer() + virtual void EndLayer(); + /// @copydoc GAL::DrawLine() virtual void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 245508b7a2..1940b047ab 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -95,6 +95,12 @@ public: /// @brief End the drawing, needs to be called for every new frame. virtual void EndDrawing() = 0; + /// @brief Begin the layer drawing, needs to be called for every new layer. + virtual void BeginLayer() = 0; + + /// @brief Finish the layer drawing, needs to be called for every new layer. + virtual void EndLayer() = 0; + /** * @brief Draw a line. * diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index ce4ff73c39..d01028112b 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -102,6 +102,12 @@ public: /// @copydoc GAL::EndDrawing() virtual void EndDrawing(); + /// @copydoc GAL::BeginLayer() + virtual void BeginLayer(); + + /// @copydoc GAL::EndLayer() + virtual void EndLayer(); + /// @copydoc GAL::DrawLine() virtual void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );