|
Carlos Lopez |
a09598 |
/* === S Y N F I G ========================================================= */
|
|
Carlos Lopez |
a09598 |
/*! \file renderer_canvas.h
|
|
Carlos Lopez |
a09598 |
** \brief Template Header
|
|
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
|
|
|
e6766e |
** ......... ... 2018 Ivan Mahonin
|
|
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 |
/* === S T A R T =========================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifndef __SYNFIG_RENDERER_CANVAS_H
|
|
Carlos Lopez |
a09598 |
#define __SYNFIG_RENDERER_CANVAS_H
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === H E A D E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
|
e06541 |
#include <climits></climits>
|
|
|
e06541 |
|
|
|
3707d8 |
#include <vector></vector>
|
|
|
3707d8 |
#include <map></map>
|
|
|
3707d8 |
|
|
|
e06541 |
#include <synfig time.h=""></synfig>
|
|
|
e06541 |
#include <synfig rendering="" task.h=""></synfig>
|
|
|
d421d7 |
#include <synfig renderer.h="" rendering=""></synfig>
|
|
|
e06541 |
|
|
|
d421d7 |
#include "../workarea.h"
|
|
Carlos Lopez |
a09598 |
#include "workarearenderer.h"
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M A C R O S ========================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === T Y P E D E F S ===================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === C L A S S E S & S T R U C T S ======================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
namespace studio {
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
class Renderer_Canvas : public studio::WorkAreaRenderer
|
|
Carlos Lopez |
a09598 |
{
|
|
|
3707d8 |
public:
|
|
|
d421d7 |
typedef etl::handle<renderer_canvas> Handle;</renderer_canvas>
|
|
|
d421d7 |
typedef etl::loose_handle<renderer_canvas> LooseHandle;</renderer_canvas>
|
|
|
d421d7 |
|
|
|
b943e0 |
enum FrameStatus {
|
|
|
b943e0 |
FS_None,
|
|
|
b943e0 |
FS_PartiallyDone,
|
|
|
b943e0 |
FS_InProcess,
|
|
|
b943e0 |
FS_Done
|
|
|
b943e0 |
};
|
|
|
d421d7 |
enum { FS_Count = FS_Done + 1 };
|
|
|
b943e0 |
|
|
|
48ca60 |
class FrameId {
|
|
|
3707d8 |
public:
|
|
|
3707d8 |
synfig::Time time;
|
|
|
48ca60 |
int width;
|
|
|
48ca60 |
int height;
|
|
|
48ca60 |
|
|
|
48ca60 |
explicit FrameId(
|
|
|
3707d8 |
const synfig::Time &time = synfig::Time(),
|
|
|
48ca60 |
int width = 0,
|
|
|
48ca60 |
int height = 0
|
|
|
48ca60 |
):
|
|
|
48ca60 |
time(time), width(width), height(height) { }
|
|
|
48ca60 |
|
|
|
48ca60 |
bool operator< (const FrameId &other) const {
|
|
|
48ca60 |
if (time < other.time) return true;
|
|
|
48ca60 |
if (other.time < time) return false;
|
|
|
48ca60 |
if (width < other.width) return true;
|
|
|
48ca60 |
if (other.width < width) return false;
|
|
|
48ca60 |
return height < other.height;
|
|
|
48ca60 |
}
|
|
|
48ca60 |
|
|
|
48ca60 |
bool operator== (const FrameId &other) const
|
|
|
48ca60 |
{ return time == other.time && width == other.width && height == other.height; }
|
|
|
48ca60 |
|
|
|
48ca60 |
bool operator!= (const FrameId &other) const
|
|
|
48ca60 |
{ return !(*this == other); }
|
|
|
d421d7 |
|
|
|
d421d7 |
FrameId with_time(const synfig::Time &time) const
|
|
|
d421d7 |
{ return FrameId(time, width, height); }
|
|
|
d421d7 |
synfig::RectInt rect() const
|
|
|
d421d7 |
{ return synfig::RectInt(0, 0, width, height); }
|
|
|
48ca60 |
};
|
|
|
48ca60 |
|
|
|
48ca60 |
class FrameDesc {
|
|
|
48ca60 |
public:
|
|
|
48ca60 |
FrameId id;
|
|
|
48ca60 |
synfig::ColorReal alpha;
|
|
|
48ca60 |
FrameDesc(): alpha() { }
|
|
|
48ca60 |
FrameDesc(
|
|
|
48ca60 |
const FrameId &id,
|
|
|
48ca60 |
synfig::ColorReal alpha ):
|
|
|
48ca60 |
id(id), alpha(alpha) { }
|
|
|
48ca60 |
FrameDesc(
|
|
|
48ca60 |
const synfig::Time &time,
|
|
|
48ca60 |
int width,
|
|
|
48ca60 |
int height,
|
|
|
48ca60 |
synfig::ColorReal alpha ):
|
|
|
48ca60 |
id(time, width, height), alpha(alpha) { }
|
|
|
3707d8 |
};
|
|
|
3707d8 |
|
|
|
e06541 |
class Tile: public etl::shared_object {
|
|
|
3707d8 |
public:
|
|
|
e06541 |
typedef etl::handle<tile> Handle;</tile>
|
|
|
e06541 |
|
|
|
b943e0 |
const FrameId frame_id;
|
|
|
e06541 |
const synfig::RectInt rect;
|
|
|
e06541 |
|
|
|
e06541 |
synfig::rendering::TaskEvent::Handle event;
|
|
|
e06541 |
synfig::rendering::SurfaceResource::Handle surface;
|
|
|
e6766e |
Cairo::RefPtr<cairo::imagesurface> cairo_surface;</cairo::imagesurface>
|
|
|
3707d8 |
|
|
|
b943e0 |
Tile() { }
|
|
|
b943e0 |
Tile(const FrameId &frame_id, synfig::RectInt &rect):
|
|
|
b943e0 |
frame_id(frame_id), rect(rect) { }
|
|
|
46d84c |
};
|
|
|
46d84c |
|
|
|
d421d7 |
typedef std::map<synfig::time, framestatus=""> StatusMap;</synfig::time,>
|
|
|
b943e0 |
typedef std::set<frameid> FrameSet;</frameid>
|
|
|
3707d8 |
typedef std::vector<framedesc> FrameList;</framedesc>
|
|
|
e06541 |
typedef std::vector<tile::handle> TileList;</tile::handle>
|
|
|
b943e0 |
typedef std::map<frameid, tilelist=""> TileMap;</frameid,>
|
|
|
3707d8 |
|
|
|
3707d8 |
private:
|
|
|
b943e0 |
// cache options
|
|
|
b943e0 |
const long long max_tiles_size_soft; //!< threshold for creation of new tiles
|
|
|
b943e0 |
const long long max_tiles_size_hard; //!< threshold for removing already created tiles
|
|
|
b943e0 |
const synfig::Real weight_future; //!< will multiply to frames count
|
|
|
b943e0 |
const synfig::Real weight_past;
|
|
|
8377b5 |
const synfig::Real weight_future_extra;
|
|
|
8377b5 |
const synfig::Real weight_past_extra;
|
|
|
b943e0 |
const synfig::Real weight_zoom_in; //!< will multiply to log(zoom)
|
|
|
b943e0 |
const synfig::Real weight_zoom_out;
|
|
|
dec360 |
const int max_enqueued_tasks;
|
|
|
b943e0 |
|
|
|
dec360 |
//! controls access to fields: enqueued_tasks, tiles, onion_frames, visible_frames, current_frame, frame_duration, tiles_size
|
|
Rodolfo Ribeiro Gomes |
424d47 |
std::mutex mutex;
|
|
|
3707d8 |
|
|
|
dec360 |
int enqueued_tasks;
|
|
|
dec360 |
|
|
|
e06541 |
//! stored tiles may be actual/outdated and rendered/not-rendered
|
|
|
3707d8 |
TileMap tiles;
|
|
|
e06541 |
|
|
|
e06541 |
//! all currently visible frames (onion skin feature allows to see more than one frame)
|
|
|
3707d8 |
FrameList onion_frames;
|
|
|
b943e0 |
FrameSet visible_frames;
|
|
|
d421d7 |
FrameId current_thumb;
|
|
|
b943e0 |
FrameId current_frame;
|
|
|
b943e0 |
synfig::Time frame_duration;
|
|
|
3707d8 |
|
|
|
e06541 |
//! increment of this field makes all tiles outdated
|
|
|
b943e0 |
long long tiles_size;
|
|
|
46d84c |
|
|
|
7c6c2d |
synfig::PixelFormat pixel_format;
|
|
|
7c6c2d |
|
|
|
017782 |
//! uses to normalize alpha value after blending of onion surfaces
|
|
|
017782 |
Cairo::RefPtr<cairo::imagesurface> alpha_src_surface;</cairo::imagesurface>
|
|
|
017782 |
Cairo::RefPtr<cairo::imagesurface> alpha_dst_surface;</cairo::imagesurface>
|
|
|
017782 |
Cairo::RefPtr<cairo::context> alpha_context;</cairo::context>
|
|
|
017782 |
|
|
|
e433dc |
synfig::Vector previous_tl;
|
|
|
e433dc |
synfig::Vector previous_br;
|
|
|
e433dc |
Cairo::RefPtr<cairo::imagesurface> previous_surface;</cairo::imagesurface>
|
|
|
e433dc |
|
|
|
e06541 |
// don't try to pass arguments to callbacks by reference, it cannot be properly saved in signal
|
|
|
b943e0 |
// Renderer_Canvas is non-thread-safe sigc::trackable, so use static callback methods in signals
|
|
|
e06541 |
static void on_tile_finished_callback(bool success, Renderer_Canvas *obj, Tile::Handle tile);
|
|
|
f2de3c |
static void on_post_tile_finished_callback(etl::handle<renderer_canvas> obj, Tile::Handle tile);</renderer_canvas>
|
|
|
e06541 |
|
|
|
b943e0 |
//! this method may be called from the other threads
|
|
|
e06541 |
void on_tile_finished(bool success, const Tile::Handle &tile);
|
|
|
48ca60 |
|
|
|
f2de3c |
//! this method may be called from the main thread only
|
|
|
f2de3c |
void on_post_tile_finished(const Tile::Handle &tile);
|
|
|
48ca60 |
|
|
|
b943e0 |
//! this method may be called from the other threads
|
|
|
65aa32 |
Cairo::RefPtr<cairo::imagesurface> convert(</cairo::imagesurface>
|
|
|
65aa32 |
const synfig::rendering::SurfaceResource::Handle &surface,
|
|
|
65aa32 |
int width, int height ) const;
|
|
Carlos Lopez |
a09598 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
b943e0 |
void insert_tile(TileList &list, const Tile::Handle &tile);
|
|
|
b943e0 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
5fc832 |
TileList::iterator erase_tile(TileList &list, TileList::iterator i, synfig::rendering::Task::List &events);
|
|
|
b943e0 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
b943e0 |
void remove_extra_tiles(synfig::rendering::Task::List &events);
|
|
|
b943e0 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
b943e0 |
void build_onion_frames();
|
|
|
b943e0 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
b943e0 |
FrameStatus calc_frame_status(const FrameId &id, const synfig::RectInt &window_rect);
|
|
|
b943e0 |
|
|
|
b943e0 |
//! mutex must be locked before call
|
|
|
b943e0 |
//! returns true if rendering task actually enqueued
|
|
|
b943e0 |
//! function can change the canvas time
|
|
|
d421d7 |
bool enqueue_render_frame(
|
|
|
d421d7 |
const synfig::rendering::Renderer::Handle &renderer,
|
|
|
d421d7 |
const synfig::Canvas::Handle &canvas,
|
|
|
d421d7 |
const synfig::RectInt &window_rect,
|
|
|
d421d7 |
const FrameId &id );
|
|
|
b943e0 |
|
|
Carlos Lopez |
a09598 |
public:
|
|
|
e06541 |
Renderer_Canvas();
|
|
Carlos Lopez |
a09598 |
~Renderer_Canvas();
|
|
Carlos Lopez |
a09598 |
|
|
|
e06541 |
// functions to render canvas in background
|
|
|
3707d8 |
|
|
|
b943e0 |
void enqueue_render();
|
|
|
3707d8 |
void wait_render();
|
|
|
b943e0 |
void clear_render();
|
|
|
b943e0 |
|
|
|
b943e0 |
void get_render_status(StatusMap &out_map);
|
|
|
3707d8 |
|
|
|
e06541 |
// just paint already rendered tiles at window
|
|
|
3707d8 |
void render_vfunc(
|
|
|
3707d8 |
const Glib::RefPtr<gdk::window>& drawable,</gdk::window>
|
|
|
3707d8 |
const Gdk::Rectangle& expose_area );
|
|
|
d421d7 |
|
|
|
d421d7 |
Cairo::RefPtr<cairo::imagesurface> get_thumb(const synfig::Time &time);</cairo::imagesurface>
|
|
|
d421d7 |
|
|
|
d421d7 |
static FrameStatus merge_status(FrameStatus a, FrameStatus b);
|
|
|
d421d7 |
static FrameStatus& merge_status_to(FrameStatus &dst, FrameStatus src)
|
|
|
d421d7 |
{ return dst = merge_status(dst, src); }
|
|
Carlos Lopez |
a09598 |
};
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
}; // END of namespace studio
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === E N D =============================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#endif
|