Author: Carlos Lopez <genet...@gmail.com>
Date:   Wed Jul 18 20:13:47 2012 +0200

Support for Layer_Composite::accelereated_cairorender.  Move to private the 
Layer_Bitmap's cairo_surface_t* and provide get and set members. On 
cairorender, use get_cairocolor instead of get_color.

---

 synfig-core/src/synfig/layer_bitmap.cpp    |   46 ++++++++++++++++++----
 synfig-core/src/synfig/layer_bitmap.h      |    5 ++-
 synfig-core/src/synfig/layer_composite.cpp |   59 ++++++++++++++++++++++++++++
 synfig-core/src/synfig/layer_composite.h   |    3 +
 synfig-core/src/synfig/render.cpp          |   24 ++---------
 5 files changed, 108 insertions(+), 29 deletions(-)

diff --git a/synfig-core/src/synfig/layer_bitmap.cpp 
b/synfig-core/src/synfig/layer_bitmap.cpp
index f578f09..9af2b35 100644
--- a/synfig-core/src/synfig/layer_bitmap.cpp
+++ b/synfig-core/src/synfig/layer_bitmap.cpp
@@ -117,7 +117,7 @@ synfig::Layer_Bitmap::get_param(const String & param)const
                                break;
                                case CAIRO:
                                default:
-                               
ret2=int(cairo_image_surface_get_width(cairosurface));
+                               ret2=int(cairo_image_surface_get_width(cs_));
                                break;
                }
                ret1.set_static(get_param_static(param));
@@ -137,7 +137,7 @@ synfig::Layer_Bitmap::get_param(const String & param)const
                                break;
                        case CAIRO:
                        default:
-                               
ret2=int(cairo_image_surface_get_height(cairosurface));
+                               ret2=int(cairo_image_surface_get_height(cs_));
                                break;
                }
                ret1.set_static(get_param_static(param));
@@ -310,7 +310,7 @@ synfig::Layer_Bitmap::get_color(Context context, const 
Point &pos)const
 CairoColor
 synfig::Layer_Bitmap::get_cairocolor(Context context, const Point &pos)const
 {
-       CairoSurface c_surface(cairosurface);
+       CairoSurface c_surface(cs_); // TODO: don't map/unmap everytime! It is 
very time consuming!
        c_surface.map_cairo_image();
 
        Point surface_pos;
@@ -666,7 +666,7 @@ Layer_Bitmap::accelerated_cairorender(Context context, 
cairo_surface_t *out_surf
                interp=1;
        
        //if we don't actually have a valid surface just skip us
-       if(cairo_surface_status(cairosurface) && 
cairo_surface_get_type(cairosurface)!=CAIRO_SURFACE_TYPE_IMAGE)
+       if(cairo_surface_status(cs_) && 
cairo_surface_get_type(cs_)!=CAIRO_SURFACE_TYPE_IMAGE)
        {
                // Render what is behind us
                return 
context.accelerated_cairorender(out_surface,quality,renddesc,cb);
@@ -680,8 +680,8 @@ Layer_Bitmap::accelerated_cairorender(Context context, 
cairo_surface_t *out_surf
        int             outw = renddesc.get_w();
        int             outh = renddesc.get_h();
 
-       int             inw = cairo_image_surface_get_width(cairosurface);
-       int             inh = cairo_image_surface_get_height(cairosurface);
+       int             inw = cairo_image_surface_get_width(cs_);
+       int             inh = cairo_image_surface_get_height(cs_);
        
        
        if(     get_amount()==1 && // our bitmap is full opaque
@@ -696,7 +696,7 @@ Layer_Bitmap::accelerated_cairorender(Context context, 
cairo_surface_t *out_surf
                        {
                                cairo_t* cr=cairo_create(out_surface); // 
create a cairo context with the out surface
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 
// set operator to ignore destiny
-                               cairo_set_source_surface(cr, cairosurface, 0, 
0); // set the source our cairosurface 
+                               cairo_set_source_surface(cr, cs_, 0, 0); // set 
the source our cairosurface 
                                cairo_paint(cr); // paint on the destiny
                                cairo_destroy(cr); // finaly destroy the cairo 
context pointer
                        }
@@ -742,7 +742,7 @@ Layer_Bitmap::accelerated_cairorender(Context context, 
cairo_surface_t *out_surf
        }
        // TODO: filter the image with gamma_adjust!!
        cairo_t* cr=cairo_create(out_surface); // create a cairo context with 
the out surface
-       cairo_set_source_surface(cr, cairosurface, 0,0);
+       cairo_set_source_surface(cr, cs_, 0,0);
        cairo_pattern_set_filter(cairo_get_source(cr), filter);
        
        cairo_set_operator(cr, CAIRO_OPERATOR_OVER); // TODO: this has to be a 
custom operator
@@ -763,3 +763,33 @@ Layer_Bitmap::get_bounding_rect()const
 {
        return Rect(tl,br);
 }
+
+
+void 
+Layer_Bitmap::set_cairo_surface(cairo_surface_t *cs)
+{
+       if(cs==NULL)
+       {
+               synfig::error("Layer_Bitmap received a NULL cairo_surface_t");
+               return;
+       }
+       if(cairo_surface_status(cs))
+       {
+               synfig::error("Layer_Bitmap received a non valid 
cairo_surface_t");
+               return;
+       }
+       else
+       {
+               if(cs_!=NULL)
+                       cairo_surface_destroy(cs_);
+               cs_=cairo_surface_reference(cs);
+       }
+}
+
+cairo_surface_t* 
+Layer_Bitmap::get_cairo_surface()const
+{
+       assert(cs_);
+       return cairo_surface_reference(cs_);
+}
+
diff --git a/synfig-core/src/synfig/layer_bitmap.h 
b/synfig-core/src/synfig/layer_bitmap.h
index a957fc9..cd75d7d 100644
--- a/synfig-core/src/synfig/layer_bitmap.h
+++ b/synfig-core/src/synfig/layer_bitmap.h
@@ -47,6 +47,7 @@ class Layer_Bitmap : public Layer_Composite, public 
Layer_NoDeform
        const Color& filter(Color& c)const;
        const CairoColor& filter(CairoColor& c)const;
        RenderMethod method;
+       mutable cairo_surface_t* cs_;
 public:
        typedef etl::handle<Layer_Bitmap> Handle;
 
@@ -54,7 +55,6 @@ public:
        Point br;
        int c;
        mutable Surface surface;
-       mutable cairo_surface_t* cairosurface;
        mutable bool trimmed;
        mutable unsigned int width, height, top, left;
 
@@ -81,6 +81,9 @@ public:
        virtual void set_render_method(Context context, RenderMethod x);
        void set_method(RenderMethod x) { method=x;}
        RenderMethod get_method()const { return method;}
+       
+       void set_cairo_surface(cairo_surface_t* cs);
+       cairo_surface_t* get_cairo_surface()const;
 
 }; // END of class Layer_Bitmap
 
diff --git a/synfig-core/src/synfig/layer_composite.cpp 
b/synfig-core/src/synfig/layer_composite.cpp
index 5644689..d5281f1 100644
--- a/synfig-core/src/synfig/layer_composite.cpp
+++ b/synfig-core/src/synfig/layer_composite.cpp
@@ -138,6 +138,65 @@ Layer_Composite::accelerated_render(Context 
context,Surface *surface,int quality
        //return 
render_threaded(Context(image.begin()),target,desc,&stagetwo,2);
 }
 
+/////
+
+bool
+Layer_Composite::accelerated_cairorender(Context context,cairo_surface_t 
*surface,int quality, const RendDesc &renddesc_, ProgressCallback *cb)  const
+{
+       RendDesc renddesc(renddesc_);
+       
+       if(!amount)
+               return 
context.accelerated_cairorender(surface,quality,renddesc,cb);
+       
+       CanvasBase image;
+       
+       SuperCallback stageone(cb,0,50000,100000);
+       SuperCallback stagetwo(cb,50000,100000,100000);
+       
+       Layer_Bitmap::Handle surfacelayer(new class Layer_Bitmap());
+       
+       Context iter;
+       
+       for(iter=context;*iter;iter++)
+               image.push_back(*iter);
+       
+       // Add one Bitmap Layer on top
+       image.push_front(surfacelayer.get());
+               
+       image.push_back(0);     // and Alpha black at end
+       
+       // Render the backdrop on the surface layer's surface.
+       cairo_surface_t* cs=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
renddesc.get_w(), renddesc.get_h());
+       if(!context.accelerated_cairorender(cs,quality,renddesc,&stageone))
+       {
+               cairo_surface_destroy(cs);
+               return false;
+       }
+       surfacelayer->set_cairo_surface(cs);
+       cairo_surface_destroy(cs);
+       // Sets up the interpolation of the context (now the surface layer is 
the first one)
+       // depending on the quality
+       if(quality<=4)surfacelayer->c=3;else
+               if(quality<=5)surfacelayer->c=2;
+               else if(quality<=6)surfacelayer->c=1;
+               else surfacelayer->c=0;
+       surfacelayer->tl=renddesc.get_tl();
+       surfacelayer->br=renddesc.get_br();
+       // Sets the blend method to straight. See below
+       surfacelayer->set_blend_method(Color::BLEND_STRAIGHT);
+       // Push this layer on the image. The blending result is only this layer
+       // and the surface layer. The rest of the context is ignored by the 
straight
+       // blend method of surface layer
+       image.push_front(const_cast<synfig::Layer_Composite*>(this));           
+
+       // Render the scene
+       return cairorender(Context(image.begin()),surface,renddesc,&stagetwo);
+}
+
+
+
+/////
+
 Rect
 Layer_Composite::get_full_bounding_rect(Context context)const
 {
diff --git a/synfig-core/src/synfig/layer_composite.h 
b/synfig-core/src/synfig/layer_composite.h
index 46a07b6..d381701 100644
--- a/synfig-core/src/synfig/layer_composite.h
+++ b/synfig-core/src/synfig/layer_composite.h
@@ -30,6 +30,8 @@
 
 #include "layer.h"
 #include "color.h"
+#include "cairo.h"
+#include "cairomm/cairomm.h"
 
 /* === M A C R O S ========================================================= */
 
@@ -89,6 +91,7 @@ public:
        virtual Rect get_full_bounding_rect(Context context)const;
        //! Renders the layer composited on the context and puts it on the 
target surface.
        virtual bool accelerated_render(Context context,Surface *surface,int 
quality, const RendDesc &renddesc, ProgressCallback *cb)const;
+       virtual bool accelerated_cairorender(Context context,cairo_surface_t 
*surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const;
 }; // END of class Layer_Composite
 
 }; // END of namespace synfig
diff --git a/synfig-core/src/synfig/render.cpp 
b/synfig-core/src/synfig/render.cpp
index 9678512..952147e 100644
--- a/synfig-core/src/synfig/render.cpp
+++ b/synfig-core/src/synfig/render.cpp
@@ -395,36 +395,20 @@ synfig::cairorender(
                        for(y2=0,pool=0;y2<a;y2++)
                                for(x2=0;x2<a;x2++)
                                {
-                                       // Notice that we will use Color 
instead of CairoColor
-                                       // because get_color for layers are at 
the moment defined for Color
-                                       // So I need to convert Color to 
CairoColor before place it on the 
-                                       // CairoSurface of target.
-                                       // Later, when all layers have its own 
get_cairocolor, I'll change this.
-                                       // It is mandatory to have 
get_cairocolor enabled for LayerBitmap
-                                       // because it uses cairosurface to get 
the (subsampled) color
-                                       Color color=context.get_color(
+                                       CairoColor color=context.get_cairocolor(
                                                                                
                  Point(
                                                                                
                                u+(Point::value_type)(x2)*dsu,
                                                                                
                                v+(Point::value_type)(y2)*dsv
                                                                                
                                )
                                                                                
                  );
-                                       if(!no_clamp)
-                                       {
-                                               color=color.clamped();
-                                               c+=color*color.get_a();
-                                               pool+=color.get_a();
-                                       }
-                                       else
-                                       {
-                                               c+=color*color.get_a();
-                                               pool+=color.get_a();
-                                       }
+                                       c+=color*color.get_a();
+                                       pool+=color.get_a();
                                }
                        if(pool)
                                c/=pool;
                        // Once the pixel is subsampled then I premultiply by 
alpha and pass
                        // it to the CairoSurface
-                       csurface[y][x]=CairoColor(c).premult_alpha();
+                       csurface[y][x]=c.premult_alpha();
                }
        }
        // unmap the rendered surface to the cairo_surface_t


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Synfig-devl mailing list
Synfig-devl@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to