/* === S Y N F I G ========================================================= */
/*! \file synfig/rendering/renderer.h
** \brief Renderer Header
**
** $Id$
**
** \legal
** ......... ... 2015 Ivan Mahonin
**
** 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.
**
** 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
*/
/* ========================================================================= */
/* === S T A R T =========================================================== */
#ifndef __SYNFIG_RENDERING_RENDERER_H
#define __SYNFIG_RENDERING_RENDERER_H
/* === H E A D E R S ======================================================= */
#include <cstdio>
#include <map>
#include <atomic>
#include "optimizer.h"
/* === M A C R O S ========================================================= */
/* === T Y P E D E F S ===================================================== */
/* === C L A S S E S & S T R U C T S ======================================= */
namespace synfig
{
namespace rendering
{
class RenderQueue;
class Renderer: public etl::shared_object
{
public:
typedef etl::handle<Renderer> Handle;
typedef std::multimap<Real, ModeToken::Handle> ModeMap;
struct DebugOptions {
String task_list_log;
String task_list_optimized_log;
String result_image;
};
private:
static Handle blank;
static std::map<String, Handle> *renderers;
static RenderQueue *queue;
static DebugOptions debug_options;
static long long last_registered_optimizer_index;
static long long last_batch_index; // TODO: atomic
ModeList modes;
Optimizer::List optimizers[Optimizer::CATEGORIES_COUNT];
public:
virtual ~Renderer();
virtual String get_name() const = 0;
const Optimizer::List& get_optimizers(Optimizer::CategoryId category_id) const
{ return optimizers[category_id]; }
bool is_optimizer_registered(const Optimizer::Handle &optimizer) const;
void register_optimizer(Real order, const Optimizer::Handle &optimizer);
void register_optimizer(const Optimizer::Handle &optimizer);
void unregister_optimizer(const Optimizer::Handle &optimizer);
const ModeList& get_modes() const
{ return modes; }
void register_mode(int index, const ModeToken::Handle &mode);
void register_mode(const ModeToken::Handle &mode);
void unregister_mode(const ModeToken::Handle &mode);
private:
int count_tasks_recursive(Task::List &list) const;
int count_tasks(Task::List &list) const;
void calc_coords(const Task::List &list) const;
void specialize_recursive(Task::List &list) const;
void specialize(Task::List &list) const;
void remove_dummy(Task::List &list) const;
void linearize(Task::List &list) const;
int subtasks_count(const Task::Handle &task, int max_count) const;
bool
call_optimizers(
const Optimizer::List &optimizers,
const Optimizer::RunParams& params,
std::atomic<int> *calls_count,
std::atomic<int> *optimizations_count,
bool deep_first ) const;
void optimize_recursive(
const Optimizer::List *optimizers, // pass by pointer for use with sigc::bind
const Optimizer::RunParams *params, // pass by pointer for use with sigc::bind
std::atomic<int> *calls_count,
std::atomic<int> *optimizations_count,
int max_level ) const;
void optimize(Optimizer::Category category, Task::List &list) const;
void log(
const String &logfile,
const Task::Handle &task,
const Optimizer::RunParams* optimization_stack = NULL,
int level = 0 ) const;
void log(
const String &logfile,
const Task::List &list,
const String &name = String(),
const Optimizer::RunParams* optimization_stack = NULL ) const;
static void initialize_renderers();
static void deinitialize_renderers();
typedef std::pair<Surface::Handle, int> DepTargetKey;
typedef std::pair<Task::Handle, Task::Set> DepTargetValue;
typedef std::multimap<DepTargetKey, DepTargetValue> DepTargetMap;
typedef DepTargetMap::value_type DepTargetPair;
void find_deps(const Task::List &list, long long batch_index) const;
public:
int get_max_simultaneous_threads() const;
void optimize(Task::List &list) const;
bool run(
const Task::List &list,
bool quiet = false ) const;
bool run(
const Task::Handle &task,
bool quiet = false ) const
{ return run(Task::List(1, task), quiet); }
void enqueue(
const Task::List &list,
const TaskEvent::Handle &finish_event_task,
bool quiet = false ) const;
void enqueue(
const Task::Handle &task,
const TaskEvent::Handle &finish_event_task,
bool quiet = false ) const
{ return enqueue(Task::List(1, task), finish_event_task, quiet); }
static void cancel(const Task::Handle &task);
static void cancel(const Task::List &list);
// function to use in signals
static void enqueue_task_func(Renderer::Handle renderer, Task::Handle task, TaskEvent::Handle finish_event_task, bool quiet)
{ renderer->enqueue(task, finish_event_task, quiet); }
static void enqueue_list_func(Renderer::Handle renderer, Task::List list, TaskEvent::Handle finish_event_task, bool quiet)
{ renderer->enqueue(list, finish_event_task, quiet); } // list will passed as copy
static void cancel_task_func(Task::Handle task)
{ cancel(task); }
static void cancel_list_func(Task::List list)
{ cancel(list); } // list will passed as copy
static void initialize();
static void deinitialize();
static void register_renderer(const String &name, const Renderer::Handle &renderer);
static void unregister_renderer(const String &name);
static const Renderer::Handle& get_renderer(const String &name);
static const std::map<String, Handle>& get_renderers();
static const DebugOptions& get_debug_options()
{ return debug_options; }
static bool subsys_init()
{ initialize(); return true; }
static bool subsys_stop()
{ deinitialize(); return false; }
};
} /* end namespace rendering */
} /* end namespace synfig */
/* -- E N D ----------------------------------------------------------------- */
#endif