X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fasyncrenderer.cpp;h=3651b75f223a96928f1fac84ee7503aa17cd8061;hb=8e1d10adadf7237f6f2bfedef207add28485e74b;hp=b2de0872913c5546cc561ef07892b8ef7a2ad4f8;hpb=ce408de81ca266b1f334ee9bc6c8fb7ba1492ed4;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp b/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp index b2de087..3651b75 100644 --- a/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp +++ b/synfig-studio/trunk/src/gtkmm/asyncrenderer.cpp @@ -2,7 +2,7 @@ /*! \file asyncrenderer.cpp ** \brief Template File ** -** $Id: asyncrenderer.cpp,v 1.5 2005/01/12 07:03:42 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley @@ -30,6 +30,7 @@ #endif #include "asyncrenderer.h" +#include "app.h" #include #include @@ -75,7 +76,7 @@ class AsyncTarget_Tile : public synfig::Target_Tile { public: etl::handle warm_target; - + struct tile_t { Surface surface; @@ -87,16 +88,18 @@ public: } }; std::list tile_queue; +#ifndef SINGLE_THREADED Glib::Mutex mutex; - +#endif // SINGLE_THREADED + #ifndef GLIB_DISPATCHER_BROKEN Glib::Dispatcher tile_ready_signal; #endif Glib::Cond cond_tile_queue_empty; bool alive_flag; - + sigc::connection ready_connection; - + public: AsyncTarget_Tile(etl::handle warm_target): warm_target(warm_target) @@ -115,27 +118,29 @@ public: ready_connection=tile_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready)); #endif } - + ~AsyncTarget_Tile() { ready_connection.disconnect(); } void set_dead() { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED alive_flag=false; } - + virtual int total_tiles()const { return warm_target->total_tiles(); } - + virtual int next_tile(int& x, int& y) { if(!alive_flag) return 0; - + return warm_target->next_tile(x,y); } @@ -145,20 +150,22 @@ public: return 0; return warm_target->next_frame(time); } - + virtual bool start_frame(synfig::ProgressCallback *cb=0) { if(!alive_flag) return false; return warm_target->start_frame(cb); } - + virtual bool add_tile(const synfig::Surface &surface, int gx, int gy) { assert(surface); if(!alive_flag) return false; +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED tile_queue.push_back(tile_t(surface,gx,gy)); if(tile_queue.size()==1) { @@ -174,13 +181,15 @@ public: tile_ready_signal(); #endif } - + return alive_flag; } void tile_ready() { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED if(!alive_flag) { tile_queue.clear(); @@ -190,9 +199,9 @@ public: while(!tile_queue.empty() && alive_flag) { tile_t& tile(tile_queue.front()); - + alive_flag=warm_target->add_tile(tile.surface,tile.x,tile.y); - + tile_queue.pop_front(); } cond_tile_queue_empty.signal(); @@ -200,6 +209,7 @@ public: virtual void end_frame() { +#ifndef SINGLE_THREADED while(alive_flag) { Glib::Mutex::Lock lock(mutex); @@ -212,6 +222,7 @@ public: break; } Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED if(!alive_flag) return; return warm_target->end_frame(); @@ -224,12 +235,14 @@ class AsyncTarget_Scanline : public synfig::Target_Scanline { public: etl::handle warm_target; - + int scanline_; Surface surface; +#ifndef SINGLE_THREADED Glib::Mutex mutex; - +#endif // SINGLE_THREADED + #ifndef GLIB_DISPATCHER_BROKEN Glib::Dispatcher frame_ready_signal; #endif @@ -255,7 +268,7 @@ public: #endif surface.set_wh(warm_target->rend_desc().get_w(),warm_target->rend_desc().get_h()); } - + ~AsyncTarget_Scanline() { ready_connection.disconnect(); @@ -271,19 +284,23 @@ public: void set_dead() { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED alive_flag=false; } - - virtual bool start_frame(synfig::ProgressCallback *cb=0) - { + + virtual bool start_frame(synfig::ProgressCallback */*cb*/=0) + { return alive_flag; } - + virtual void end_frame() { { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED if(!alive_flag) return; @@ -302,22 +319,26 @@ public: #endif } +#ifndef SINGLE_THREADED while(alive_flag && !ready_next) { Glib::Mutex::Lock lock(mutex); if(cond_frame_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT))) break; } +#endif // SINGLE_THREADED } - + virtual Color * start_scanline(int scanline) { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED return surface[scanline]; } - + virtual bool end_scanline() { return alive_flag; @@ -325,7 +346,9 @@ public: void frame_ready() { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED if(alive_flag) alive_flag=warm_target->add_frame(&surface); cond_frame_queue_empty.signal(); @@ -343,6 +366,9 @@ AsyncRenderer::AsyncRenderer(etl::handle target_,synfig::Progres error(false), success(false), cb(cb) +#ifdef SINGLE_THREADED + , updating(false) +#endif // SINGLE_THREADED { render_thread=0; if(etl::handle::cast_dynamic(target_)) @@ -350,9 +376,9 @@ AsyncRenderer::AsyncRenderer(etl::handle target_,synfig::Progres etl::handle wrap_target( new AsyncTarget_Tile(etl::handle::cast_dynamic(target_)) ); - + signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Tile::set_dead)); - + target=wrap_target; } else if(etl::handle::cast_dynamic(target_)) @@ -362,9 +388,9 @@ AsyncRenderer::AsyncRenderer(etl::handle target_,synfig::Progres etl::handle::cast_dynamic(target_) ) ); - + signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Scanline::set_dead)); - + target=wrap_target; } } @@ -379,25 +405,29 @@ AsyncRenderer::stop() { if(target) { +#ifndef SINGLE_THREADED Glib::Mutex::Lock lock(mutex); +#endif // SINGLE_THREADED done_connection.disconnect(); - + if(render_thread) { signal_stop_(); - + +#ifndef SINGLE_THREADED #if REJOIN_ON_STOP render_thread->join(); #endif - +#endif + // Make sure all the dispatch crap is cleared out //Glib::MainContext::get_default()->iteration(false); - + if(success) signal_success_(); - + signal_finished_(); - + target=0; render_thread=0; } @@ -426,6 +456,16 @@ AsyncRenderer::start() ); } +#ifdef SINGLE_THREADED +void +AsyncRenderer::rendering_progress() +{ + updating = true; + while(studio::App::events_pending()) studio::App::iteration(false); + updating = false; +} +#endif // SINGLE_THREADED + void AsyncRenderer::start_() { @@ -435,7 +475,13 @@ AsyncRenderer::start_() #ifndef GLIB_DISPATCHER_BROKEN done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop)); #endif - + +#ifdef SINGLE_THREADED + synfig::info("%s:%d rendering in the same thread", __FILE__, __LINE__); + target->signal_progress().connect(sigc::mem_fun(this,&AsyncRenderer::rendering_progress)); + render_thread = (Glib::Thread*)1; + render_target(); +#else // SINGLE_THREADED render_thread=Glib::Thread::create( sigc::mem_fun(*this,&AsyncRenderer::render_target), #if REJOIN_ON_STOP @@ -445,6 +491,7 @@ AsyncRenderer::start_() #endif ); assert(render_thread); +#endif // SINGLE_THREADED } else { @@ -456,7 +503,7 @@ void AsyncRenderer::render_target() { etl::handle target(AsyncRenderer::target); - + if(target && target->render()) { success=true; @@ -469,7 +516,9 @@ AsyncRenderer::render_target() #endif } +#ifndef SINGLE_THREADED if(mutex.trylock()) +#endif // SINGLE_THREADED { #ifdef GLIB_DISPATCHER_BROKEN done_connection=Glib::signal_timeout().connect( @@ -482,6 +531,8 @@ AsyncRenderer::render_target() #else signal_done_.emit(); #endif +#ifndef SINGLE_THREADED mutex.unlock(); +#endif // SINGLE_THREADED } }