XGetImage takes a lot of time to run
Asked Answered
C

1

5

XGetImage takes 3-4 seconds to execute and completely freezes X11

Display *display;
    display = XOpenDisplay(NULL);
if (!display) {fprintf(stderr, "unable to connect to display");return 7;}
    Window w;
    int x,y,i;
    unsigned m;
    Window root = XDefaultRootWindow(display);
if (!root) {fprintf(stderr, "unable to open rootwindow");return 8;}
    //sleep(1);
    if(!XQueryPointer(display,root,&root,&w,&x,&y,&i,&i,&m))
{  printf("unable to query pointer\n"); return 9;}
    XImage *image;
    XWindowAttributes attr;
    XGetWindowAttributes(display, root, &attr);
    image = XGetImage(display,root,0,0,attr.width,attr.height,AllPlanes,XYPixmap);
    XCloseDisplay(display);
if (!image) {printf("unable to get image\n"); return 10;}

In the Xorg log:

[ 13234.693] AUDIT: Thu Jan  7 20:12:13 2016: 3856: client 45 connected from local host ( uid=500 gid=500 pid=12993 )
  Auth name: MIT-MAGIC-COOKIE-1 ID: 153
[ 13238.774] AUDIT: Thu Jan  7 20:12:18 2016: 3856: client 45 disconnected

time:
real    0m4.080s
user    0m0.002s
sys 0m0.007s

Ideally I want this function to run in less than 0.1 seconds

Callas answered 7/1, 2016 at 18:14 Comment(9)
You still have not tested any function return values, as recommended when you posted your previous similar questionReply
I've added some error handling to opening the display, what other functions need error handling?Callas
Until you know the source of the problem: every function that returns a value, and the values returned by pointer arguments.Reply
I've modified the code to add some error correction, let me know if additional eror correction is neededCallas
it's a bunch oif i5 laptops that cannot be change, I don't think it's slow and if it is I cannot replace it :(Callas
for understandability and readability by us humans 1) consistently indent the code. suggest using 4 space per indent level. indent after every opening brace ''{' un-indent before every closing brace '}'. 2) separate code blocks (for, if, else, while, do...while, switch, case, default) by a blank line. 3) follow the axiom: only one statement per line and (at most) one variable declaration per statement.Kite
regarding this line: if(!XQueryPointer(display,root,&root,&w,&x,&y,&i,&i,&m)). it is unlikely that the address of variable i would be passed twice to the XQueryPointer() function.Kite
You probably want ZPixmap rather than XYPixmap.Marozik
you are right, zpixmap is alot faster than xypixmap, please post that answer so I cna mark it as the correct oneCallas
M
9

XYPixmap is a very specialized format that doesn't have many uses. You should use ZPixmap nearly always.

XYPixmap works plane by plane. What does it mean? Take bit 0 of every pixel, and tightly pack all these bits in an array of unsigned int. That's youir plane 0. Then take bit 1 of every pixel, and pack all these bits in an array. That's your plane 1. Then take bit 2 of every pixel...

   Framebuffer
   __________________________________________________________________
  / 
   Pixel 0                     Pixel 1                      Pixel 2
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
    |                           |                            |
    |  +------------------------+                            |
    |  |                                                     |
    |  |  +--------------------------------------------------+
    |  |  |
    v  v  v
   [0][0][0]..... \
   (Plane 0)      |
                  |
   [1][1][1]....  | Result
   (Plane 1)      |
   ....           |
   [7][7][7]....  |
   (Plane 7)      |
                  /

If your framebuffer is stored like this, which is the case for most modern hardware, that's a lot of bit manipulation!

The picture shows 8 bit pixels, but it's the same for any other depth.

ZPixmap on the other hand takes entire pixels and stuffs them into an array:

   Framebuffer
   __________________________________________________________________
  / 
   Pixel 0                     Pixel 1                      Pixel 2
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
    |  |  |  |  |  |  |  |      |  |  |  |  |  |  |  |       |  |  |
    v  v  v  v  v  v  v  v      v  v  v  v  v  v  v  v       v  v  v
   [0][1][2][3][4][5][6][7]    [0][1][2][3][4][5][6][7]     [0][1][2]....
  \_____________________________________________________________________
    Result

This is simple direct copying, which should be very fast.

Marozik answered 22/1, 2016 at 17:20 Comment(2)
Wonderful, I've tried looking around for that sort of explanation but found none, this was very informative, thank you very muchCallas
There's such few information available on XGetImage, struct XImage, and, specially, XYPixmap, plane masks, and the like. Goodness, I had to google for an hour to find such useful information! (The man pages tell you next to nothing...)Puff

© 2022 - 2024 — McMap. All rights reserved.