diff --git a/src/ui/widget/canvas.cpp b/src/ui/widget/canvas.cpp index 8330282ecf600c29ffdb1991fdbb3642d2c25a32..54a6d98dd5d557e8d2b7609cbb31d3e5a0de8021 100644 --- a/src/ui/widget/canvas.cpp +++ b/src/ui/widget/canvas.cpp @@ -82,6 +82,9 @@ * them "externally" (e.g. gradient CanvasItemCurves). */ +// Do updates either on idle or on draw signal +static bool const use_signal_idle = Glib::getenv("USE_SIGNAL_IDLE") == "1"; + struct PaintRectSetup { Geom::IntRect canvas_rect; gint64 start_time; @@ -89,6 +92,41 @@ struct PaintRectSetup { Geom::Point mouse_loc; }; +class FpsReporter +{ + std::string m_label; + unsigned m_fps = 0; + unsigned m_last_fps = 0; + std::chrono::time_point m_t_report; + +public: + FpsReporter(const char *label) + : m_label(label) + {} + + bool operator()(bool quiet=false) + { + ++m_fps; + + auto t_now = std::chrono::high_resolution_clock::now(); + + if (t_now - m_t_report < std::chrono::seconds(1)) { + return false; + } + + m_last_fps = m_fps; + + if (!quiet) { + std::cerr << m_label << " fps " << m_fps << std::endl; + } + + m_fps = 0; + m_t_report = t_now; + return true; + } + + unsigned fps() const { return m_last_fps; } +}; namespace Inkscape { namespace UI { @@ -769,6 +807,14 @@ void Canvas::on_size_allocate(Gtk::Allocation &allocation) bool Canvas::on_draw(const::Cairo::RefPtr<::Cairo::Context>& cr) { + static FpsReporter fpsreporter(__PRETTY_FUNCTION__); + fpsreporter(); + + if (!use_signal_idle && _need_paint) { + _need_paint = false; + do_update(); + } + // sp_canvas_item_recursive_print_tree(0, _root); // canvas_item_print_tree(_canvas_item_root); @@ -934,6 +980,20 @@ Canvas::add_idle() return; } + if (!use_signal_idle) { + auto draw_region = Cairo::Region::create(Cairo::RectangleInt{ + _x0, + _y0, + _allocation.get_width(), + _allocation.get_height(), + }); + draw_region->subtract(_clean_region); + draw_region->translate(_allocation.get_x() - _x0, _allocation.get_y() - _y0); + queue_draw_region(draw_region); + _need_paint = true; + return; + } + if (get_realized() && !_idle_connection.connected()) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint redrawPriority = prefs->getIntLimited("/options/redrawpriority/value", G_PRIORITY_HIGH_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT_IDLE); @@ -957,6 +1017,9 @@ Canvas::remove_idle() bool Canvas::on_idle() { + static FpsReporter fpsreporter(__PRETTY_FUNCTION__); + fpsreporter(); + if (_in_destruction) { std::cerr << "Canvas::on_idle: Called after canvas destroyed!" << std::endl; } @@ -988,6 +1051,9 @@ Canvas::on_idle() bool Canvas::do_update() { + static FpsReporter fpsreporter(__PRETTY_FUNCTION__); + fpsreporter(); + assert(_canvas_item_root); assert(_drawing); @@ -1021,6 +1087,9 @@ Canvas::do_update() bool Canvas::paint() { + static FpsReporter fpsreporter(__PRETTY_FUNCTION__); + fpsreporter(); + if (_need_update) { std::cerr << "Canvas::Paint: called while needing update!" << std::endl; } diff --git a/src/ui/widget/canvas.h b/src/ui/widget/canvas.h index a902088909cf455878add344f254669497c23743..e93b0b6901b4ef14c9eb2eb3a8502a3f91dc9727 100644 --- a/src/ui/widget/canvas.h +++ b/src/ui/widget/canvas.h @@ -209,6 +209,7 @@ private: // Drawing bool _drawing_disabled = false; ///< Disable drawing during critical operations bool _need_update = true; // Set true so setting CanvasItem bounds are calculated at least once. + bool _need_paint = true; CanvasItemGroup *_canvas_item_root = nullptr; Inkscape::Drawing *_drawing = nullptr;