1 /* === S I N F 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 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
31 #include "target_tile.h"
42 /* === U S I N G =========================================================== */
46 using namespace sinfg;
48 /* === M A C R O S ========================================================= */
49 const unsigned int DEF_TILE_WIDTH = 64;
50 const unsigned int DEF_TILE_HEIGHT= 64;
52 #define SINFG_OPTIMIZE_LAYER_TREE 1
54 #define SINFG_DISPLAY_EFFICIENCY 1
57 /* === G L O B A L S ======================================================= */
59 /* === P R O C E D U R E S ================================================= */
61 /* === M E T H O D S ======================================================= */
63 Target_Tile::Target_Tile():
65 tile_w_(DEF_TILE_WIDTH),
66 tile_h_(DEF_TILE_HEIGHT),
74 Target_Tile::next_frame(Time& time)
84 // If the description's end frame is equal to
85 // the start frame, then it is assumed that we
86 // are rendering only one frame. Correct it.
87 if(desc.get_frame_end()==desc.get_frame_start())
88 desc.set_frame_end(desc.get_frame_start()+1);
90 frame_start=desc.get_frame_start();
91 frame_end=desc.get_frame_end();
92 time_start=desc.get_time_start();
93 time_end=desc.get_time_end();
95 // Calculate the number of frames
96 total_frames=frame_end-frame_start;
97 if(total_frames<=0)total_frames=1;
99 //RendDesc rend_desc=desc;
100 //rend_desc.set_gamma(1);
102 // int total_tiles(total_tiles());
103 time=(time_end-time_start)*curr_frame_/total_frames+time_start;
106 /* sinfg::info("curr_frame_: %d",curr_frame_);
107 sinfg::info("total_frames: %d",total_frames);
108 sinfg::info("time_end: %s",time_end.get_string().c_str());
109 sinfg::info("time_start: %s",time_start.get_string().c_str());
111 // sinfg::info("time: %s",time.get_string().c_str());
113 return total_frames- curr_frame_+1;
117 Target_Tile::next_tile(int& x, int& y)
119 // Width of the image(in tiles)
120 int tw(rend_desc().get_w()/tile_w_);
121 int th(rend_desc().get_h()/tile_h_);
123 // Add the last tiles (which will be clipped)
124 if(rend_desc().get_w()%tile_w_!=0)tw++;
125 if(rend_desc().get_h()%tile_h_!=0)th++;
127 x=(curr_tile_%tw)*tile_h_;
128 y=(curr_tile_/tw)*tile_w_;
131 return (tw*th)-curr_tile_+1;
135 sinfg::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
137 if(tile_w_<=0||tile_h_<=0)
139 if(cb)cb->error(_("Bad Tile Size"));
142 const RendDesc &rend_desc(desc);
143 #define total_tiles total_tiles()
145 etl::clock total_time;
146 etl::clock::value_type work_time(0);
147 etl::clock::value_type find_tile_time(0);
148 etl::clock::value_type add_tile_time(0);
151 // If the quality is set to zero, then we
152 // use the parametric scanline-renderer.
160 etl::clock tile_timer;
162 while((i=next_tile(x,y)))
164 find_tile_time+=tile_timer();
165 SuperCallback super(cb,(total_tiles-i+1)*1000,(total_tiles-i+2)*1000,total_tiles*1000);
166 if(!super.amount_complete(0,1000))
168 //if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
171 // Perform clipping on the tile
174 w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
175 h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
176 if(w<=0||h<=0)continue;
185 tile_desc.set_subwindow(x,y,w,h);
186 if(!parametric_render(context, surface, tile_desc,&super))
188 // For some reason, the parametric renderer failed.
189 if(cb)cb->error(_("Parametric Renderer Failure"));
196 if(cb)cb->error(_("Bad surface"));
199 if(get_remove_alpha())
200 for(int i=0;i<surface.get_w()*surface.get_h();i++)
201 surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
203 // Add the tile to the target
204 if(!add_tile(surface,x,y))
206 if(cb)cb->error(_("add_tile():Unable to put surface on target"));
213 else // If quality is set otherwise, then we use the accelerated renderer
220 etl::clock tile_timer;
222 while((i=next_tile(x,y)))
224 find_tile_time+=tile_timer();
225 SuperCallback super(cb,(total_tiles-i)*1000,(total_tiles-i+1)*1000,total_tiles*1000);
226 if(!super.amount_complete(0,1000))
228 // if(cb && !cb->amount_complete(total_tiles-i,total_tiles))
230 // Perform clipping on the tile
233 w=x+tile_w_<rend_desc.get_w()?tile_w_:rend_desc.get_w()-x;
234 h=y+tile_h_<rend_desc.get_h()?tile_h_:rend_desc.get_h()-y;
235 if(w<=0||h<=0)continue;
244 tile_desc.set_subwindow(x,y,w,h);
249 if(!context.accelerated_render(&surface,get_quality(),tile_desc,&super))
251 // For some reason, the accelerated renderer failed.
252 if(cb)cb->error(_("Accelerated Renderer Failure"));
260 if(cb)cb->error(_("Bad surface"));
263 if(get_remove_alpha())
264 for(int i=0;i<surface.get_w()*surface.get_h();i++)
265 surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
269 // Add the tile to the target
270 if(!add_tile(surface,x,y))
272 if(cb)cb->error(_("add_tile():Unable to put surface on target"));
275 add_tile_time+=timer();
280 if(cb && !cb->amount_complete(total_tiles,total_tiles))
283 #if SINFG_DISPLAY_EFFICIENCY==1
284 sinfg::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());
285 sinfg::info(">>>>>> FRAME EFICIENCY: %f%%",(100.0f*work_time/total_time()));
292 sinfg::Target_Tile::render(ProgressCallback *cb)
294 SuperCallback super_cb;
309 // If the description's end frame is equal to
310 // the start frame, then it is assumed that we
311 // are rendering only one frame. Correct it.
312 if(desc.get_frame_end()==desc.get_frame_start())
313 desc.set_frame_end(desc.get_frame_start()+1);
315 frame_start=desc.get_frame_start();
316 frame_end=desc.get_frame_end();
317 time_start=desc.get_time_start();
318 time_end=desc.get_time_end();
320 // Calculate the number of frames
321 total_frames=frame_end-frame_start;
329 //sinfg::info("1time_set_to %s",t.get_string().c_str());
337 // If we have a callback, and it returns
338 // false, go ahead and bail. (maybe a use cancel)
339 if(cb && !cb->amount_complete(total_frames-(i-1),total_frames))
345 // Set the time that we wish to render
346 //if(!get_avoid_time_sync() || canvas->get_time()!=t)
351 #ifdef SINFG_OPTIMIZE_LAYER_TREE
352 Canvas::Handle op_canvas(Canvas::create());
353 optimize_layers(canvas->get_context(), op_canvas);
354 context=op_canvas->get_context();
356 context=canvas->get_context();
360 #ifdef SINFG_OPTIMIZE_LAYER_TREE
362 Canvas::Handle op_canvas(Canvas::create());
363 // Set the time that we wish to render
365 optimize_layers(canvas->get_context(), op_canvas);
366 context=op_canvas->get_context();
369 // Set the time that we wish to render
371 context=canvas->get_context();
375 if(!render_frame_(context,0))
378 }while((i=next_frame(t)));
379 //sinfg::info("tilerenderer: i=%d, t=%s",i,t.get_string().c_str());
388 // Set the time that we wish to render
389 // if(!get_avoid_time_sync() || canvas->get_time()!=t)
392 //sinfg::info("2time_set_to %s",t.get_string().c_str());
396 #ifdef SINFG_OPTIMIZE_LAYER_TREE
397 Canvas::Handle op_canvas(Canvas::create());
398 optimize_layers(canvas->get_context(), op_canvas);
399 context=op_canvas->get_context();
401 context=canvas->get_context();
404 if(!render_frame_(context, cb))
412 if(cb)cb->error(_("Caught string :")+str);
415 catch(std::bad_alloc)
417 if(cb)cb->error(_("Ran out of memory (Probably a bug)"));
422 if(cb)cb->error(_("Caught unknown error, rethrowing..."));