1 /* === S Y N F I G ========================================================= */
2 /*! \file target_tile.cpp
3 ** \brief Template File
5 ** $Id: target_tile.cpp,v 1.2 2005/01/12 06:46:45 darco Exp $
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
10 ** This package is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License as
12 ** published by the Free Software Foundation; either version 2 of
13 ** the License, or (at your option) any later version.
15 ** This package is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** General Public License for more details.
21 /* ========================================================================= */
23 /* === H E A D E R S ======================================================= */
32 #include "target_tile.h"
43 /* === U S I N G =========================================================== */
47 using namespace synfig;
49 /* === M A C R O S ========================================================= */
50 const unsigned int DEF_TILE_WIDTH = 64;
51 const unsigned int DEF_TILE_HEIGHT= 64;
53 #define SYNFIG_OPTIMIZE_LAYER_TREE 1
55 #define SYNFIG_DISPLAY_EFFICIENCY 1
58 /* === G L O B A L S ======================================================= */
60 /* === P R O C E D U R E S ================================================= */
62 /* === M E T H O D S ======================================================= */
64 Target_Tile::Target_Tile():
66 tile_w_(DEF_TILE_WIDTH),
67 tile_h_(DEF_TILE_HEIGHT),
75 Target_Tile::next_frame(Time& time)
85 // If the description's end frame is equal to
86 // the start frame, then it is assumed that we
87 // are rendering only one frame. Correct it.
88 if(desc.get_frame_end()==desc.get_frame_start())
89 desc.set_frame_end(desc.get_frame_start()+1);
91 frame_start=desc.get_frame_start();
92 frame_end=desc.get_frame_end();
93 time_start=desc.get_time_start();
94 time_end=desc.get_time_end();
96 // Calculate the number of frames
97 total_frames=frame_end-frame_start;
98 if(total_frames<=0)total_frames=1;
100 //RendDesc rend_desc=desc;
101 //rend_desc.set_gamma(1);
103 // int total_tiles(total_tiles());
104 time=(time_end-time_start)*curr_frame_/total_frames+time_start;
107 /* synfig::info("curr_frame_: %d",curr_frame_);
108 synfig::info("total_frames: %d",total_frames);
109 synfig::info("time_end: %s",time_end.get_string().c_str());
110 synfig::info("time_start: %s",time_start.get_string().c_str());
112 // synfig::info("time: %s",time.get_string().c_str());
114 return total_frames- curr_frame_+1;
118 Target_Tile::next_tile(int& x, int& y)
120 // Width of the image(in tiles)
121 int tw(rend_desc().get_w()/tile_w_);
122 int th(rend_desc().get_h()/tile_h_);
124 // Add the last tiles (which will be clipped)
125 if(rend_desc().get_w()%tile_w_!=0)tw++;
126 if(rend_desc().get_h()%tile_h_!=0)th++;
128 x=(curr_tile_%tw)*tile_h_;
129 y=(curr_tile_/tw)*tile_w_;
132 return (tw*th)-curr_tile_+1;
136 synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
138 if(tile_w_<=0||tile_h_<=0)
140 if(cb)cb->error(_("Bad Tile Size"));
143 const RendDesc &rend_desc(desc);
144 #define total_tiles total_tiles()
146 etl::clock total_time;
147 etl::clock::value_type work_time(0);
148 etl::clock::value_type find_tile_time(0);
149 etl::clock::value_type add_tile_time(0);
152 // If the quality is set to zero, then we
153 // use the parametric scanline-renderer.
161 etl::clock tile_timer;
163 while((i=next_tile(x,y)))
165 find_tile_time+=tile_timer();
166 SuperCallback super(cb,(total_tiles-i+1)*1000,(total_tiles-i+2)*1000,total_tiles*1000);
167 if(!super.amount_complete(0,1000))
169 //if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
172 // Perform clipping on the tile
175 w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
176 h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
177 if(w<=0||h<=0)continue;
186 tile_desc.set_subwindow(x,y,w,h);
187 if(!parametric_render(context, surface, tile_desc,&super))
189 // For some reason, the parametric renderer failed.
190 if(cb)cb->error(_("Parametric Renderer Failure"));
197 if(cb)cb->error(_("Bad surface"));
200 if(get_remove_alpha())
201 for(int i=0;i<surface.get_w()*surface.get_h();i++)
202 surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
204 // Add the tile to the target
205 if(!add_tile(surface,x,y))
207 if(cb)cb->error(_("add_tile():Unable to put surface on target"));
214 else // If quality is set otherwise, then we use the accelerated renderer
221 etl::clock tile_timer;
223 while((i=next_tile(x,y)))
225 find_tile_time+=tile_timer();
226 SuperCallback super(cb,(total_tiles-i)*1000,(total_tiles-i+1)*1000,total_tiles*1000);
227 if(!super.amount_complete(0,1000))
229 // if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
231 // Perform clipping on the tile
234 w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
235 h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
236 if(w<=0||h<=0)continue;
245 tile_desc.set_subwindow(x,y,w,h);
250 if(!context.accelerated_render(&surface,get_quality(),tile_desc,&super))
252 // For some reason, the accelerated renderer failed.
253 if(cb)cb->error(_("Accelerated Renderer Failure"));
261 if(cb)cb->error(_("Bad surface"));
264 if(get_remove_alpha())
265 for(int i=0;i<surface.get_w()*surface.get_h();i++)
266 surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
270 // Add the tile to the target
271 if(!add_tile(surface,x,y))
273 if(cb)cb->error(_("add_tile():Unable to put surface on target"));
276 add_tile_time+=timer();
281 if(cb && !cb->amount_complete(total_tiles,total_tiles))
284 #if SYNFIG_DISPLAY_EFFICIENCY==1
285 synfig::info(">>>>>> Render Time: %fsec, Find Tile Time: %fsec, Add Tile Time: %fsec, Total Time: %fsec",work_time,find_tile_time,add_tile_time,total_time());
286 synfig::info(">>>>>> FRAME EFICIENCY: %f%%",(100.0f*work_time/total_time()));
293 synfig::Target_Tile::render(ProgressCallback *cb)
295 SuperCallback super_cb;
310 if(cb) cb->error(_("Target initialisation failure"));
315 // If the description's end frame is equal to
316 // the start frame, then it is assumed that we
317 // are rendering only one frame. Correct it.
318 if(desc.get_frame_end()==desc.get_frame_start())
319 desc.set_frame_end(desc.get_frame_start()+1);
321 frame_start=desc.get_frame_start();
322 frame_end=desc.get_frame_end();
323 time_start=desc.get_time_start();
324 time_end=desc.get_time_end();
326 // Calculate the number of frames
327 total_frames=frame_end-frame_start;
335 //synfig::info("1time_set_to %s",t.get_string().c_str());
343 // If we have a callback, and it returns
344 // false, go ahead and bail. (maybe a use cancel)
345 if(cb && !cb->amount_complete(total_frames-(i-1),total_frames))
351 // Set the time that we wish to render
352 //if(!get_avoid_time_sync() || canvas->get_time()!=t)
357 #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
358 Canvas::Handle op_canvas(Canvas::create());
359 optimize_layers(canvas->get_context(), op_canvas);
360 context=op_canvas->get_context();
362 context=canvas->get_context();
366 #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
368 Canvas::Handle op_canvas(Canvas::create());
369 // Set the time that we wish to render
371 optimize_layers(canvas->get_context(), op_canvas);
372 context=op_canvas->get_context();
375 // Set the time that we wish to render
377 context=canvas->get_context();
381 if(!render_frame_(context,0))
384 }while((i=next_frame(t)));
385 //synfig::info("tilerenderer: i=%d, t=%s",i,t.get_string().c_str());
394 // Set the time that we wish to render
395 // if(!get_avoid_time_sync() || canvas->get_time()!=t)
398 //synfig::info("2time_set_to %s",t.get_string().c_str());
402 #ifdef SYNFIG_OPTIMIZE_LAYER_TREE
403 Canvas::Handle op_canvas(Canvas::create());
404 optimize_layers(canvas->get_context(), op_canvas);
405 context=op_canvas->get_context();
407 context=canvas->get_context();
410 if(!render_frame_(context, cb))
418 if(cb)cb->error(_("Caught string :")+str);
421 catch(std::bad_alloc)
423 if(cb)cb->error(_("Ran out of memory (Probably a bug)"));
428 if(cb)cb->error(_("Caught unknown error, rethrowing..."));