Author: Carlos Lopez <[email protected]>
Date: Sun Sep 16 20:57:45 2012 +0200
Blur_Layer: add support for Cairo render. Gaussian blur doesn't work yet. Some
changes are needed in etl::gaussian
---
synfig-core/src/modules/mod_filter/blur.cpp | 127 +++++++++++++++++++++++++++
synfig-core/src/modules/mod_filter/blur.h | 5 +-
2 files changed, 130 insertions(+), 2 deletions(-)
diff --git a/synfig-core/src/modules/mod_filter/blur.cpp
b/synfig-core/src/modules/mod_filter/blur.cpp
index 35ee6f7..f9f92c8 100644
--- a/synfig-core/src/modules/mod_filter/blur.cpp
+++ b/synfig-core/src/modules/mod_filter/blur.cpp
@@ -236,6 +236,133 @@ Blur_Layer::accelerated_render(Context context,Surface
*surface,int quality, con
return true;
}
+/////
+bool
+Blur_Layer::accelerated_cairorender(Context context,cairo_surface_t
*surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
+{
+ // don't do anything at quality 10
+ if (quality == 10)
+ return
context.accelerated_cairorender(surface,quality,renddesc,cb);
+
+ // int x,y;
+ SuperCallback stageone(cb,0,5000,10000);
+ SuperCallback stagetwo(cb,5000,10000,10000);
+
+ const int w = renddesc.get_w(), h = renddesc.get_h();
+ const Real pw = renddesc.get_pw(), ph = renddesc.get_ph();
+
+ const Point tl(renddesc.get_tl());
+ const Point br(renddesc.get_br());
+
+ RendDesc workdesc(renddesc);
+ cairo_surface_t *worksurface, *blurred;
+
+ //callbacks depend on how long the blur takes
+ if(size[0] || size[1])
+ {
+ if(type == Blur::DISC)
+ {
+ stageone = SuperCallback(cb,0,5000,10000);
+ stagetwo = SuperCallback(cb,5000,10000,10000);
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9000,10000);
+ stagetwo = SuperCallback(cb,9000,10000,10000);
+ }
+ }
+ else
+ {
+ stageone = SuperCallback(cb,0,9999,10000);
+ stagetwo = SuperCallback(cb,9999,10000,10000);
+ }
+
+ //expand the working surface to accommodate the blur
+
+ //the expanded size = 1/2 the size in each direction rounded up
+ int halfsizex = (int) (abs(size[0]*.5/pw) + 3),
+ halfsizey = (int) (abs(size[1]*.5/ph) + 3);
+
+ //expand by 1/2 size in each direction on either side
+ switch(type)
+ {
+ case Blur::DISC:
+ case Blur::BOX:
+ case Blur::CROSS:
+ {
+
workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::FASTGAUSSIAN:
+ {
+ if(quality < 4)
+ {
+ halfsizex*=2;
+ halfsizey*=2;
+ }
+
workdesc.set_subwindow(-max(1,halfsizex),-max(1,halfsizey),w+2*max(1,halfsizex),h+2*max(1,halfsizey));
+ break;
+ }
+ case Blur::GAUSSIAN:
+ {
+#define GAUSSIAN_ADJUSTMENT (0.05)
+ Real pw =
(Real)workdesc.get_w()/(workdesc.get_br()[0]-workdesc.get_tl()[0]);
+ Real ph =
(Real)workdesc.get_h()/(workdesc.get_br()[1]-workdesc.get_tl()[1]);
+
+ pw=pw*pw;
+ ph=ph*ph;
+
+ halfsizex =
(int)(abs(pw)*size[0]*GAUSSIAN_ADJUSTMENT+0.5);
+ halfsizey =
(int)(abs(ph)*size[1]*GAUSSIAN_ADJUSTMENT+0.5);
+
+ halfsizex = (halfsizex + 1)/2;
+ halfsizey = (halfsizey + 1)/2;
+ workdesc.set_subwindow( -halfsizex, -halfsizey,
w+2*halfsizex, h+2*halfsizey );
+#undef GAUSSIAN_ADJUSTMENT
+ break;
+ }
+ }
+
+ worksurface=cairo_surface_create_similar(surface,
CAIRO_CONTENT_COLOR_ALPHA, workdesc.get_w(), workdesc.get_h());
+ //render the background onto the expanded surface
+
if(!context.accelerated_cairorender(worksurface,quality,workdesc,&stageone))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Cairo
Renderer Failure",__LINE__));
+ cairo_surface_destroy(worksurface);
+ return false;
+ }
+ blurred=cairo_surface_create_similar(surface,
CAIRO_CONTENT_COLOR_ALPHA, workdesc.get_w(), workdesc.get_h());
+
+ //blur the image
+
Blur(size,type,&stagetwo)(worksurface,workdesc.get_br()-workdesc.get_tl(),blurred);
+
+ cairo_t *cr=cairo_create(surface);
+ cairo_save(cr);
+ cairo_set_source_surface(cr, worksurface, -halfsizex, -halfsizey);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint(cr);
+ cairo_restore(cr);
+
+ cairo_save(cr);
+ cairo_set_source_surface(cr, blurred, -halfsizex, -halfsizey);
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); // TODO this has to be
the real operator
+ cairo_paint_with_alpha(cr, get_amount());
+ cairo_restore(cr);
+
+ if(cb && !cb->amount_complete(10000,10000))
+ {
+ if(cb)cb->error(strprintf(__FILE__"%d: Accelerated Renderer
Failure",__LINE__));
+ return false;
+ }
+ cairo_surface_destroy(blurred);
+ cairo_surface_destroy(worksurface);
+ cairo_destroy(cr);
+ return true;
+
+}
+
+/////
+
Layer::Vocab
Blur_Layer::get_param_vocab(void)const
{
diff --git a/synfig-core/src/modules/mod_filter/blur.h
b/synfig-core/src/modules/mod_filter/blur.h
index cfe8a2f..48e941a 100644
--- a/synfig-core/src/modules/mod_filter/blur.h
+++ b/synfig-core/src/modules/mod_filter/blur.h
@@ -37,7 +37,7 @@ using namespace synfig;
using namespace std;
using namespace etl;
-class Blur_Layer : public synfig::Layer_Composite
+class Blur_Layer : public Layer_Composite
{
SYNFIG_LAYER_MODULE_EXT
private:
@@ -47,13 +47,14 @@ private:
public:
Blur_Layer();
- virtual bool set_param(const String & param, const synfig::ValueBase
&value);
+ virtual bool set_param(const String & param, const ValueBase &value);
virtual ValueBase get_param(const String & param)const;
virtual Color get_color(Context context, const Point &pos)const;
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;
virtual synfig::Rect get_full_bounding_rect(Context context)const;
virtual Vocab get_param_vocab()const;
------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://ad.doubleclick.net/clk;258768047;13503038;j?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl