From 563a8b15e0205d24af0c93a6c38df0965ea7e5cd Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 8 Jan 2020 04:23:44 +0100 Subject: [PATCH] Revert to use an image surface for CairoWidgets This partially reverts 2edbda252619 and is a follow up to 0b266a54f, to fix performance issues with MS Windows graphics performance. --- libs/gtkmm2ext/cairo_widget.cc | 43 ++++++++++++++++++------- libs/gtkmm2ext/gtkmm2ext/cairo_widget.h | 5 +-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/libs/gtkmm2ext/cairo_widget.cc b/libs/gtkmm2ext/cairo_widget.cc index bbc4452238..b06e443ec0 100644 --- a/libs/gtkmm2ext/cairo_widget.cc +++ b/libs/gtkmm2ext/cairo_widget.cc @@ -58,9 +58,9 @@ CairoWidget::CairoWidget () { _name_proxy.connect (sigc::mem_fun (*this, &CairoWidget::on_name_changed)); #ifdef USE_CAIRO_IMAGE_SURFACE - _use_intermediate_surface = true; + _use_image_surface = true; #else - _use_intermediate_surface = NULL != getenv("ARDOUR_IMAGE_SURFACE"); + _use_image_surface = NULL != getenv("ARDOUR_IMAGE_SURFACE"); #endif } @@ -82,7 +82,8 @@ CairoWidget::set_canvas_widget () ensure_style (); gtk_widget_set_realized (GTK_WIDGET(gobj()), true); _canvas_widget = true; - _use_intermediate_surface = false; + _use_image_surface = false; + image_surface.clear (); } void @@ -97,9 +98,13 @@ CairoWidget::use_nsglview () } void -CairoWidget::use_intermediate_surface (bool yn) +CairoWidget::use_image_surface (bool yn) { - _use_intermediate_surface = yn; + if (_use_image_surface == yn) { + return; + } + image_surface.clear (); + _use_image_surface = yn; } int @@ -158,9 +163,14 @@ CairoWidget::on_expose_event (GdkEventExpose *ev) return true; } #endif - Cairo::RefPtr cr = get_window()->create_cairo_context (); - if (_use_intermediate_surface) { - cr->push_group (); + Cairo::RefPtr cr; + if (_use_image_surface) { + if (!image_surface) { + image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height()); + } + cr = Cairo::Context::create (image_surface); + } else { + cr = get_window()->create_cairo_context (); } cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height); @@ -188,9 +198,15 @@ CairoWidget::on_expose_event (GdkEventExpose *ev) render (cr, &expose_area); - if (_use_intermediate_surface) { - cr->pop_group_to_source (); - cr->paint (); + if (_use_image_surface) { + image_surface->flush(); + /* now blit our private surface back to the GDK one */ + Cairo::RefPtr window_context = get_window()->create_cairo_context (); + window_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height); + window_context->clip (); + window_context->set_source (image_surface, 0, 0); + window_context->set_operator (Cairo::OPERATOR_SOURCE); + window_context->paint (); } return true; @@ -245,6 +261,11 @@ CairoWidget::on_size_allocate (Gtk::Allocation& alloc) memcpy (&_allocation, &alloc, sizeof(Gtk::Allocation)); } + if (_use_image_surface) { + image_surface.clear (); + image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, alloc.get_width(), alloc.get_height()); + } + if (_canvas_widget) { return; } diff --git a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h index 7c7456eaa3..0dbd8fe8a0 100644 --- a/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h +++ b/libs/gtkmm2ext/gtkmm2ext/cairo_widget.h @@ -40,7 +40,7 @@ public: void set_canvas_widget (); void use_nsglview (); - void use_intermediate_surface (bool yn = true); + void use_image_surface (bool yn = true); /* swizzle Gtk::Widget methods for Canvas::Widget */ void queue_draw (); @@ -143,12 +143,13 @@ protected: static sigc::slot focus_handler; private: + Cairo::RefPtr image_surface; Glib::SignalProxyProperty _name_proxy; sigc::connection _parent_style_change; Widget * _current_parent; bool _canvas_widget; void* _nsglview; - bool _use_intermediate_surface; + bool _use_image_surface; Gdk::Rectangle _allocation; };