Flickering with Socket and Plug

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

Flickering with Socket and Plug

René Hansen
Hey GTK list,

I've uploaded a demo app on https://github.com/rehans/GtkSocketPlugDemo

It is very simple and just creates a GtkWindow with a GtkSocket child. A
GtkPlug with an GtkDrawingArea attached is connected to the socket. The
GtkDrawingArea redraws itself every 16ms and simply paints an image.
(Some things in the demo might not be very meaningful but it is just to
demo the problem)

While this demo works on Ubuntu 16.04 (tested on 3 PCs) with
libgtk-3-0:amd64  3.18.9-1ubuntu3.3  amd64  GTK+ graphical user
interface library

it starts flickering constantly on Ubuntu 17.04 with
libgtk-3-0:amd64  3.22.11-0ubuntu3  amd64  GTK+ graphical user interface
library

The Raspberry PI 3 with (Debian Stretch installed) shows the same
behavior like Ubuntu 17.04 with
libgtk-3-0:armhf  3.22.11-1+rpi3  armhf  GTK+ graphical user interface
library

(I've checked the GTK Version with "dpkg -l libgtk-3-0" from Terminal)

Does anyone know what is causing this behavior and can help me out here?
Anything I can improve? Is this a GTK bug which was introduced after 3.18.9?

René
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Stefan Salewski-2
On Sun, 2017-09-24 at 13:54 +0200, René Hansen wrote:
> it starts flickering constantly

I don't know what Socket and Plug is...

But you seems to do the drawing completely wrong.

Generally gtk_widget_queue_draw() is involved in the drawing process,
that is that your timer does not do the drawing directly, but only
invalidates the widget, which cause a indirect draw.

You may find a few examples for this, one recent using plain C was
contained in this thread:

https://lists.cairographics.org/archives/cairo/2016-October/027791.html

https://pastebin.com/in17XGjs
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
 > But you seems to do the drawing completely wrong.
 >
 > Generally gtk_widget_queue_draw() is involved in the drawing process,
 > that is that your timer does not do the drawing directly, but only
 > invalidates the widget, which cause a indirect draw.

True, you are right. I had a look at a bunch of examples and many do it
like this. They invalidate parts or the whole widget in a timer callback
and redraw it in the on_draw function.

 > You may find a few examples for this, one recent using plain C was
 > contained in this thread:
 >
 > https://lists.cairographics.org/archives/cairo/2016-October/027791.html
 >
 > https://pastebin.com/in17XGjs

I just had a look at the links. In the example it is done almost the
same like I do (if I got it right), though it must not be the "right
way". But even placing gtk_widget_queue_draw into my draw_callback
funtion does not prevent the window from flickering.

It must be someting inside the Socket and Plug of GTK, because when I
simply add the drawing_area to the window (without any socket or plug
involved) everything works fine.
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list
In reply to this post by René Hansen

Hi Rene,

It looks like you are trying to paint a surface 100 times every 16ms. Maybe not such a good thing to do. If you are looking to animate a drawing, GTK has a frame clock that is easy to use.

The plug and socket are separate programs. You would start your socket and add one or more plugs to it. Each plug is running as it's own process. It is some extra work to do this and there are a few different approaches for drawing that I would use before going this route. I sort of think that if I was running a bunch of complicated OpenGL windows on x11, maybe give it a try.

There is some socket and plug test code at the following.

https://github.com/cecashon/OrderedSetVelociRaptor/blob/master/Misc/Csamples/plug2.c
https://github.com/cecashon/OrderedSetVelociRaptor/blob/master/Misc/Csamples/socket2.c

I just added a frame clock to the plug. If you are looking to animate a drawing in a plug that might be of some help.

If you are programming in C++, the gtkmm tutorial is very good.

https://developer.gnome.org/gtkmm-tutorial/stable/chapter-plugs-sockets.html.en

Break apart your code into a plug and socket and change your drawing a little and see if that flickering still occurs.

Eric




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
Hey Eric,

> It looks like you are trying to paint a surface 100 times every 16ms.
> Maybe not such a good thing to do.

Yes, I agree but that's on purpose in order to make the problem *very*
obvious ;) In one of my projects I draw round about 25 bitmaps (which
partly overlap) onto the drawingarea. While some mouse interaction takes
place I need to redraw several times. This results in flickering of all
single bitmaps almost everytime I redraw. It looks as if the drawingarea
gets cleared before I finish drawing my bitmaps.

 > The plug and socket are separate programs. You would start your socket
 > and add one or more plugs to it. Each plug is running as it's own
 > process.

Yes, that's correct. But in the documentation of Gtk::Socket::add_id it
says:
"Adds an XEMBED client, such as a Gtk::Plug, to the Gtk::Socket.
The client may be in the same process or in a different process."

So I am of the assumption that both is possible. Either Socket and Plug
live in the same process or different processes. Is that correct?

Some details about my real world project (I hope it is not too
confusing). I have a host application (executable) which builds its GUI
with Gtk. Then I have a plug-in (shared object resp. .so file) which
also builds its GUI with Gtk. But the plug-ins GUI must be shown by
embedding it into the host application (like x11 is capable of). So I
pass the socket_id of the host to the plug-in so it can connect by
creating a plug. The plug-in lives inside the host application's
process. But it is also possible that the host creates an extra process
to let the plug-in run, but still, the GUI must be shown inside the host
application. Both scenarios are possible.

 > There is some socket and plug test code at the following.
...
 > I just added a frame clock to the plug. If you are looking to animate
a drawing in a plug that might be of some help.

Thanks! I will have closer look and try to figure out how this works.

 > If you are programming in C++, the gtkmm tutorial is very good.

Yes, I know this one, built it and let it run successfully. No
flickering. Afterwards I extended this example by having both socket and
plug in the same process. I added some idle call to the plug and let it
draw a bunch of bitmaps. It started flickering. Then I removed all the
gtkmm stuff in order to have plain Gtk code. And this is the example I
have put on my github ;)

Thanks for help. I will study your "plug2.c" example and see what I will
come up with.

René
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Paul Davis
For whatever it's worth, I was working on a similar plugin situation 16 years ago.  I tried using plug+socket. Couldn't make it work. GTK+ developers at the time told me to stop using it.

We now get a Gtk::Widget* from a plugin and add that to our own Gtk::Window.

On Tue, Sep 26, 2017 at 1:54 PM, René Hansen <[hidden email]> wrote:
Hey Eric,

It looks like you are trying to paint a surface 100 times every 16ms.
Maybe not such a good thing to do.

Yes, I agree but that's on purpose in order to make the problem *very* obvious ;) In one of my projects I draw round about 25 bitmaps (which partly overlap) onto the drawingarea. While some mouse interaction takes place I need to redraw several times. This results in flickering of all single bitmaps almost everytime I redraw. It looks as if the drawingarea gets cleared before I finish drawing my bitmaps.

> The plug and socket are separate programs. You would start your socket
> and add one or more plugs to it. Each plug is running as it's own
> process.

Yes, that's correct. But in the documentation of Gtk::Socket::add_id it says:
"Adds an XEMBED client, such as a Gtk::Plug, to the Gtk::Socket.
The client may be in the same process or in a different process."

So I am of the assumption that both is possible. Either Socket and Plug live in the same process or different processes. Is that correct?

Some details about my real world project (I hope it is not too confusing). I have a host application (executable) which builds its GUI with Gtk. Then I have a plug-in (shared object resp. .so file) which also builds its GUI with Gtk. But the plug-ins GUI must be shown by embedding it into the host application (like x11 is capable of). So I pass the socket_id of the host to the plug-in so it can connect by creating a plug. The plug-in lives inside the host application's process. But it is also possible that the host creates an extra process to let the plug-in run, but still, the GUI must be shown inside the host application. Both scenarios are possible.

> There is some socket and plug test code at the following.
...
> I just added a frame clock to the plug. If you are looking to animate a drawing in a plug that might be of some help.

Thanks! I will have closer look and try to figure out how this works.

> If you are programming in C++, the gtkmm tutorial is very good.

Yes, I know this one, built it and let it run successfully. No flickering. Afterwards I extended this example by having both socket and plug in the same process. I added some idle call to the plug and let it draw a bunch of bitmaps. It started flickering. Then I removed all the gtkmm stuff in order to have plain Gtk code. And this is the example I have put on my github ;)

Thanks for help. I will study your "plug2.c" example and see what I will come up with.


René
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list


_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list
In reply to this post by René Hansen

I don't know about the flickering and don't have Ubuntu17.04 to test with.

If I test out 100 pixbufs and try to redraw with a timer at 16ms it will draw without flickering but not update the drawing every 16ms. It is dependent on the draw callback drawing time. For long drawing times you can do some performance testing to try to optimize the process. You don't want the drawing times too long. If you have long drawing times and put your drawing on a separate thread you will get some flicker if the window needs to redraw itself but the drawing thread hasn't finished.

I tested this out some but couldn't get it to flicker on Ubuntu 16.04.

Eric

/*
    gcc -Wall pixbuf_cache1.c -o pixbuf_cache1 `pkg-config --cflags --libs gtk+-3.0`
    Tested on Ubuntu16.04 and GTK3.18
*/
 
#include <gtk/gtk.h>

static GdkPixbuf* draw_icon();
static gboolean redraw_pixbufs(gpointer da);
static gboolean draw_pixbufs(GtkWidget *da, cairo_t *cr, GdkPixbuf **pixbuf_cache);
static void quit_program(GtkWidget *widget, gpointer data);

static GTimer *timer=NULL;
static guint timer_id=0;

int main(int argc, char **argv)
  {     
    gtk_init(&argc, &argv);  

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
    gtk_window_set_title(GTK_WINDOW(window), "Pixbuf Cache");
    g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);

    timer=g_timer_new();

    gint i=0;
    GdkPixbuf *pixbuf_cache[100];
    for(i=0;i<100;i++)
      {
        pixbuf_cache[i]=draw_icon();
      }
 
    GtkWidget *da=gtk_drawing_area_new();
    gtk_widget_set_hexpand(da, TRUE);
    gtk_widget_set_vexpand(da, TRUE);
    g_signal_connect(da, "draw", G_CALLBACK(draw_pixbufs), pixbuf_cache);

    gtk_container_add(GTK_CONTAINER(window), da);

    timer_id=g_timeout_add(16, (GSourceFunc)redraw_pixbufs, da);

    gtk_widget_show_all(window);                 
    gtk_main();

    g_timer_destroy(timer);
    for(i=0;i<100;i++)
      {
        g_object_unref(pixbuf_cache[i]);
      }

    return 0;
  }
static gboolean redraw_pixbufs(gpointer da)
  {
    gtk_widget_queue_draw(GTK_WIDGET(da));
    return G_SOURCE_CONTINUE;
  }
static gboolean draw_pixbufs(GtkWidget *da, cairo_t *cr, GdkPixbuf **pixbuf_cache)
  {
    g_timer_start(timer);
    gint i=0;
    gint j=0;
    gint move_x=0;
    gint move_y=0;
    static gint overlap=0;

    for(i=0;i<10;i++)
      {
        for(j=0;j<10;j++)
          {
            GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple(pixbuf_cache[10*i+j], 40, 40, GDK_INTERP_BILINEAR);
            gdk_cairo_set_source_pixbuf(cr, pixbuf, move_x, move_y);
            cairo_paint(cr);
            move_x+=40-overlap;
            g_object_unref(pixbuf);
          }
        move_x=0;
        move_y+=40;
      }

    if(overlap==20) overlap=0;
    else overlap++;
    
    g_print("Timer %f\n", g_timer_elapsed(timer, NULL));  
    return FALSE;
  }
static GdkPixbuf* draw_icon()
  { 
    static gdouble move_line=0.0;
    //Create a surface to draw a 256x256 icon.
    cairo_surface_t *surface_icon=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 256, 256);
    cairo_t *cr=cairo_create(surface_icon);

    cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
    cairo_paint(cr);

    cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
    cairo_set_line_width(cr, 15.0);
    cairo_translate(cr, 128, 128);
    cairo_rotate(cr, move_line);
    cairo_move_to(cr, 0.0, 0.0);
    cairo_line_to(cr, 200, 0.0);
    cairo_stroke(cr);      
  
    GdkPixbuf *icon=gdk_pixbuf_get_from_surface(surface_icon, 0, 0, 256, 256);

    cairo_destroy(cr);
    cairo_surface_destroy(surface_icon);
    move_line+=0.1;

    return icon;
  }
static void quit_program(GtkWidget *widget, gpointer data)
  {
    g_source_remove(timer_id);
    gtk_main_quit();
  }
 




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list
In reply to this post by René Hansen

Hi Rene,

I looked at this a little more and can get the flicker. Testing on Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04 with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little so that I could test it a little easier.

Eric


/*
    gcc -Wall socket_plug1.c -o socket_plug1 `pkg-config --cflags --libs gtk+-3.0`
    Tested on Ubuntu16.04 and GTK3.18 and GTK3.22
    Flickers with 3.22
*/
 
#include <cairo.h>
#include <gtk/gtkx.h>

//cairo_surface_t * image = NULL;
GdkPixbuf *image=NULL;
static GTimer *timer=NULL;
static guint timer_id=0;

gboolean timeout(gpointer data)
{
  gtk_widget_queue_draw(GTK_WIDGET(data));
  return TRUE;
}

gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
{
  g_timer_start(timer);
  gint width=gtk_widget_get_allocated_width(widget);
  gint height=gtk_widget_get_allocated_height(widget);
  gint rect_x=width/10;
  gint rect_y=height/10;
  gint i=0;
  gint j=0;
  gint move_x=0;
  gint move_y=0;
  static gint overlap=0;

  //Set some limits to draw with.
  if(rect_x>20&&rect_y>20)
    {
      GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple(image, rect_x, rect_y, GDK_INTERP_BILINEAR);
      for(i=0;i<10;i++)
        {
          for(j=0;j<10;j++)
            {
              gdk_cairo_set_source_pixbuf(cr, pixbuf, move_x, move_y);
              cairo_paint(cr);
              move_x+=rect_x-overlap;
            }
          move_x=0;
          move_y+=rect_y;
        }
      g_object_unref(pixbuf);

      if(overlap==20) overlap=0;
      else overlap++;
    }
  else
    {
      //Just draw white if below the limit.
      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
      cairo_paint(cr);
    }
    
  g_print("Timer %f\n", g_timer_elapsed(timer, NULL));  
  return FALSE;
}
static void quit_program(GtkWidget *widget, gpointer data)
  {
    g_source_remove(timer_id);
    gtk_main_quit();
  }
//-------------------------------------------------------------------------
int main(int argc, char** argv)
{
  gtk_init (&argc, &argv);

  //image = cairo_image_surface_create_from_png("1200px-GTK+_logo.svg.png");
  GError *error=NULL;
  image = gdk_pixbuf_new_from_file("1200px-GTK+_logo.svg.png", &error);
  if(error!=NULL) g_print("%s\n", error->message);

  GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
  g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);

  timer=g_timer_new();

  GtkWidget* socket = gtk_socket_new();
  gtk_widget_set_hexpand(socket, TRUE);
  gtk_widget_set_vexpand(socket, TRUE);
  gtk_container_add(GTK_CONTAINER(window), socket);

  Window socket_id = gtk_socket_get_id(GTK_SOCKET(socket));
  GtkWidget* plug = gtk_plug_new(socket_id);
  gtk_widget_set_hexpand(plug, TRUE);
  gtk_widget_set_vexpand(plug, TRUE);

  GtkWidget* drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_hexpand(drawing_area, TRUE);
  gtk_widget_set_vexpand(drawing_area, TRUE);
  gtk_container_add(GTK_CONTAINER(plug), drawing_area);
  g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK (draw_callback), NULL);

  timer_id=g_timeout_add(16, timeout, drawing_area);
  gtk_widget_show_all(plug);
  gtk_widget_show_all (window);
 
  gtk_main ();
  return 0;
}


_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
Hey Eric,

 > I looked at this a little more and can get the flicker. Testing on
 > Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04
 > with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little
 > so that I could test it a little easier.

Good, that you can reproduce it!

So what is your suggestion, how can we procceed with this issue? This is
very likely a bug in GTK, right?

Many thanks for our effort!
René

On 27.09.2017 22:00, [hidden email] wrote:

>
> Hi Rene,
>
> I looked at this a little more and can get the flicker. Testing on
> Ubuntu16.04 with GTK3.18 it works without flicker and on Ubuntu16.04
> with a jhbuild of GTK3.22 it does flicker. I tweaked your code a little
> so that I could test it a little easier.
>
> Eric
>
>
> /*
>      gcc -Wall socket_plug1.c -o socket_plug1 `pkg-config --cflags
> --libs gtk+-3.0`
>      Tested on Ubuntu16.04 and GTK3.18 and GTK3.22
>      Flickers with 3.22
> */
>
> #include <cairo.h>
> #include <gtk/gtkx.h>
>
> //cairo_surface_t * image = NULL;
> GdkPixbuf *image=NULL;
> static GTimer *timer=NULL;
> static guint timer_id=0;
>
> gboolean timeout(gpointer data)
> {
>    gtk_widget_queue_draw(GTK_WIDGET(data));
>    return TRUE;
> }
>
> gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
> {
>    g_timer_start(timer);
>    gint width=gtk_widget_get_allocated_width(widget);
>    gint height=gtk_widget_get_allocated_height(widget);
>    gint rect_x=width/10;
>    gint rect_y=height/10;
>    gint i=0;
>    gint j=0;
>    gint move_x=0;
>    gint move_y=0;
>    static gint overlap=0;
>
>    //Set some limits to draw with.
>    if(rect_x>20&&rect_y>20)
>      {
>        GdkPixbuf *pixbuf=gdk_pixbuf_scale_simple(image, rect_x, rect_y,
> GDK_INTERP_BILINEAR);
>        for(i=0;i<10;i++)
>          {
>            for(j=0;j<10;j++)
>              {
>                gdk_cairo_set_source_pixbuf(cr, pixbuf, move_x, move_y);
>                cairo_paint(cr);
>                move_x+=rect_x-overlap;
>              }
>            move_x=0;
>            move_y+=rect_y;
>          }
>        g_object_unref(pixbuf);
>
>        if(overlap==20) overlap=0;
>        else overlap++;
>      }
>    else
>      {
>        //Just draw white if below the limit.
>        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
>        cairo_paint(cr);
>      }
>
>    g_print("Timer %f\n", g_timer_elapsed(timer, NULL));
>    return FALSE;
> }
> static void quit_program(GtkWidget *widget, gpointer data)
>    {
>      g_source_remove(timer_id);
>      gtk_main_quit();
>    }
> //-------------------------------------------------------------------------
> int main(int argc, char** argv)
> {
>    gtk_init (&argc, &argv);
>
>    //image =
> cairo_image_surface_create_from_png("1200px-GTK+_logo.svg.png");
>    GError *error=NULL;
>    image = gdk_pixbuf_new_from_file("1200px-GTK+_logo.svg.png", &error);
>    if(error!=NULL) g_print("%s\n", error->message);
>
>    GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
>    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
>    g_signal_connect(window, "destroy", G_CALLBACK(quit_program), NULL);
>
>    timer=g_timer_new();
>
>    GtkWidget* socket = gtk_socket_new();
>    gtk_widget_set_hexpand(socket, TRUE);
>    gtk_widget_set_vexpand(socket, TRUE);
>    gtk_container_add(GTK_CONTAINER(window), socket);
>
>    Window socket_id = gtk_socket_get_id(GTK_SOCKET(socket));
>    GtkWidget* plug = gtk_plug_new(socket_id);
>    gtk_widget_set_hexpand(plug, TRUE);
>    gtk_widget_set_vexpand(plug, TRUE);
>
>    GtkWidget* drawing_area = gtk_drawing_area_new ();
>    gtk_widget_set_hexpand(drawing_area, TRUE);
>    gtk_widget_set_vexpand(drawing_area, TRUE);
>    gtk_container_add(GTK_CONTAINER(plug), drawing_area);
>    g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK
> (draw_callback), NULL);
>
>    timer_id=g_timeout_add(16, timeout, drawing_area);
>    gtk_widget_show_all(plug);
>    gtk_widget_show_all (window);
>
>    gtk_main ();
>    return 0;
> }
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
In reply to this post by Paul Davis
Hey Paul,

thanks for your remark. Since Steinberg released the technical preview
of VST3 with Linux support, I try to port my synthesizer. The SDK
contains a tiny host called EditorHost. It simply opens up the GUI
editor of a plug-in. The host uses gtkmm (like my plug-in) and passes
the socket_id resp. the window id to the plug-in.

Until I switched to Ubuntu 17.04 everything was running smooth already.
Unfortunately it started flickering.

So, in case of Ardour the plug-in has to use gtkmm for building its GUI,
right? Using another GUI framework is not possible.

OT: Any plans of having VST3 in Ardour for Linux?

René

On 26.09.2017 20:13, Paul Davis wrote:

> For whatever it's worth, I was working on a similar plugin situation 16
> years ago.  I tried using plug+socket. Couldn't make it work. GTK+
> developers at the time told me to stop using it.
>
> We now get a Gtk::Widget* from a plugin and add that to our own Gtk::Window.
>
> On Tue, Sep 26, 2017 at 1:54 PM, René Hansen <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Hey Eric,
>
>         It looks like you are trying to paint a surface 100 times every
>         16ms.
>         Maybe not such a good thing to do.
>
>
>     Yes, I agree but that's on purpose in order to make the problem
>     *very* obvious ;) In one of my projects I draw round about 25
>     bitmaps (which partly overlap) onto the drawingarea. While some
>     mouse interaction takes place I need to redraw several times. This
>     results in flickering of all single bitmaps almost everytime I
>     redraw. It looks as if the drawingarea gets cleared before I finish
>     drawing my bitmaps.
>
>     > The plug and socket are separate programs. You would start your socket
>     > and add one or more plugs to it. Each plug is running as it's own
>     > process.
>
>     Yes, that's correct. But in the documentation of Gtk::Socket::add_id
>     it says:
>     "Adds an XEMBED client, such as a Gtk::Plug, to the Gtk::Socket.
>     The client may be in the same process or in a different process."
>
>     So I am of the assumption that both is possible. Either Socket and
>     Plug live in the same process or different processes. Is that correct?
>
>     Some details about my real world project (I hope it is not too
>     confusing). I have a host application (executable) which builds its
>     GUI with Gtk. Then I have a plug-in (shared object resp. .so file)
>     which also builds its GUI with Gtk. But the plug-ins GUI must be
>     shown by embedding it into the host application (like x11 is capable
>     of). So I pass the socket_id of the host to the plug-in so it can
>     connect by creating a plug. The plug-in lives inside the host
>     application's process. But it is also possible that the host creates
>     an extra process to let the plug-in run, but still, the GUI must be
>     shown inside the host application. Both scenarios are possible.
>
>     > There is some socket and plug test code at the following.
>     ...
>     > I just added a frame clock to the plug. If you are looking to animate a drawing in a plug that might be of some help.
>
>     Thanks! I will have closer look and try to figure out how this works.
>
>     > If you are programming in C++, the gtkmm tutorial is very good.
>
>     Yes, I know this one, built it and let it run successfully. No
>     flickering. Afterwards I extended this example by having both socket
>     and plug in the same process. I added some idle call to the plug and
>     let it draw a bunch of bitmaps. It started flickering. Then I
>     removed all the gtkmm stuff in order to have plain Gtk code. And
>     this is the example I have put on my github ;)
>
>     Thanks for help. I will study your "plug2.c" example and see what I
>     will come up with.
>
>
>     René
>     _______________________________________________
>     gtk-list mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.gnome.org/mailman/listinfo/gtk-list
>     <https://mail.gnome.org/mailman/listinfo/gtk-list>
>
>
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Paul Davis
Our opinion (ardour developers) is that no desktop GUI toolkit is appropriate for plugins.

We were distressed to see Steinberg use gtkmm for this purpose (even though we use gtkmm for ardour).

Plugins do not need to use the same toolkit as the host.

We have no plans to add VST3 support at any time in the near future, on any platform.


On Thu, Sep 28, 2017 at 2:06 PM, René Hansen <[hidden email]> wrote:
Hey Paul,

thanks for your remark. Since Steinberg released the technical preview of VST3 with Linux support, I try to port my synthesizer. The SDK contains a tiny host called EditorHost. It simply opens up the GUI editor of a plug-in. The host uses gtkmm (like my plug-in) and passes the socket_id resp. the window id to the plug-in.

Until I switched to Ubuntu 17.04 everything was running smooth already. Unfortunately it started flickering.

So, in case of Ardour the plug-in has to use gtkmm for building its GUI, right? Using another GUI framework is not possible.

OT: Any plans of having VST3 in Ardour for Linux?

René

On <a href="tel:26.09.2017%2020" value="+12609201720" target="_blank">26.09.2017 20:13, Paul Davis wrote:
For whatever it's worth, I was working on a similar plugin situation 16 years ago.  I tried using plug+socket. Couldn't make it work. GTK+ developers at the time told me to stop using it.

We now get a Gtk::Widget* from a plugin and add that to our own Gtk::Window.

On Tue, Sep 26, 2017 at 1:54 PM, René Hansen <[hidden email] <mailto:[hidden email]>> wrote:

    Hey Eric,

        It looks like you are trying to paint a surface 100 times every
        16ms.
        Maybe not such a good thing to do.


    Yes, I agree but that's on purpose in order to make the problem
    *very* obvious ;) In one of my projects I draw round about 25
    bitmaps (which partly overlap) onto the drawingarea. While some
    mouse interaction takes place I need to redraw several times. This
    results in flickering of all single bitmaps almost everytime I
    redraw. It looks as if the drawingarea gets cleared before I finish
    drawing my bitmaps.

    > The plug and socket are separate programs. You would start your socket
    > and add one or more plugs to it. Each plug is running as it's own
    > process.

    Yes, that's correct. But in the documentation of Gtk::Socket::add_id
    it says:
    "Adds an XEMBED client, such as a Gtk::Plug, to the Gtk::Socket.
    The client may be in the same process or in a different process."

    So I am of the assumption that both is possible. Either Socket and
    Plug live in the same process or different processes. Is that correct?

    Some details about my real world project (I hope it is not too
    confusing). I have a host application (executable) which builds its
    GUI with Gtk. Then I have a plug-in (shared object resp. .so file)
    which also builds its GUI with Gtk. But the plug-ins GUI must be
    shown by embedding it into the host application (like x11 is capable
    of). So I pass the socket_id of the host to the plug-in so it can
    connect by creating a plug. The plug-in lives inside the host
    application's process. But it is also possible that the host creates
    an extra process to let the plug-in run, but still, the GUI must be
    shown inside the host application. Both scenarios are possible.

    > There is some socket and plug test code at the following.
    ...
    > I just added a frame clock to the plug. If you are looking to animate a drawing in a plug that might be of some help.

    Thanks! I will have closer look and try to figure out how this works.

    > If you are programming in C++, the gtkmm tutorial is very good.

    Yes, I know this one, built it and let it run successfully. No
    flickering. Afterwards I extended this example by having both socket
    and plug in the same process. I added some idle call to the plug and
    let it draw a bunch of bitmaps. It started flickering. Then I
    removed all the gtkmm stuff in order to have plain Gtk code. And
    this is the example I have put on my github ;)

    Thanks for help. I will study your "plug2.c" example and see what I
    will come up with.


    René
    _______________________________________________
    gtk-list mailing list
    [hidden email] <mailto:[hidden email]>
    https://mail.gnome.org/mailman/listinfo/gtk-list
    <https://mail.gnome.org/mailman/listinfo/gtk-list>




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list
In reply to this post by René Hansen

It looks like a bug in GTK but I haven't figured out what is causing it. A bug report in bugzilla would be good. Maybe someone can pinpoint the cause of the flicker better than I can.

Looking around it looks like the GtkPlug and GtkSocket never got deprecated but I don't see them in the master branch anymore.

Eric




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
You are right!

 > Looking around it looks like the GtkPlug and GtkSocket never got
 > deprecated but I don't see them in the master branch anymore.

Look at this commit:
https://git.gnome.org/browse/gtk+/commit/?id=021fe010b6cbf5119938efbad3122ef2854fc62b

and this article:
https://www.phoronix.com/scan.php?page=news_item&px=GTK4-Cleaning-House-100

 > A bug report in bugzilla would be good. Maybe someone can pinpoint the
 > cause of the flicker better than I can.

Does it make sense at all to report a bug when GtkSocket and GtkPlug are
already deprecated/old and even have been removed? I fear chances are
low that it will ever get fixed.

René

On 28.09.2017 20:54, [hidden email] wrote:

>
> It looks like a bug in GTK but I haven't figured out what is causing it.
> A bug report in bugzilla would be good. Maybe someone can pinpoint the
> cause of the flicker better than I can.
>
> Looking around it looks like the GtkPlug and GtkSocket never got
> deprecated but I don't see them in the master branch anymore.
>
> Eric
>
>
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list

If the GtkSocket and GtkPlug can be fixed they should be. They have worked at least through version 3.18 and have never been deprecated. It would be a good thing if they worked for all of GTK3 and the last stable version of 3.22 for consistency.

It looks like it has something to do with double buffering but I haven't been able to figure the problem out or find a work around.

Eric

_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
 > If the GtkSocket and GtkPlug can be fixed they should be. They have
 > worked at least through version 3.18 and have never been deprecated. It
 > would be a good thing if they worked for all of GTK3 and the last stable
 > version of 3.22 for consistency.

Ok, I've reported the bug here:
https://bugzilla.gnome.org/show_bug.cgi?id=788367
Anything I can improve in the report or add more information?

I wonder if there will be a replacement for GtkSocket and GtkPlug in Gtk4.

 > It looks like it has something to do with double buffering but I haven't
 > been able to figure the problem out or find a work around.

This was my very first assumption as well. I tried many things actually
before posting on the gtk-list. But I have not found a workaround. I've
also created my own double buffering by drawing into an offscreen image
and afterwards painting it. But even painting this single image resulted
in flickering, at least less often.

René
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list

Hi Rene,

I usually just test on ubuntu16.04 with GTK3.18. Now you have me checking a few things with GTK3.22. I have been working on a small drawing program that doesn't use sockets or plugs and it does the same flickering on GTK3.22 especially with animation but it works fine with GTK3.18.

https://github.com/cecashon/OrderedSetVelociRaptor/blob/master/Misc/cairo_drawings/bezier_points1.c

Good that you filed a bug report. I think that the flickering may affect more than just the plug and socket.

Eric




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

René Hansen
Hey Eric,

 > I usually just test on ubuntu16.04 with GTK3.18. Now you have me
 > checking a few things with GTK3.22. I have been working on a small
 > drawing program that doesn't use sockets or plugs and it does the same
 > flickering on GTK3.22 especially with animation but it works fine with
 > GTK3.18.

I've just built (on Ubuntu 17.04) and checked your "Smooth Artist" app.
I cannot make it flicker neither on Ubuntu 17.04 nor on 16.04. What do
you do in order to make it flicker?

René
_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: Flickering with Socket and Plug

Gtk+ - General mailing list

Well, that is interesting. It flickers for me when I rotate the drawing with the frame clock on GTK3.22. Maybe it is just my slow computer. It works well with GTK3.18 though.

With the socket_plug1.c drawing the flickering gets worse the farther "down" in the drawing so I figured it is being single buffered somehow. Really though, I just don't know. I looked at some clock drawings that I have in a simple clock widget and I get some flickering there also in GTK3.22 so there is a difference in drawing somewhere.

Eric




_______________________________________________
gtk-list mailing list
[hidden email]
https://mail.gnome.org/mailman/listinfo/gtk-list