Re: Display Raster Data?




I don't know the format, size, etc. of the images that you are working with. There are a few things that can affect the time it takes to move image data around. GTK should be able to handle the problem well though.

Try setting up a test environment with a frame counter and a timer on your image transfer function and see how long it takes. Work from there to optimize the situation. You can use a Pixbuf or a cairo image surface if you need to deal with byte copies or pixel by pixel copies. It's worth a try.

https://developer.gnome.org/gdk-pixbuf/stable/gdk-pixbuf-The-GdkPixbuf-Structure.html
https://cairographics.org/manual/cairo-Image-Surfaces.html

Eric


/*
    gcc -Wall cairo_image1.c -o cairo_image1 `pkg-config gtk+-3.0 --cflags --libs`

    Tested on Ubuntu16.04 32-bit with GTK3.18.
*/

#include<gtk/gtk.h>
#include<stdint.h>

cairo_surface_t *surface=NULL;

static gboolean animate_drawing(GtkWidget *drawing, GdkFrameClock *frame_clock, gpointer data);
static gboolean da_drawing(GtkWidget *da, cairo_t *cr, gpointer data);
static void draw_image(cairo_t *cr);

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

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Cairo Image");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    surface=cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 400, 400);

    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(da_drawing), NULL);
 
    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), da, 0, 0, 1, 1);
 
    gtk_container_add(GTK_CONTAINER(window), grid);
    gtk_widget_show_all(window);

    gtk_widget_add_tick_callback(GTK_WIDGET(da), (GtkTickCallback)animate_drawing, NULL, NULL);

    gtk_main();

    cairo_surface_destroy(surface);

    return 0;
  }
static gboolean animate_drawing(GtkWidget *da, GdkFrameClock *frame_clock, gpointer data)
  {
    //Check frame rate.
    gint64 frame=gdk_frame_clock_get_frame_counter(frame_clock);
    gint64 current_time=gdk_frame_clock_get_frame_time(frame_clock);
    gint64 start = gdk_frame_clock_get_history_start(frame_clock);
    gint64 history_len=frame-start;
    GdkFrameTimings *previous_timings=gdk_frame_clock_get_timings(frame_clock, frame-history_len);
    gint64 previous_frame_time=gdk_frame_timings_get_frame_time(previous_timings);
    g_print("Frame %i, %f fps\n", (gint)frame, (gdouble)(history_len)*G_USEC_PER_SEC/(gdouble)(current_time-previous_frame_time));

    gtk_widget_queue_draw(da);
    return G_SOURCE_CONTINUE;
  }
static gboolean da_drawing(GtkWidget *da, cairo_t *cr, gpointer data)
  {
    //Get the draw time.
    GTimer *timer=g_timer_new();
    draw_image(cr);
    g_print("Time %f\n", g_timer_elapsed(timer, NULL));
    g_timer_destroy(timer);
    return FALSE;
  }
static void draw_image(cairo_t *cr)
  {
    static gint counter=0;
    gint i=0;
    gint j=0;
    gint width=cairo_image_surface_get_width(surface);
    gint height=cairo_image_surface_get_height(surface);
    uint32_t *p1=(uint32_t*)cairo_image_surface_get_data(surface);
      
    for(i=0;i<height;i++)
      {
        for(j=0;j<width;j++)
          { 
            if(counter==i||counter==i+1) *p1=0xffff00ff;
            else *p1=0xffffffff;
            p1++;
          }                     
       }
  
    cairo_surface_mark_dirty(surface);
    cairo_set_source_surface(cr, surface, 0.0, 0.0);
    cairo_paint(cr);

    if(counter>height) counter=0;
    else counter++;
  }





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]