Bug 9450

Summary: extreme zoom of single line very slow in Linux
Product: cairo Reporter: David <idht4n>
Component: xlib backendAssignee: Carl Worth <cworth>
Status: RESOLVED FIXED QA Contact: cairo-bugs mailing list <cairo-bugs>
Severity: normal    
Priority: high    
Version: 1.3.9   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description David 2006-12-26 07:51:27 UTC
At high zoom levels, it takes a very long time to draw a single line.
There is a thread that discusses this on the cairo mailing list,
but I wanted to follow it up with a bug report here (the title of the
thread was "newbie clipping question").  The conclusion was that the problem
was an X bug that could be worked around in the xlib backend of cairo.

Here is some code that demonstrates the problem:

#include <stdio.h>
#include <gtk/gtk.h>
#include <sys/time.h>

#define DAREA_SIZE (50)

GtkWidget *darea;
double zoom = 3200.0;
int redrawTimeout;


gint onRedrawTimeout(gpointer data)
{
GdkRectangle rect;
rect.x = 0;
rect.y = 0;
rect.width = DAREA_SIZE;
rect.height = DAREA_SIZE;
gdk_window_invalidate_rect(darea->window,
                            &rect,
                            FALSE);
redrawTimeout = 0;
return FALSE;
}

void onExpose(double *exposeRect)
{

cairo_t *cr;
cr = gdk_cairo_create (darea->window);

cairo_rectangle (cr,
                  exposeRect[0], exposeRect[1], exposeRect[2],
                  exposeRect[3]);


cairo_clip (cr);

/* draw white background */
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, DAREA_SIZE, 0.0);
cairo_line_to(cr, DAREA_SIZE, DAREA_SIZE);
cairo_line_to(cr, 0.0, DAREA_SIZE);
cairo_close_path(cr);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_fill(cr);

/* draw line at currrent zoom level */
cairo_move_to(cr, 0.0, 0.0);
cairo_line_to(cr, 10*zoom, 10*zoom);
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_stroke(cr);

cairo_destroy (cr);
}


gint onDrawingAreaEvent(GtkWidget *item, GdkEvent *event)
{
switch (event->type) {
case GDK_EXPOSE: {
   double exposeRect[4];
   exposeRect[0] = event->expose.area.x;
   exposeRect[1] = event->expose.area.y;
   exposeRect[2] = event->expose.area.width;
   exposeRect[3] = event->expose.area.height;
   onExpose(exposeRect);
   return TRUE;
}
}
}

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

GtkWidget *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *vbox;
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add (GTK_CONTAINER(window), vbox);

darea = gtk_drawing_area_new();

gtk_box_pack_start(GTK_BOX(vbox), darea, TRUE, TRUE, 0);
gtk_widget_set_size_request (GTK_WIDGET (darea), DAREA_SIZE, DAREA_SIZE);

gtk_signal_connect(GTK_OBJECT(darea), "event",
GTK_SIGNAL_FUNC(onDrawingAreaEvent), 0);

gtk_widget_show_all(window);
gtk_main();
}
Comment 1 Chris Wilson 2008-10-08 07:56:31 UTC
We don't generate trapezoids that big any more, and we also workaround the broken Xserver.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.