Re: GDK_POINTER_MOTION_HINT_MASK has no effect



Last post on this I swear, but I thought of another simple improvement.

GTK performs expose event compression, that is, when it sends an
expose to your program, the expose is the union of all the expose
events which the window system generated since your app last saw
expose. GTK computes the smallest set of non-overlapping rectangles
which are damaged (in event->region), and also the bounding box of
that set of rectangles (in event->area).

In the code I posted previously I was just using the bounding box of
the rects. If you have a large number of images moving around, this
will usually be almost the entire display. Very inefficient! Here's a
new version of the expose handler which extracts the list of the exact
damaged areas and only repaints those. This saves about 20% CPU on my
desktop machine, and would save much more if I used small images.

-------------------------
static gboolean
expose_cb (GtkDrawingArea * area, GdkEventExpose * event, App * app)
{
  GdkRectangle *rect;
  int i, j, n;

  gdk_region_get_rectangles (event->region, &rect, &n);
  for (j = 0; j < n; j++)
    {
      for (i = 0; i < app->n; i++)
        {
          GdkRectangle repaint;

          if (gdk_rectangle_intersect (&rect[j], &app->area[i], &repaint))
            gdk_pixbuf_render_to_drawable (app->image[i],
                                           GTK_WIDGET (area)->window,
                                           GTK_WIDGET (area)->style->white_gc,
                                           repaint.x - app->area[i].x,
                                           repaint.y - app->area[i].y,
                                           repaint.x, repaint.y,
                                           repaint.width, repaint.height,
                                           GDK_RGB_DITHER_NORMAL, 0, 0);
        }

      if (app->rubber && gdk_rectangle_intersect (&rect[j], &app->box, NULL))
        gdk_draw_line (GTK_WIDGET (area)->window,
                       GTK_WIDGET (area)->style->white_gc,
                       app->x1, app->y1, app->x2, app->y2);
    }
  g_free (rect);

  return TRUE;
}
---------------------

John


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