Author: Carlos Lopez <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl