X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Ftarget_scanline.cpp;h=b4745fed127eb3dd7ae9d827aac12812254d4764;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=5c33cf3cd383745d4d0efa751e06381a51f8ced9;hpb=28f28705612902c15cd0702cc891fba35bf2d2df;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/target_scanline.cpp b/synfig-core/trunk/src/synfig/target_scanline.cpp index 5c33cf3..b4745fe 100644 --- a/synfig-core/trunk/src/synfig/target_scanline.cpp +++ b/synfig-core/trunk/src/synfig/target_scanline.cpp @@ -2,19 +2,21 @@ /*! \file target_scanline.cpp ** \brief Template File ** -** $Id: target_scanline.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $ +** $Id$ ** ** \legal -** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2008 Chris Moore ** -** This software and associated documentation -** are CONFIDENTIAL and PROPRIETARY property of -** the above-mentioned copyright holder. +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. ** -** You may not copy, print, publish, or in any -** other way distribute this software without -** a prior written agreement with -** the copyright holder. +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. ** \endlegal */ /* ========================================================================= */ @@ -45,11 +47,17 @@ using namespace synfig; /* === M A C R O S ========================================================= */ -#define SYNFIG_OPTIMIZE_LAYER_TREE 1 +// note that if this isn't defined then the rendering is incorrect for +// the straight blend method since the optimize_layers() function in +// canvas.cpp which makes the straight blend method work correctly +// isn't called. ie. leave this defined. to see the problem, draw a +// small circle over a solid background. set circle to amount 0.99 +// and blend method 'straight'. the background should vanish but doesn't +#define SYNFIG_OPTIMIZE_LAYER_TREE #define PIXEL_RENDERING_LIMIT 1500000 -#define USE_PIXELRENDERING_LIMIT 0 +#define USE_PIXELRENDERING_LIMIT 1 /* === G L O B A L S ======================================================= */ @@ -84,11 +92,11 @@ Target_Scanline::next_frame(Time& time) frame_end=desc.get_frame_end(); time_start=desc.get_time_start(); time_end=desc.get_time_end(); - + // Calculate the number of frames total_frames=frame_end-frame_start; if(total_frames<=0)total_frames=1; - + //RendDesc rend_desc=desc; //rend_desc.set_gamma(1); @@ -123,8 +131,11 @@ synfig::Target_Scanline::render(ProgressCallback *cb) assert(canvas); curr_frame_=0; - init(); - + if( !init() ){ + if(cb) cb->error(_("Target initialization failure")); + return false; + } + // If the description's end frame is equal to // the start frame, then it is assumed that we // are rendering only one frame. Correct it. @@ -135,22 +146,22 @@ synfig::Target_Scanline::render(ProgressCallback *cb) frame_end=desc.get_frame_end(); time_start=desc.get_time_start(); time_end=desc.get_time_end(); - + // Calculate the number of frames total_frames=frame_end-frame_start; - - + + //RendDesc rend_desc=desc; - + try { // Grab the time int i=next_frame(t); - + //synfig::info("1time_set_to %s",t.get_string().c_str()); - + if(i>1) do{ - + //if(total_frames>1) //for(i=0,t=time_start;iamount_complete(total_frames-(i-1),total_frames)) return false; - + // Set the time that we wish to render if(!get_avoid_time_sync() || canvas->get_time()!=t) canvas->set_time(t); - + Context context; - - #ifdef SYNFIG_OPTIMIZE_LAYER_TREE - Canvas::Handle op_canvas(Canvas::create()); - optimize_layers(canvas->get_context(), op_canvas); - context=op_canvas->get_context(); - #else + +#ifdef SYNFIG_OPTIMIZE_LAYER_TREE + Canvas::Handle op_canvas; + if (!getenv("SYNFIG_DISABLE_OPTIMIZE_LAYER_TREE")) + { + op_canvas = Canvas::create(); + op_canvas->set_file_name(canvas->get_file_name()); + optimize_layers(canvas->get_time(), canvas->get_context(), op_canvas); + context=op_canvas->get_context(); + } + else + context=canvas->get_context(); +#else context=canvas->get_context(); - #endif - +#endif + // If the quality is set to zero, then we // use the parametric scanline-renderer. if(quality==0) @@ -194,31 +212,31 @@ synfig::Target_Scanline::render(ProgressCallback *cb) { #if USE_PIXELRENDERING_LIMIT if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT) - { - synfig::info("Render BROKEN UP! (%d pixels)", desc.get_w()*desc.get_h()); - - Surface surface; + { + Surface surface; int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w(); + if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit? int rows = desc.get_h()/rowheight; int lastrowheight = desc.get_h() - rows*rowheight; - + rows++; - - synfig::info("\t blockh=%d,remh=%d,totrows=%d", rowheight,lastrowheight,rows); - + + synfig::info("Render broken up into %d block%s %d pixels tall, and a final block %d pixels tall", + rows-1, rows==2?"":"s", rowheight, lastrowheight); + // loop through all the full rows if(!start_frame()) { throw(string("add_frame(): target panic on start_frame()")); return false; } - + for(int i=0; i < rows; ++i) { RendDesc blockrd = desc; - + //render the strip at the normal size unless it's the last one... - if(i == rows) + if(i == rows-1) { if(!lastrowheight) break; blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight); @@ -227,7 +245,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) { blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight); } - + if(!context.accelerated_render(&surface,quality,blockrd,0)) { if(cb)cb->error(_("Accelerated Renderer Failure")); @@ -237,9 +255,9 @@ synfig::Target_Scanline::render(ProgressCallback *cb) int y; int rowspan=sizeof(Color)*surface.get_w(); Surface::pen pen = surface.begin(); - + int yoff = i*rowheight; - + for(y = 0; y < blockrd.get_h(); y++, pen.inc_y()) { Color *colordata= start_scanline(y + yoff); @@ -248,7 +266,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) throw(string("add_frame(): call to start_scanline(y) returned NULL")); return false; } - + if(get_remove_alpha()) { for(int i = 0; i < surface.get_w(); i++) @@ -256,7 +274,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) } else memcpy(colordata,surface[y],rowspan); - + if(!end_scanline()) { throw(string("add_frame(): target panic on end_scanline()")); @@ -264,15 +282,15 @@ synfig::Target_Scanline::render(ProgressCallback *cb) } } } - } + } + + end_frame(); - end_frame(); - }else //use normal rendering... { #endif Surface surface; - + if(!context.accelerated_render(&surface,quality,desc,0)) { // For some reason, the accelerated renderer failed. @@ -300,15 +318,22 @@ synfig::Target_Scanline::render(ProgressCallback *cb) if(!get_avoid_time_sync() || canvas->get_time()!=t) canvas->set_time(t); Context context; - - #ifdef SYNFIG_OPTIMIZE_LAYER_TREE - Canvas::Handle op_canvas(Canvas::create()); - optimize_layers(canvas->get_context(), op_canvas); - context=op_canvas->get_context(); - #else + +#ifdef SYNFIG_OPTIMIZE_LAYER_TREE + Canvas::Handle op_canvas; + if (!getenv("SYNFIG_DISABLE_OPTIMIZE_LAYER_TREE")) + { + op_canvas = Canvas::create(); + op_canvas->set_file_name(canvas->get_file_name()); + optimize_layers(canvas->get_time(), canvas->get_context(), op_canvas); + context=op_canvas->get_context(); + } + else + context=canvas->get_context(); +#else context=canvas->get_context(); - #endif - +#endif + // If the quality is set to zero, then we // use the parametric scanline-renderer. if(quality==0) @@ -329,31 +354,31 @@ synfig::Target_Scanline::render(ProgressCallback *cb) #if USE_PIXELRENDERING_LIMIT if(desc.get_w()*desc.get_h() > PIXEL_RENDERING_LIMIT) { - synfig::info("Render BROKEN UP! (%d pixels)", desc.get_w()*desc.get_h()); - - Surface surface; - int totalheight = desc.get_h(); + Surface surface; + int totalheight = desc.get_h(); int rowheight = PIXEL_RENDERING_LIMIT/desc.get_w(); + if (!rowheight) rowheight = 1; // TODO: render partial lines to stay within the limit? int rows = desc.get_h()/rowheight; int lastrowheight = desc.get_h() - rows*rowheight; - + rows++; - - synfig::info("\t blockh=%d,remh=%d,totrows=%d", rowheight,lastrowheight,rows); - + + synfig::info("Render broken up into %d block%s %d pixels tall, and a final block %d pixels tall", + rows-1, rows==2?"":"s", rowheight, lastrowheight); + // loop through all the full rows if(!start_frame()) { throw(string("add_frame(): target panic on start_frame()")); return false; } - + for(int i=0; i < rows; ++i) { RendDesc blockrd = desc; - + //render the strip at the normal size unless it's the last one... - if(i == rows) + if(i == rows-1) { if(!lastrowheight) break; blockrd.set_subwindow(0,i*rowheight,desc.get_w(),lastrowheight); @@ -362,9 +387,9 @@ synfig::Target_Scanline::render(ProgressCallback *cb) { blockrd.set_subwindow(0,i*rowheight,desc.get_w(),rowheight); } - + SuperCallback sc(cb, i*rowheight, (i+1)*rowheight, totalheight); - + if(!context.accelerated_render(&surface,quality,blockrd,&sc)) { if(cb)cb->error(_("Accelerated Renderer Failure")); @@ -374,9 +399,9 @@ synfig::Target_Scanline::render(ProgressCallback *cb) int y; int rowspan=sizeof(Color)*surface.get_w(); Surface::pen pen = surface.begin(); - + int yoff = i*rowheight; - + for(y = 0; y < blockrd.get_h(); y++, pen.inc_y()) { Color *colordata= start_scanline(y + yoff); @@ -385,7 +410,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) throw(string("add_frame(): call to start_scanline(y) returned NULL")); return false; } - + if(get_remove_alpha()) { for(int i = 0; i < surface.get_w(); i++) @@ -393,7 +418,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) } else memcpy(colordata,surface[y],rowspan); - + if(!end_scanline()) { throw(string("add_frame(): target panic on end_scanline()")); @@ -401,18 +426,18 @@ synfig::Target_Scanline::render(ProgressCallback *cb) } } } - + //I'm done with this part sc.amount_complete(100,100); - } + } + + end_frame(); - end_frame(); - }else { - #endif + #endif Surface surface; - + if(!context.accelerated_render(&surface,quality,desc,cb)) { if(cb)cb->error(_("Accelerated Renderer Failure")); @@ -433,7 +458,7 @@ synfig::Target_Scanline::render(ProgressCallback *cb) #endif } } - + } catch(String str) { @@ -462,13 +487,13 @@ Target_Scanline::add_frame(const Surface *surface) int y; int rowspan=sizeof(Color)*surface->get_w(); Surface::const_pen pen=surface->begin(); - + if(!start_frame()) { throw(string("add_frame(): target panic on start_frame()")); return false; } - + for(y=0;yget_h();y++,pen.inc_y()) { Color *colordata= start_scanline(y); @@ -477,7 +502,7 @@ Target_Scanline::add_frame(const Surface *surface) throw(string("add_frame(): call to start_scanline(y) returned NULL")); return false; } - + if(get_remove_alpha()) { for(int i=0;iget_w();i++) @@ -485,15 +510,15 @@ Target_Scanline::add_frame(const Surface *surface) } else memcpy(colordata,(*surface)[y],rowspan); - + if(!end_scanline()) { throw(string("add_frame(): target panic on end_scanline()")); return false; } } - + end_frame(); - + return true; }