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