Slow rendering when GC.line_style = LineOnOffDash

Farrington, Paul Paul.Farrington at fisglobal.com
Sat Dec 3 02:53:09 UTC 2022


Hi,

We’ve noticed that XDrawRectangle where the GC.line_style is LineOnOffDash has gotten slower in recent X Server releases. We’ve observed this on both Linux RH8 and FBSD 11.4 and above. There are two sample programs pasted below, one which draws 5 rectangles with LineSolid and one which draws 5 rectangles with LineOnOffDash. There is also a makefile for RH8. Running the two programs with an X Server version 1.18.4, both programs render the rectangles instantly. But in X Server version 1.20.8 or more obviously 1.20.14, rendering the dashed line rectangles is much slower. You can watch them being drawn on the screen, whereas the solid line version still renders instantly.

Is there some other attribute that needs to be set when using LineOnOffDash? Or is this a bug?

Thanks to https://rosettacode.org/wiki/Window_creation/X11 for the example “hello world” program.

The only difference between hello-x.c and hello-fast.c is whether we use “dashGC” or “gc” in the first five calls to XDrawRectangle.

Source file #1: hello-x.c

#include <X11/Xlib.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/time.h>



GC getSolidGC(Display *d, Window w);

GC getDashGC(Display *d, Window w);



int main(void) {

   Display *d;

   Window w;

   XEvent e;

   const char *msg = "Hello, World!";

   int s;



   d = XOpenDisplay(NULL);

   if (d == NULL) {

      fprintf(stderr, "Cannot open display\n");

      exit(1);

   }



   s = DefaultScreen(d);

   w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 500, 500, 1,

                           BlackPixel(d, s), WhitePixel(d, s));

   XSelectInput(d, w, ExposureMask | KeyPressMask);

   XMapWindow(d, w);



   GC gc = getSolidGC(d, w);



   if (!gc)

    msg = "no GC";

   else

   {

        msg = "there is a GC";

   }



   int border = 2;

   int x = 20;

   int y = 20;

   int dx = 400;

   int dy = 200;



   while (1) {

      XNextEvent(d, &e);

      if (e.type == Expose) {

        if (border)

        {

            int origX = x;

            int origY = y;

            int origDX = dx;

            int newDY = dy/8;



            GC dashGC = getDashGC(d, w);

            XDrawRectangle(d, w, dashGC, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, dashGC, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, dashGC, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, dashGC, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, dashGC, origX, origY, origDX, newDY);



            while (border-- > 0)

            {

                XDrawRectangle(d, w, gc, x, y, dx, dy);

                x++;

                y++;

                dx -= 2;

                dy -= 2;

            }

        }

        else

            XFillRectangle(d, w, gc, x, y, dx, dy);

         XDrawString(d, w, gc, 10, 400, msg, strlen(msg));

      }

      if (e.type == KeyPress)

         break;

   }



   XCloseDisplay(d);

   return 0;

}



GC getSolidGC(Display *d, Window w)

{

    XColor exact, color;

    int scr = DefaultScreen(d);

    XAllocNamedColor(d, DefaultColormap(d, scr), "magenta", &exact, &color);

    /* XAllocNamedColor(d, DefaultColormap(d, scr), "red", &exact, &color); */

    unsigned long gcmask = 0;

    XGCValues xgcv;

    xgcv.plane_mask = ~color.pixel;

    xgcv.function = GXclear;

    gcmask |= (GCPlaneMask|GCFunction);



    xgcv.line_style = LineSolid;

    gcmask |= GCLineStyle;



    GC gc = XCreateGC(d, w, gcmask, &xgcv);

    return gc;

}



GC getDashGC(Display *d, Window w)

{

    XColor exact, color;

    int scr = DefaultScreen(d);

    XAllocNamedColor(d, DefaultColormap(d, scr), "magenta", &exact, &color);

    /* XAllocNamedColor(d, DefaultColormap(d, scr), "red", &exact, &color); */

    unsigned long gcmask = 0;

    XGCValues xgcv;

    xgcv.plane_mask = ~color.pixel;

    xgcv.function = GXclear;

    gcmask |= (GCPlaneMask|GCFunction);



    xgcv.line_style = LineOnOffDash;

    gcmask |= GCLineStyle;



    GC gc = XCreateGC(d, w, gcmask, &xgcv);

    return gc;

}




Source file #2: hello-fast.c

#include <X11/Xlib.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/time.h>



GC getSolidGC(Display *d, Window w);

GC getDashGC(Display *d, Window w);



int main(void) {

   Display *d;

   Window w;

   XEvent e;

   const char *msg = "Hello, World!";

   int s;



   d = XOpenDisplay(NULL);

   if (d == NULL) {

      fprintf(stderr, "Cannot open display\n");

      exit(1);

   }



   s = DefaultScreen(d);

   w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 500, 500, 1,

                           BlackPixel(d, s), WhitePixel(d, s));

   XSelectInput(d, w, ExposureMask | KeyPressMask);

   XMapWindow(d, w);



   GC gc = getSolidGC(d, w);



   if (!gc)

    msg = "no GC";

   else

   {

        msg = "there is a GC";

   }



   int border = 2;

   int x = 20;

   int y = 20;

   int dx = 400;

   int dy = 200;



   while (1) {

      XNextEvent(d, &e);

      if (e.type == Expose) {

        if (border)

        {

            int origX = x;

            int origY = y;

            int origDX = dx;

            int newDY = dy/8;



            GC dashGC = getDashGC(d, w);

            XDrawRectangle(d, w, gc, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, gc, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, gc, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, gc, origX, origY, origDX, newDY);

            origY += (newDY+10);

            XDrawRectangle(d, w, gc, origX, origY, origDX, newDY);



            while (border-- > 0)

            {

                XDrawRectangle(d, w, gc, x, y, dx, dy);

                x++;

                y++;

                dx -= 2;

                dy -= 2;

            }

        }

        else

            XFillRectangle(d, w, gc, x, y, dx, dy);

         XDrawString(d, w, gc, 10, 400, msg, strlen(msg));

      }

      if (e.type == KeyPress)

         break;

   }



   XCloseDisplay(d);

   return 0;

}



GC getSolidGC(Display *d, Window w)

{

    XColor exact, color;

    int scr = DefaultScreen(d);

    XAllocNamedColor(d, DefaultColormap(d, scr), "magenta", &exact, &color);

    unsigned long gcmask = 0;

    XGCValues xgcv;

    xgcv.plane_mask = ~color.pixel;

    xgcv.function = GXclear;

    gcmask |= (GCPlaneMask|GCFunction);



    xgcv.line_style = LineSolid;

    gcmask |= GCLineStyle;



    GC gc = XCreateGC(d, w, gcmask, &xgcv);

    return gc;

}



GC getDashGC(Display *d, Window w)

{

    XColor exact, color;

    int scr = DefaultScreen(d);

    XAllocNamedColor(d, DefaultColormap(d, scr), "magenta", &exact, &color);

    unsigned long gcmask = 0;

    XGCValues xgcv;

    xgcv.plane_mask = ~color.pixel;

    xgcv.function = GXclear;

    gcmask |= (GCPlaneMask|GCFunction);



    xgcv.line_style = LineOnOffDash;

    gcmask |= GCLineStyle;



    GC gc = XCreateGC(d, w, gcmask, &xgcv);

    return gc;

}


Here’s a makefile that will work on Red Hat 8:

default:

    g++ hello-x.c -I/usr/local/include\

   /usr/lib64/libXmu.so \

    /usr/lib64/libXext.so \

    /usr/lib64/libXt.so \

    /usr/lib64/libX11.so \

         -o hello-x

    g++ hello-fast.c -I/usr/local/include\

   /usr/lib64/libXmu.so \

    /usr/lib64/libXext.so \

    /usr/lib64/libXt.so \

    /usr/lib64/libX11.so \

         -o hello-fast


Thanks,
- Paul

Paul Farrington
E:  paul.farrington at fisglobal.com<mailto:paul.farrington at fisglobal.com>

The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.x.org/archives/xorg/attachments/20221203/c77415c9/attachment-0001.htm>


More information about the xorg mailing list