Web lists-archives.com

Re: Flickering with Socket and Plug





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
gtk-list@xxxxxxxxx
https://mail.gnome.org/mailman/listinfo/gtk-list