|
Carlos Lopez |
a09598 |
/* === S Y N F I G ========================================================= */
|
|
Carlos Lopez |
a09598 |
/*! \file asyncrenderer.cpp
|
|
Carlos Lopez |
a09598 |
** \brief Template File
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** $Id$
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** \legal
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2007 Chris Moore
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is free software; you can redistribute it and/or
|
|
Carlos Lopez |
a09598 |
** modify it under the terms of the GNU General Public License as
|
|
Carlos Lopez |
a09598 |
** published by the Free Software Foundation; either version 2 of
|
|
Carlos Lopez |
a09598 |
** the License, or (at your option) any later version.
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is distributed in the hope that it will be useful,
|
|
Carlos Lopez |
a09598 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Carlos Lopez |
a09598 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Carlos Lopez |
a09598 |
** General Public License for more details.
|
|
Carlos Lopez |
a09598 |
** \endlegal
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* ========================================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === H E A D E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef USING_PCH
|
|
Carlos Lopez |
a09598 |
# include "pch.h"
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
#ifdef HAVE_CONFIG_H
|
|
Carlos Lopez |
a09598 |
# include <config.h></config.h>
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "asyncrenderer.h"
|
|
Carlos Lopez |
a09598 |
#include "app.h"
|
|
Carlos Lopez |
a09598 |
#include <glibmm thread.h=""></glibmm>
|
|
Carlos Lopez |
a09598 |
#include <glibmm dispatcher.h=""></glibmm>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include <synfig general.h=""></synfig>
|
|
|
4590f7 |
#include <synfig context.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
#include <etl clock=""></etl>
|
|
Carlos Lopez |
a09598 |
|
|
|
abdbf2 |
#include <gui localization.h=""></gui>
|
|
BobSynfig |
56dae1 |
#include <docks dock_info.h=""></docks>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === U S I N G =========================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
using namespace std;
|
|
Carlos Lopez |
a09598 |
using namespace etl;
|
|
Carlos Lopez |
a09598 |
using namespace synfig;
|
|
Carlos Lopez |
a09598 |
using namespace studio;
|
|
Carlos Lopez |
a09598 |
|
|
|
4590f7 |
#define BOREDOM_TIMEOUT 1
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#define REJOIN_ON_STOP 1
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// The Glib::Dispatcher class is broken as of Glibmm 2.4.5.
|
|
Carlos Lopez |
a09598 |
// Defining this macro enables the workaround.
|
|
Carlos Lopez |
a09598 |
#define GLIB_DISPATCHER_BROKEN 1
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === C L A S S E S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
class AsyncTarget_Tile : public synfig::Target_Tile
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
public:
|
|
Carlos Lopez |
a09598 |
etl::handle<synfig::target_tile> warm_target;</synfig::target_tile>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
struct tile_t
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Surface surface;
|
|
Carlos Lopez |
a09598 |
int x,y;
|
|
Carlos Lopez |
a09598 |
tile_t(const Surface& surface,int x, int y):
|
|
Carlos Lopez |
a09598 |
surface(surface),
|
|
Carlos Lopez |
a09598 |
x(x),y(y)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
std::list<tile_t> tile_queue;</tile_t>
|
|
|
4590f7 |
std::list<glib::thread*> threads;</glib::thread*>
|
|
|
4590f7 |
bool err;
|
|
Carlos Lopez |
a09598 |
Glib::Mutex mutex;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
Glib::Dispatcher tile_ready_signal;
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
Glib::Cond cond_tile_queue_empty;
|
|
Carlos Lopez |
a09598 |
bool alive_flag;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
sigc::connection ready_connection;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
public:
|
|
Carlos Lopez |
a09598 |
AsyncTarget_Tile(etl::handle<synfig::target_tile> warm_target):</synfig::target_tile>
|
|
|
4590f7 |
warm_target(warm_target), err(false)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
set_avoid_time_sync(warm_target->get_avoid_time_sync());
|
|
Carlos Lopez |
a09598 |
set_tile_w(warm_target->get_tile_w());
|
|
Carlos Lopez |
a09598 |
set_tile_h(warm_target->get_tile_h());
|
|
Carlos Lopez |
a09598 |
set_canvas(warm_target->get_canvas());
|
|
Carlos Lopez |
a09598 |
set_quality(warm_target->get_quality());
|
|
|
dc451c |
set_alpha_mode(warm_target->get_alpha_mode());
|
|
Carlos Lopez |
a09598 |
set_threads(warm_target->get_threads());
|
|
Carlos Lopez |
a09598 |
set_clipping(warm_target->get_clipping());
|
|
Carlos Lopez |
a09598 |
set_rend_desc(&warm_target->rend_desc());
|
|
|
4590f7 |
set_engine(warm_target->get_engine());
|
|
Carlos Lopez |
a09598 |
alive_flag=true;
|
|
Carlos Lopez |
a09598 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
ready_connection=tile_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready));
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
~AsyncTarget_Tile()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
ready_connection.disconnect();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
void set_dead()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
alive_flag=false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
a4bbdd |
virtual bool async_render_tile(
|
|
|
a4bbdd |
etl::handle<canvas> canvas,</canvas>
|
|
|
a4bbdd |
ContextParams context_params,
|
|
|
a4bbdd |
RectInt rect,
|
|
|
a4bbdd |
RendDesc tile_desc,
|
|
|
3ca1e7 |
ProgressCallback */*cb*/ )
|
|
|
4590f7 |
{
|
|
|
4590f7 |
if(!alive_flag)
|
|
|
4590f7 |
return false;
|
|
|
4590f7 |
|
|
|
4590f7 |
Glib::Thread *thread = Glib::Thread::create(
|
|
|
4590f7 |
sigc::hide_return(
|
|
|
4590f7 |
sigc::bind(
|
|
|
4590f7 |
sigc::mem_fun(*this, &AsyncTarget_Tile::sync_render_tile),
|
|
|
a4bbdd |
canvas, context_params, rect, tile_desc, (synfig::ProgressCallback*)NULL )),
|
|
|
4590f7 |
true
|
|
|
4590f7 |
);
|
|
|
4590f7 |
assert(thread);
|
|
|
4590f7 |
|
|
|
4590f7 |
{
|
|
|
4590f7 |
Glib::Mutex::Lock lock(mutex);
|
|
|
4590f7 |
threads.push_back(thread);
|
|
|
4590f7 |
}
|
|
|
4590f7 |
|
|
|
4590f7 |
return true;
|
|
|
4590f7 |
}
|
|
|
4590f7 |
|
|
|
a4bbdd |
bool sync_render_tile(
|
|
|
a4bbdd |
etl::handle<canvas> canvas,</canvas>
|
|
|
a4bbdd |
ContextParams context_params,
|
|
|
a4bbdd |
RectInt rect,
|
|
|
a4bbdd |
RendDesc tile_desc,
|
|
|
a4bbdd |
ProgressCallback *cb )
|
|
|
4590f7 |
{
|
|
|
4590f7 |
if(!alive_flag)
|
|
|
4590f7 |
return false;
|
|
|
a4bbdd |
bool r = warm_target->async_render_tile(canvas, context_params, rect, tile_desc, cb);
|
|
|
4590f7 |
if (!r) { Glib::Mutex::Lock lock(mutex); err = true; }
|
|
|
4590f7 |
return r;
|
|
|
4590f7 |
}
|
|
|
4590f7 |
|
|
|
4590f7 |
virtual bool wait_render_tiles(ProgressCallback *cb=NULL)
|
|
|
4590f7 |
{
|
|
|
4590f7 |
if(!alive_flag)
|
|
|
4590f7 |
return false;
|
|
|
4590f7 |
|
|
|
4590f7 |
while(true)
|
|
|
4590f7 |
{
|
|
|
4590f7 |
Glib::Thread *thread;
|
|
|
4590f7 |
{
|
|
|
4590f7 |
Glib::Mutex::Lock lock(mutex);
|
|
|
4590f7 |
if (threads.empty()) break;
|
|
|
4590f7 |
thread = threads.front();
|
|
|
4590f7 |
threads.pop_front();
|
|
|
4590f7 |
|
|
|
4590f7 |
}
|
|
|
4590f7 |
thread->join();
|
|
|
4590f7 |
}
|
|
|
4590f7 |
|
|
|
4590f7 |
{ Glib::Mutex::Lock lock(mutex); if (err) return false; }
|
|
|
4590f7 |
return warm_target->wait_render_tiles(cb);
|
|
|
4590f7 |
}
|
|
|
4590f7 |
|
|
|
9f38ba |
virtual int next_tile(RectInt& rect)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return 0;
|
|
Carlos Lopez |
a09598 |
|
|
|
9f38ba |
return warm_target->next_tile(rect);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual int next_frame(Time& time)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return 0;
|
|
Carlos Lopez |
a09598 |
return warm_target->next_frame(time);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual bool start_frame(synfig::ProgressCallback *cb=0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return false;
|
|
|
4590f7 |
{ Glib::Mutex::Lock lock(mutex); err = false; }
|
|
Carlos Lopez |
a09598 |
return warm_target->start_frame(cb);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual bool add_tile(const synfig::Surface &surface, int gx, int gy)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
assert(surface);
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return false;
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
tile_queue.push_back(tile_t(surface,gx,gy));
|
|
Carlos Lopez |
a09598 |
if(tile_queue.size()==1)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#ifdef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
ready_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
a09598 |
sigc::bind_return(
|
|
Carlos Lopez |
a09598 |
sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready),
|
|
Carlos Lopez |
a09598 |
false
|
|
Carlos Lopez |
a09598 |
)
|
|
Carlos Lopez |
a09598 |
,0
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
tile_ready_signal();
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return alive_flag;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void tile_ready()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
tile_queue.clear();
|
|
Carlos Lopez |
a09598 |
cond_tile_queue_empty.signal();
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
while(!tile_queue.empty() && alive_flag)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
tile_t& tile(tile_queue.front());
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if (getenv("SYNFIG_SHOW_TILE_OUTLINES"))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Color red(1,0,0);
|
|
Carlos Lopez |
a09598 |
tile.surface.fill(red, 0, 0, 1, tile.surface.get_h());
|
|
Carlos Lopez |
a09598 |
tile.surface.fill(red, 0, 0, tile.surface.get_w(), 1);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
alive_flag=warm_target->add_tile(tile.surface,tile.x,tile.y);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
tile_queue.pop_front();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
cond_tile_queue_empty.signal();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual void end_frame()
|
|
Carlos Lopez |
a09598 |
{
|
|
|
a4bbdd |
while(alive_flag)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
a4bbdd |
Glib::Mutex::Lock lock(mutex);
|
|
|
a4bbdd |
Glib::TimeVal end_time;
|
|
Carlos Lopez |
408d07 |
|
|
|
a4bbdd |
end_time.assign_current_time();
|
|
|
a4bbdd |
end_time.add_microseconds(BOREDOM_TIMEOUT);
|
|
Carlos Lopez |
408d07 |
|
|
|
a4bbdd |
if(!tile_queue.empty() && alive_flag)
|
|
|
a4bbdd |
{
|
|
|
a4bbdd |
if(cond_tile_queue_empty.timed_wait(mutex,end_time))
|
|
Carlos Lopez |
a09598 |
break;
|
|
Carlos Lopez |
a09598 |
}
|
|
|
a4bbdd |
else
|
|
|
a4bbdd |
break;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
return warm_target->end_frame();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
0be21f |
class AsyncTarget_Cairo_Tile : public synfig::Target_Cairo_Tile
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
public:
|
|
Carlos Lopez |
0be21f |
etl::handle<synfig::target_cairo_tile> warm_target;</synfig::target_cairo_tile>
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
class tile_t
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
public:
|
|
Carlos Lopez |
0be21f |
cairo_surface_t* surface;
|
|
Carlos Lopez |
0be21f |
int x,y;
|
|
Carlos Lopez |
0be21f |
tile_t(): surface(NULL), x(0), y(0)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
tile_t(cairo_surface_t*& surface_,int x_, int y_)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(surface_)
|
|
Carlos Lopez |
0be21f |
surface=cairo_surface_reference(surface_);
|
|
Carlos Lopez |
0be21f |
else
|
|
Carlos Lopez |
0be21f |
surface=surface_;
|
|
Carlos Lopez |
0be21f |
x=x_;
|
|
Carlos Lopez |
0be21f |
y=y_;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
tile_t(const tile_t &other):
|
|
Carlos Lopez |
0be21f |
surface(cairo_surface_reference(other.surface)),
|
|
Carlos Lopez |
0be21f |
x(other.x),
|
|
Carlos Lopez |
0be21f |
y(other.y)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
~tile_t()
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(surface)
|
|
Carlos Lopez |
0be21f |
cairo_surface_destroy(surface);
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
};
|
|
Carlos Lopez |
0be21f |
std::list<tile_t> tile_queue;</tile_t>
|
|
Carlos Lopez |
0be21f |
Glib::Mutex mutex;
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
0be21f |
Glib::Dispatcher tile_ready_signal;
|
|
Carlos Lopez |
0be21f |
#endif
|
|
Carlos Lopez |
0be21f |
Glib::Cond cond_tile_queue_empty;
|
|
Carlos Lopez |
0be21f |
bool alive_flag;
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
sigc::connection ready_connection;
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
public:
|
|
Carlos Lopez |
0be21f |
AsyncTarget_Cairo_Tile(etl::handle<synfig::target_cairo_tile> warm_target):</synfig::target_cairo_tile>
|
|
Carlos Lopez |
0be21f |
warm_target(warm_target)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
set_avoid_time_sync(warm_target->get_avoid_time_sync());
|
|
Carlos Lopez |
0be21f |
set_tile_w(warm_target->get_tile_w());
|
|
Carlos Lopez |
0be21f |
set_tile_h(warm_target->get_tile_h());
|
|
Carlos Lopez |
0be21f |
set_canvas(warm_target->get_canvas());
|
|
Carlos Lopez |
0be21f |
set_quality(warm_target->get_quality());
|
|
|
dc451c |
set_alpha_mode(warm_target->get_alpha_mode());
|
|
Carlos Lopez |
0be21f |
set_threads(warm_target->get_threads());
|
|
Carlos Lopez |
0be21f |
set_clipping(warm_target->get_clipping());
|
|
Carlos Lopez |
0be21f |
set_rend_desc(&warm_target->rend_desc());
|
|
Carlos Lopez |
0be21f |
alive_flag=true;
|
|
Carlos Lopez |
0be21f |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
0be21f |
ready_connection=tile_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Cairo_Tile::tile_ready));
|
|
Carlos Lopez |
0be21f |
#endif
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
~AsyncTarget_Cairo_Tile()
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
ready_connection.disconnect();
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
void set_dead()
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
0be21f |
alive_flag=false;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
virtual int next_tile(int& x, int& y)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
return 0;
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
return warm_target->next_tile(x,y);
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
virtual int next_frame(Time& time)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
return 0;
|
|
Carlos Lopez |
0be21f |
return warm_target->next_frame(time);
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
virtual bool start_frame(synfig::ProgressCallback *cb=0)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
return false;
|
|
Carlos Lopez |
0be21f |
return warm_target->start_frame(cb);
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
66f437 |
virtual bool add_tile(cairo_surface_t* surface, int gx, int gy)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
if(cairo_surface_status(surface))
|
|
Carlos Lopez |
0be21f |
return false;
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
return false;
|
|
Carlos Lopez |
0be21f |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
0be21f |
tile_queue.push_back(tile_t(surface,gx,gy));
|
|
Carlos Lopez |
0be21f |
if(tile_queue.size()==1)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
#ifdef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
0be21f |
ready_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
0be21f |
sigc::bind_return(
|
|
Carlos Lopez |
0be21f |
sigc::mem_fun(*this,&AsyncTarget_Cairo_Tile::tile_ready),
|
|
Carlos Lopez |
0be21f |
false
|
|
Carlos Lopez |
0be21f |
)
|
|
Carlos Lopez |
0be21f |
,0
|
|
Carlos Lopez |
0be21f |
);
|
|
Carlos Lopez |
0be21f |
#else
|
|
Carlos Lopez |
0be21f |
tile_ready_signal();
|
|
Carlos Lopez |
0be21f |
#endif
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
//cairo_surface_destroy(surface);
|
|
Carlos Lopez |
0be21f |
return alive_flag;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
void tile_ready()
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
tile_queue.clear();
|
|
Carlos Lopez |
0be21f |
cond_tile_queue_empty.signal();
|
|
Carlos Lopez |
0be21f |
return;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
while(!tile_queue.empty() && alive_flag)
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
tile_t& tile(tile_queue.front());
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
// if (getenv("SYNFIG_SHOW_TILE_OUTLINES"))
|
|
Carlos Lopez |
0be21f |
// {
|
|
Carlos Lopez |
0be21f |
// Color red(1,0,0);
|
|
Carlos Lopez |
0be21f |
// tile.surface.fill(red, 0, 0, 1, tile.surface.get_h());
|
|
Carlos Lopez |
0be21f |
// tile.surface.fill(red, 0, 0, tile.surface.get_w(), 1);
|
|
Carlos Lopez |
0be21f |
// }
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
alive_flag=warm_target->add_tile(tile.surface,tile.x,tile.y);
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
tile_queue.pop_front();
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
cond_tile_queue_empty.signal();
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
virtual void end_frame()
|
|
Carlos Lopez |
0be21f |
{
|
|
|
a4bbdd |
while(alive_flag)
|
|
Carlos Lopez |
0be21f |
{
|
|
|
a4bbdd |
Glib::Mutex::Lock lock(mutex);
|
|
|
a4bbdd |
Glib::TimeVal end_time;
|
|
|
a4bbdd |
|
|
|
a4bbdd |
end_time.assign_current_time();
|
|
|
a4bbdd |
end_time.add_microseconds(BOREDOM_TIMEOUT);
|
|
|
a4bbdd |
|
|
|
a4bbdd |
if(!tile_queue.empty() && alive_flag)
|
|
Carlos Lopez |
0be21f |
{
|
|
|
a4bbdd |
if(cond_tile_queue_empty.timed_wait(mutex,end_time))
|
|
Carlos Lopez |
0be21f |
break;
|
|
Carlos Lopez |
0be21f |
}
|
|
|
a4bbdd |
else
|
|
|
a4bbdd |
break;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
0be21f |
if(!alive_flag)
|
|
Carlos Lopez |
0be21f |
return;
|
|
Carlos Lopez |
0be21f |
return warm_target->end_frame();
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
0be21f |
};
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
class AsyncTarget_Scanline : public synfig::Target_Scanline
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
public:
|
|
Carlos Lopez |
a09598 |
etl::handle<synfig::target_scanline> warm_target;</synfig::target_scanline>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
int scanline_;
|
|
Carlos Lopez |
a09598 |
Surface surface;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Glib::Mutex mutex;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
Glib::Dispatcher frame_ready_signal;
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
Glib::Cond cond_frame_queue_empty;
|
|
Carlos Lopez |
a09598 |
bool alive_flag;
|
|
Carlos Lopez |
a09598 |
bool ready_next;
|
|
Carlos Lopez |
a09598 |
sigc::connection ready_connection;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
public:
|
|
Carlos Lopez |
a09598 |
AsyncTarget_Scanline(etl::handle<synfig::target_scanline> warm_target):</synfig::target_scanline>
|
|
|
6320b8 |
warm_target(warm_target),
|
|
|
6320b8 |
scanline_(),
|
|
|
6320b8 |
alive_flag(),
|
|
|
6320b8 |
ready_next()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
set_avoid_time_sync(warm_target->get_avoid_time_sync());
|
|
Carlos Lopez |
a09598 |
set_canvas(warm_target->get_canvas());
|
|
Carlos Lopez |
a09598 |
set_quality(warm_target->get_quality());
|
|
|
dc451c |
set_alpha_mode(warm_target->get_alpha_mode());
|
|
Carlos Lopez |
a09598 |
set_threads(warm_target->get_threads());
|
|
Carlos Lopez |
a09598 |
set_rend_desc(&warm_target->rend_desc());
|
|
Carlos Lopez |
a09598 |
alive_flag=true;
|
|
Carlos Lopez |
a09598 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
ready_connection=frame_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready));
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
surface.set_wh(warm_target->rend_desc().get_w(),warm_target->rend_desc().get_h());
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
~AsyncTarget_Scanline()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
ready_connection.disconnect();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual int next_frame(Time& time)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return 0;
|
|
Carlos Lopez |
a09598 |
return warm_target->next_frame(time);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void set_dead()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
alive_flag=false;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual bool start_frame(synfig::ProgressCallback */*cb*/=0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return alive_flag;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual void end_frame()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(!alive_flag)
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
ready_next=false;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
ready_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
a09598 |
sigc::bind_return(
|
|
Carlos Lopez |
a09598 |
sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready),
|
|
Carlos Lopez |
a09598 |
false
|
|
Carlos Lopez |
a09598 |
)
|
|
Carlos Lopez |
a09598 |
,0
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
frame_ready_signal();
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
a4bbdd |
Glib::TimeVal end_time;
|
|
Carlos Lopez |
e2c658 |
|
|
|
a4bbdd |
end_time.assign_current_time();
|
|
|
a4bbdd |
end_time.add_microseconds(BOREDOM_TIMEOUT);
|
|
Carlos Lopez |
408d07 |
|
|
|
a4bbdd |
while(alive_flag && !ready_next)
|
|
|
a4bbdd |
{
|
|
|
a4bbdd |
Glib::Mutex::Lock lock(mutex);
|
|
|
a4bbdd |
if(cond_frame_queue_empty.timed_wait(mutex, end_time))
|
|
|
a4bbdd |
break;
|
|
Carlos Lopez |
408d07 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual Color * start_scanline(int scanline)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return surface[scanline];
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
virtual bool end_scanline()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
return alive_flag;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void frame_ready()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
if(alive_flag)
|
|
Carlos Lopez |
a09598 |
alive_flag=warm_target->add_frame(&surface);
|
|
|
a4bbdd |
cond_frame_queue_empty.signal();
|
|
Carlos Lopez |
a09598 |
ready_next=true;
|
|
BobSynfig |
56dae1 |
|
|
BobSynfig |
56dae1 |
int n_total_frames_to_render = warm_target->desc.get_frame_end() //120
|
|
BobSynfig |
56dae1 |
- warm_target->desc.get_frame_start() //0
|
|
BobSynfig |
56dae1 |
+ 1; //->121
|
|
BobSynfig |
56dae1 |
int current_rendered_frames_count = warm_target->curr_frame_
|
|
BobSynfig |
56dae1 |
- warm_target->desc.get_frame_start();
|
|
BobSynfig |
56dae1 |
float r = (float) current_rendered_frames_count
|
|
BobSynfig |
56dae1 |
/ (float) n_total_frames_to_render;
|
|
BobSynfig |
56dae1 |
App::dock_info_->set_render_progress(r);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
80f902 |
class AsyncTarget_Cairo : public synfig::Target_Cairo
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
public:
|
|
Carlos Lopez |
80f902 |
etl::handle<synfig::target_cairo> warm_target;</synfig::target_cairo>
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
cairo_surface_t* surface;
|
|
Carlos Lopez |
80f902 |
ProgressCallback *callback;
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
Glib::Mutex mutex;
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
80f902 |
Glib::Dispatcher frame_ready_signal;
|
|
Carlos Lopez |
80f902 |
#endif
|
|
Carlos Lopez |
80f902 |
Glib::Cond cond_frame_queue_empty;
|
|
Carlos Lopez |
80f902 |
bool alive_flag;
|
|
Carlos Lopez |
80f902 |
bool ready_next;
|
|
Carlos Lopez |
80f902 |
sigc::connection ready_connection;
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
public:
|
|
Carlos Lopez |
80f902 |
AsyncTarget_Cairo(etl::handle<synfig::target_cairo> warm_target):</synfig::target_cairo>
|
|
|
6320b8 |
warm_target(warm_target),
|
|
|
6320b8 |
surface(),
|
|
|
6320b8 |
callback(),
|
|
|
6320b8 |
alive_flag(),
|
|
|
6320b8 |
ready_next()
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
set_avoid_time_sync(warm_target->get_avoid_time_sync());
|
|
Carlos Lopez |
80f902 |
set_canvas(warm_target->get_canvas());
|
|
Carlos Lopez |
80f902 |
set_quality(warm_target->get_quality());
|
|
|
dc451c |
set_alpha_mode(warm_target->get_alpha_mode());
|
|
Carlos Lopez |
80f902 |
set_rend_desc(&warm_target->rend_desc());
|
|
Carlos Lopez |
80f902 |
alive_flag=true;
|
|
Carlos Lopez |
80f902 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
80f902 |
ready_connection=frame_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Cairo::frame_ready));
|
|
Carlos Lopez |
80f902 |
#endif
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
~AsyncTarget_Cairo()
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
ready_connection.disconnect();
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
virtual int next_frame(Time& time)
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
80f902 |
if(!alive_flag)
|
|
Carlos Lopez |
80f902 |
return 0;
|
|
Carlos Lopez |
80f902 |
return warm_target->next_frame(time);
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
void set_dead()
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
80f902 |
alive_flag=false;
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
virtual bool put_surface(cairo_surface_t* s, ProgressCallback *cb)
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
80f902 |
surface=s;
|
|
Carlos Lopez |
80f902 |
callback=cb;
|
|
Carlos Lopez |
80f902 |
if(!alive_flag)
|
|
Carlos Lopez |
80f902 |
return false;
|
|
Carlos Lopez |
80f902 |
ready_next=false;
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
#ifdef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
80f902 |
ready_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
80f902 |
sigc::bind_return(sigc::mem_fun(*this,&AsyncTarget_Cairo::frame_ready),false)
|
|
Carlos Lopez |
80f902 |
,0
|
|
Carlos Lopez |
80f902 |
);
|
|
Carlos Lopez |
80f902 |
#else
|
|
Carlos Lopez |
80f902 |
frame_ready_signal();
|
|
Carlos Lopez |
80f902 |
#endif
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
|
a4bbdd |
Glib::TimeVal end_time;
|
|
|
a4bbdd |
|
|
|
a4bbdd |
end_time.assign_current_time();
|
|
|
a4bbdd |
end_time.add_microseconds(BOREDOM_TIMEOUT);
|
|
|
a4bbdd |
|
|
|
a4bbdd |
while(alive_flag && !ready_next)
|
|
Carlos Lopez |
80f902 |
{
|
|
|
a4bbdd |
Glib::Mutex::Lock lock(mutex);
|
|
|
a4bbdd |
if(cond_frame_queue_empty.timed_wait(mutex, end_time))
|
|
|
a4bbdd |
break;
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
return true;
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
void frame_ready()
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
80f902 |
if(alive_flag)
|
|
Carlos Lopez |
80f902 |
alive_flag=warm_target->put_surface(surface, callback);
|
|
|
a4bbdd |
cond_frame_queue_empty.signal();
|
|
Carlos Lopez |
80f902 |
ready_next=true;
|
|
BobSynfig |
56dae1 |
|
|
BobSynfig |
56dae1 |
int n_total_frames_to_render = warm_target->desc.get_frame_end() //120
|
|
BobSynfig |
56dae1 |
- warm_target->desc.get_frame_start() //0
|
|
BobSynfig |
56dae1 |
+ 1; //->121
|
|
BobSynfig |
56dae1 |
int current_rendered_frames_count = warm_target->curr_frame_
|
|
BobSynfig |
56dae1 |
- warm_target->desc.get_frame_start();
|
|
BobSynfig |
56dae1 |
float r = (float) current_rendered_frames_count
|
|
BobSynfig |
56dae1 |
/ (float) n_total_frames_to_render;
|
|
BobSynfig |
56dae1 |
App::dock_info_->set_render_progress(r);
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
virtual bool obtain_surface(cairo_surface_t*& s)
|
|
Carlos Lopez |
80f902 |
{
|
|
Carlos Lopez |
80f902 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
80f902 |
if(!alive_flag)
|
|
Carlos Lopez |
80f902 |
return false;
|
|
Carlos Lopez |
80f902 |
return warm_target->obtain_surface(s);
|
|
Carlos Lopez |
80f902 |
}
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
80f902 |
};
|
|
Carlos Lopez |
80f902 |
|
|
Carlos Lopez |
a09598 |
/* === G L O B A L S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === P R O C E D U R E S ================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M E T H O D S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::AsyncRenderer(etl::handle<synfig::target> target_,synfig::ProgressCallback *cb):</synfig::target>
|
|
Carlos Lopez |
a09598 |
error(false),
|
|
Carlos Lopez |
a09598 |
success(false),
|
|
|
5d2885 |
cb(cb),
|
|
|
a86ba5 |
start_clock(0),
|
|
|
a86ba5 |
finish_clock(0),
|
|
|
5d2885 |
start_time(0, 0),
|
|
|
5d2885 |
finish_time(0, 0)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
render_thread=0;
|
|
Carlos Lopez |
a09598 |
if(etl::handle<synfig::target_tile>::cast_dynamic(target_))</synfig::target_tile>
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
etl::handle<asynctarget_tile> wrap_target(</asynctarget_tile>
|
|
Carlos Lopez |
a09598 |
new AsyncTarget_Tile(etl::handle<synfig::target_tile>::cast_dynamic(target_))</synfig::target_tile>
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Tile::set_dead));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
target=wrap_target;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else if(etl::handle<synfig::target_scanline>::cast_dynamic(target_))</synfig::target_scanline>
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
etl::handle<asynctarget_scanline> wrap_target(</asynctarget_scanline>
|
|
Carlos Lopez |
a09598 |
new AsyncTarget_Scanline(
|
|
Carlos Lopez |
a09598 |
etl::handle<synfig::target_scanline>::cast_dynamic(target_)</synfig::target_scanline>
|
|
Carlos Lopez |
a09598 |
)
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Scanline::set_dead));
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
target=wrap_target;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
0be21f |
else if(etl::handle<synfig::target_cairo_tile>::cast_dynamic(target_))</synfig::target_cairo_tile>
|
|
Carlos Lopez |
0be21f |
{
|
|
Carlos Lopez |
0be21f |
etl::handle<asynctarget_cairo_tile> wrap_target(</asynctarget_cairo_tile>
|
|
Carlos Lopez |
0be21f |
new AsyncTarget_Cairo_Tile(
|
|
Carlos Lopez |
0be21f |
etl::handle<synfig::target_cairo_tile>::cast_dynamic(target_)</synfig::target_cairo_tile>
|
|
Carlos Lopez |
0be21f |
)
|
|
Carlos Lopez |
0be21f |
);
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Cairo_Tile::set_dead));
|
|
Carlos Lopez |
0be21f |
|
|
Carlos Lopez |
0be21f |
target=wrap_target;
|
|
Carlos Lopez |
0be21f |
}
|
|
Carlos Lopez |
b17237 |
else if(etl::handle<synfig::target_cairo>::cast_dynamic(target_))</synfig::target_cairo>
|
|
Carlos Lopez |
b17237 |
{
|
|
Carlos Lopez |
b17237 |
etl::handle<asynctarget_cairo> wrap_target(</asynctarget_cairo>
|
|
Carlos Lopez |
b17237 |
new AsyncTarget_Cairo(
|
|
Carlos Lopez |
b17237 |
etl::handle<synfig::target_cairo>::cast_dynamic(target_)</synfig::target_cairo>
|
|
Carlos Lopez |
b17237 |
)
|
|
Carlos Lopez |
b17237 |
);
|
|
Carlos Lopez |
b17237 |
|
|
Carlos Lopez |
b17237 |
signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Cairo::set_dead));
|
|
Carlos Lopez |
b17237 |
|
|
Carlos Lopez |
b17237 |
target=wrap_target;
|
|
Carlos Lopez |
b17237 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::~AsyncRenderer()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
stop();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::stop()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
if(target)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Glib::Mutex::Lock lock(mutex);
|
|
Carlos Lopez |
a09598 |
done_connection.disconnect();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(render_thread)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
signal_stop_();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#if REJOIN_ON_STOP
|
|
|
a4bbdd |
render_thread->join();
|
|
Carlos Lopez |
a09598 |
#endif
|
|
|
5d2885 |
finish_time.assign_current_time();
|
|
|
a86ba5 |
finish_clock = ::clock();
|
|
|
5d2885 |
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
// Make sure all the dispatch crap is cleared out
|
|
Carlos Lopez |
a09598 |
//Glib::MainContext::get_default()->iteration(false);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(success)
|
|
Carlos Lopez |
a09598 |
signal_success_();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
target=0;
|
|
Carlos Lopez |
a09598 |
render_thread=0;
|
|
|
48b78b |
|
|
|
48b78b |
lock.release();
|
|
|
48b78b |
|
|
|
48b78b |
signal_finished_();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::pause()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::resume()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::start()
|
|
Carlos Lopez |
a09598 |
{
|
|
BobSynfig |
56dae1 |
App::dock_info_->set_render_progress(0.0);
|
|
|
5d2885 |
start_time.assign_current_time();
|
|
|
5d2885 |
finish_time = start_time;
|
|
|
a86ba5 |
start_clock = ::clock();
|
|
|
a86ba5 |
finish_clock = start_clock;
|
|
Carlos Lopez |
a09598 |
done_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
a09598 |
sigc::bind_return(
|
|
Carlos Lopez |
a09598 |
mem_fun(*this,&AsyncRenderer::start_),
|
|
Carlos Lopez |
a09598 |
false
|
|
Carlos Lopez |
a09598 |
)
|
|
|
b17c40 |
, 0
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::start_()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
error=false;success=false;
|
|
Carlos Lopez |
a09598 |
if(target)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#ifndef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop));
|
|
Carlos Lopez |
a09598 |
#endif
|
|
|
a4bbdd |
render_thread=Glib::Thread::create(
|
|
|
a4bbdd |
sigc::mem_fun(*this,&AsyncRenderer::render_target),
|
|
Carlos Lopez |
a09598 |
#if REJOIN_ON_STOP
|
|
|
a4bbdd |
true
|
|
Carlos Lopez |
a09598 |
#else
|
|
|
a4bbdd |
false
|
|
Carlos Lopez |
a09598 |
#endif
|
|
|
a4bbdd |
);
|
|
|
a4bbdd |
assert(render_thread);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
stop();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
void
|
|
Carlos Lopez |
a09598 |
AsyncRenderer::render_target()
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
etl::handle<target> target(AsyncRenderer::target);</target>
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(target && target->render())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
success=true;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
else
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
error=true;
|
|
Carlos Lopez |
a09598 |
#ifndef REJOIN_ON_STOP
|
|
Carlos Lopez |
a09598 |
return;
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
if(mutex.trylock())
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
#ifdef GLIB_DISPATCHER_BROKEN
|
|
Carlos Lopez |
a09598 |
done_connection=Glib::signal_timeout().connect(
|
|
Carlos Lopez |
a09598 |
sigc::bind_return(
|
|
Carlos Lopez |
a09598 |
mem_fun(*this,&AsyncRenderer::stop),
|
|
Carlos Lopez |
a09598 |
false
|
|
Carlos Lopez |
a09598 |
)
|
|
Carlos Lopez |
a09598 |
,0
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
signal_done_.emit();
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
mutex.unlock();
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
}
|