|
|
9ea54a |
|
|
|
c4ee38 |
#include <cassert></cassert>
|
|
|
c4ee38 |
#include <iostream></iostream>
|
|
|
c4ee38 |
#include <iomanip></iomanip>
|
|
|
c4ee38 |
|
|
|
c4ee38 |
#include <glib.h></glib.h>
|
|
|
c4ee38 |
|
|
|
9ea54a |
#include <glibmm.h></glibmm.h>
|
|
|
9ea54a |
|
|
|
9ea54a |
#include <cairomm cairomm.h=""></cairomm>
|
|
|
9ea54a |
|
|
|
9ea54a |
#include <gtkmm drawingarea.h=""></gtkmm>
|
|
|
9ea54a |
|
|
|
9ea54a |
#include <synfig general.h=""></synfig>
|
|
|
9ea54a |
#include <synfig context.h=""></synfig>
|
|
|
9ea54a |
#include <synfig rendering="" task.h=""></synfig>
|
|
|
9ea54a |
#include <synfig common="" rendering="" task="" tasktransformation.h=""></synfig>
|
|
|
9ea54a |
|
|
|
9ea54a |
#include "visualizationwindow.h"
|
|
|
9ea54a |
|
|
|
9ea54a |
|
|
|
9ea54a |
using namespace synfig;
|
|
|
9ea54a |
|
|
|
9ea54a |
|
|
|
c4ee38 |
void
|
|
|
c4ee38 |
VisualizationWindow::Measure::print(const String &name, long long sum, long long rendered_frames) {
|
|
|
c4ee38 |
Real time = Real(sum)/Real(rendered_frames)*1e-6;
|
|
|
c4ee38 |
std::cout << std::setw(30) << name << std::setw(0) << " : "
|
|
|
c4ee38 |
<< std::setw(15) << std::setprecision(6) << std::fixed << time << std::endl;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
|
|
|
c4ee38 |
|
|
|
c4ee38 |
|
|
|
9ea54a |
VisualizationWindow::VisualizationWindow(
|
|
|
9ea54a |
const Canvas::Handle &canvas,
|
|
|
9ea54a |
const rendering::Renderer::Handle &renderer
|
|
|
9ea54a |
):
|
|
|
9ea54a |
canvas(canvas),
|
|
|
9ea54a |
renderer(renderer),
|
|
|
9ea54a |
transform(false),
|
|
|
9ea54a |
frame(0),
|
|
|
9ea54a |
frames_count(1),
|
|
|
9ea54a |
frame_duration(0),
|
|
|
c4ee38 |
pixel_format(0),
|
|
|
c4ee38 |
last_frame_time(0),
|
|
|
c4ee38 |
last_report_time(0),
|
|
|
c4ee38 |
last_report_id(0),
|
|
|
c4ee38 |
rendered_frames(0),
|
|
|
c4ee38 |
report_seconds(10),
|
|
|
c4ee38 |
closed(false)
|
|
|
9ea54a |
{
|
|
|
9ea54a |
// prepare rend desc
|
|
|
9ea54a |
rend_desc = canvas->rend_desc();
|
|
|
9ea54a |
rend_desc.set_wh(
|
|
|
9ea54a |
std::max(1, rend_desc.get_w()),
|
|
|
9ea54a |
std::max(1, rend_desc.get_h()) );
|
|
|
9ea54a |
Vector p0 = rend_desc.get_tl();
|
|
|
9ea54a |
Vector p1 = rend_desc.get_br();
|
|
|
9ea54a |
if (p0[0] > p1[0] || p0[1] > p1[1]) {
|
|
|
9ea54a |
if (p0[0] > p1[0]) { matrix.m00 = -1.0; matrix.m20 = p0[0] + p1[0]; std::swap(p0[0], p1[0]); }
|
|
|
9ea54a |
if (p0[1] > p1[1]) { matrix.m11 = -1.0; matrix.m21 = p0[1] + p1[1]; std::swap(p0[1], p1[1]); }
|
|
|
9ea54a |
rend_desc.set_tl_br(p0, p1);
|
|
|
9ea54a |
transform = true;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
// prepare frames counter
|
|
|
9ea54a |
frames_count = std::max(
|
|
|
9ea54a |
frames_count,
|
|
|
9ea54a |
rend_desc.get_frame_end() - rend_desc.get_frame_start() + 1 );
|
|
|
9ea54a |
Real fps = rend_desc.get_frame_rate();
|
|
|
9ea54a |
frame_duration = fps > real_precision<real>() ? 1/fps : 0;</real>
|
|
|
9ea54a |
|
|
|
9ea54a |
// prepare cairo surface
|
|
|
9ea54a |
cairo_surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, rend_desc.get_w(), rend_desc.get_h());
|
|
|
9ea54a |
|
|
|
9ea54a |
// check endianness and prepare pixel format
|
|
|
9ea54a |
union { int i; char c[4]; } checker = {0x01020304};
|
|
|
9ea54a |
bool big_endian = checker.c[0] == 1;
|
|
|
9ea54a |
pixel_format = big_endian
|
|
|
9ea54a |
? (PF_A_START | PF_RGB | PF_A_PREMULT)
|
|
|
9ea54a |
: (PF_BGR | PF_A | PF_A_PREMULT);
|
|
|
9ea54a |
|
|
|
9ea54a |
// prepare surface resource
|
|
|
9ea54a |
surface_resource = new rendering::SurfaceResource();
|
|
|
9ea54a |
surface_resource->create(rend_desc.get_w(), rend_desc.get_h());
|
|
|
9ea54a |
|
|
|
c4ee38 |
// prepare measures
|
|
|
c4ee38 |
measures.push_back(Measure("other gtk processing"));
|
|
|
c4ee38 |
measures.push_back(Measure("set time"));
|
|
|
c4ee38 |
measures.push_back(Measure("load resources"));
|
|
|
c4ee38 |
measures.push_back(Measure("outline grow"));
|
|
|
c4ee38 |
measures.push_back(Measure("create task"));
|
|
|
c4ee38 |
measures.push_back(Measure("optimize and render"));
|
|
|
c4ee38 |
measures.push_back(Measure("convert to cairo"));
|
|
|
c4ee38 |
measures.push_back(Measure("queue paint with cairo"));
|
|
|
c4ee38 |
|
|
|
9ea54a |
// create widgets
|
|
|
9ea54a |
Gtk::DrawingArea *drawing_area = manage(new Gtk::DrawingArea());
|
|
|
9ea54a |
drawing_area->signal_draw().connect(sigc::mem_fun(*this, &VisualizationWindow::on_content_draw));
|
|
|
9ea54a |
drawing_area->set_size_request(
|
|
|
9ea54a |
rend_desc.get_w(),
|
|
|
9ea54a |
rend_desc.get_h() );
|
|
|
9ea54a |
drawing_area->show();
|
|
|
9ea54a |
add(*drawing_area);
|
|
|
9ea54a |
|
|
|
9ea54a |
// redraw forever
|
|
|
9ea54a |
Glib::signal_idle().connect(sigc::mem_fun(*this, &VisualizationWindow::on_idle));
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
c4ee38 |
void
|
|
|
c4ee38 |
VisualizationWindow::on_hide() {
|
|
|
c4ee38 |
closed = true;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
|
|
|
9ea54a |
bool
|
|
|
9ea54a |
VisualizationWindow::on_idle() {
|
|
|
c4ee38 |
if (closed) return false;
|
|
|
9ea54a |
queue_draw();
|
|
|
9ea54a |
return true;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
|
|
|
9ea54a |
bool
|
|
|
9ea54a |
VisualizationWindow::convert(const rendering::SurfaceResource::Handle &surface)
|
|
|
9ea54a |
{
|
|
|
9ea54a |
rendering::SurfaceResource::LockReadBase surface_lock(surface);
|
|
|
9ea54a |
if (surface_lock.get_resource() && surface_lock.get_resource()->is_blank())
|
|
|
9ea54a |
return false;
|
|
|
9ea54a |
|
|
|
9ea54a |
if (!surface_lock.convert(rendering::Surface::Token::Handle(), false, true)) {
|
|
|
9ea54a |
synfig::error("convert: surface does not exists");
|
|
|
9ea54a |
return false;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
int w = cairo_surface->get_width();
|
|
|
9ea54a |
int h = cairo_surface->get_height();
|
|
|
9ea54a |
const rendering::Surface &s = *surface_lock.get_surface();
|
|
|
9ea54a |
if (w != s.get_width() || h != s.get_height()) {
|
|
|
9ea54a |
synfig::error("convert: surface with wrong size");
|
|
|
9ea54a |
return false;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
const Color *pixels = s.get_pixels_pointer();
|
|
|
9ea54a |
std::vector<color> pixels_copy;</color>
|
|
|
9ea54a |
if (!pixels) {
|
|
|
9ea54a |
pixels_copy.resize(w*h);
|
|
|
9ea54a |
if (s.get_pixels(&pixels_copy.front()))
|
|
|
9ea54a |
pixels = &pixels_copy.front();
|
|
|
9ea54a |
}
|
|
|
9ea54a |
if (!pixels) {
|
|
|
9ea54a |
synfig::error("convert: cannot access surface pixels - that really strange");
|
|
|
9ea54a |
return false;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
// do conversion
|
|
|
9ea54a |
color_to_pixelformat(
|
|
|
9ea54a |
cairo_surface->get_data(),
|
|
|
9ea54a |
pixels,
|
|
|
9ea54a |
pixel_format,
|
|
|
9ea54a |
0,
|
|
|
9ea54a |
cairo_surface->get_width(),
|
|
|
9ea54a |
cairo_surface->get_height(),
|
|
|
9ea54a |
cairo_surface->get_stride() );
|
|
|
9ea54a |
cairo_surface->mark_dirty();
|
|
|
9ea54a |
|
|
|
9ea54a |
return true;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
9ea54a |
|
|
|
9ea54a |
bool
|
|
|
9ea54a |
VisualizationWindow::on_content_draw(const Cairo::RefPtr<cairo::context> &context) {</cairo::context>
|
|
|
c4ee38 |
if (!last_frame_time && !last_report_time) {
|
|
|
c4ee38 |
last_frame_time = last_report_time = g_get_monotonic_time();
|
|
|
c4ee38 |
std::cout << std::endl
|
|
|
6c234c |
<< "gathering statistics, please wait reports every "
|
|
|
c4ee38 |
<< report_seconds << " seconds"
|
|
|
c4ee38 |
<< std::endl
|
|
|
c4ee38 |
<< std::endl;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
Measure *measure = &measures.front();
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
Time time = frame_duration*(frame + rend_desc.get_frame_start());
|
|
|
9ea54a |
canvas->set_time(time);
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
canvas->load_resources(time);
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
canvas->set_outline_grow(rend_desc.get_outline_grow());
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
bool surface_exists = false;
|
|
|
9ea54a |
ContextParams context_params(rend_desc.get_render_excluded_contexts());
|
|
|
9ea54a |
rendering::Task::Handle task = canvas->build_rendering_task(context_params);
|
|
|
9ea54a |
if (task) {
|
|
|
9ea54a |
if (transform) {
|
|
|
9ea54a |
rendering::TaskTransformationAffine::Handle t = new rendering::TaskTransformationAffine();
|
|
|
9ea54a |
t->transformation->matrix = matrix;
|
|
|
9ea54a |
t->sub_task() = task;
|
|
|
9ea54a |
task = t;
|
|
|
9ea54a |
}
|
|
|
9ea54a |
surface_resource->clear();
|
|
|
9ea54a |
task->target_surface = surface_resource;
|
|
|
9ea54a |
task->target_rect = RectInt( VectorInt(), task->target_surface->get_size() );
|
|
|
9ea54a |
task->source_rect = Rect(rend_desc.get_tl(), rend_desc.get_br());
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
if (task)
|
|
|
9ea54a |
renderer->run(task);
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
if (task)
|
|
|
9ea54a |
surface_exists = convert(task->target_surface);
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
9ea54a |
if (surface_exists) {
|
|
|
9ea54a |
context->set_source(cairo_surface, 0, 0);
|
|
|
9ea54a |
context->paint();
|
|
|
9ea54a |
}
|
|
|
9ea54a |
|
|
|
c4ee38 |
(measure++)->last = g_get_monotonic_time();
|
|
|
c4ee38 |
|
|
|
c4ee38 |
assert(measure - 1 == &measures.back());
|
|
|
c4ee38 |
for(Measure *m = &measures.front(); m < measure; ++m) {
|
|
|
c4ee38 |
m->sum += m->last - last_frame_time;
|
|
|
c4ee38 |
last_frame_time = m->last;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
|
|
|
c4ee38 |
if (rendered_frames > 1 && last_frame_time - last_report_time >= report_seconds*1000000ll) {
|
|
|
c4ee38 |
std::cout << "report #" << (++last_report_id) << std::endl;
|
|
|
c4ee38 |
Measure *mb = &measures.front();
|
|
|
c4ee38 |
for(Measure *m = mb+1; m < measure; ++m) {
|
|
|
c4ee38 |
m->print(rendered_frames);
|
|
|
c4ee38 |
m->sum = 0;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
mb->print(rendered_frames); // print 'other gtk' at last row
|
|
|
c4ee38 |
mb->sum = 0;
|
|
|
c4ee38 |
Measure::print("whole frame", last_frame_time - last_report_time, rendered_frames);
|
|
|
c4ee38 |
std::cout << std::endl;
|
|
|
c4ee38 |
last_report_time = last_frame_time;
|
|
|
c4ee38 |
rendered_frames = 0;
|
|
|
c4ee38 |
}
|
|
|
c4ee38 |
|
|
|
c4ee38 |
++rendered_frames;
|
|
|
9ea54a |
frame = (frame + 1) % frames_count;
|
|
|
6c234c |
queue_draw();
|
|
|
9ea54a |
return true;
|
|
|
9ea54a |
}
|