Created
December 11, 2013 22:19
-
-
Save larsbergstrom/7919498 to your computer and use it in GitHub Desktop.
Sharing a pixmap across threads with/without separate XDisplay pointer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gcc visual.c -g -lGL -lX11 -lGLU -lpthread && ./a.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Off-thread visual | |
Creating off-thread | |
Making current off-thread | |
Making current NONE off-thread | |
Destroying off-thread | |
Re-creating glx pixmap on-thread | |
larsberg@thor:~/tmp$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Off-thread visual | |
Creating off-thread | |
Making current off-thread | |
X Error of failed request: BadPixmap (invalid Pixmap parameter) | |
Major opcode of failed request: 153 (GLX) | |
Minor opcode of failed request: 13 (X_GLXCreateGLXPixmap) | |
Resource id in failed request: 0x3a00004 | |
Serial number of failed request: 19 | |
Current serial number in output stream: 20 | |
larsberg@thor:~/tmp$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#include <pthread.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <GL/glx.h> | |
#include <GL/gl.h> | |
static int attributeList[] = {GLX_RGBA, | |
GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None}; | |
static Bool WaitForNotify(Display *d,XEvent *e,char *arg) { | |
return(e->type == MapNotify) && (e->xmap.window == (Window)arg); | |
} | |
Pixmap pix; | |
int use_separate_display = 1; | |
void *off_thread(void *main_dpy) { | |
Display *dpy; | |
XVisualInfo *vi; | |
GLXPixmap px; | |
GLXContext cx; | |
printf("Off-thread visual\n"); | |
if (use_separate_display) { | |
/* kaboom */ | |
dpy = XOpenDisplay(0); | |
} else { | |
/* works fine */ | |
dpy = (Display *)main_dpy; | |
} | |
vi = glXChooseVisual(dpy,DefaultScreen(dpy),attributeList); | |
if (vi == NULL) | |
{ | |
printf("couldn't find the visual \n"); | |
return 0; | |
} | |
/* create a GLX context */ | |
if (!(cx = glXCreateContext(dpy,vi,0,GL_FALSE))) | |
{ | |
fprintf(stderr, "glXGetContext failed!\n"); | |
return 0; | |
} | |
printf("Creating off-thread\n"); | |
px = glXCreateGLXPixmap (dpy, vi, pix); | |
printf("Making current off-thread\n"); | |
if (!(glXMakeCurrent(dpy,px,cx))) | |
{ | |
fprintf(stderr, "second glXMakeCurrent failed (pixmap)!\n"); | |
return 0; | |
} | |
printf("Making current NONE off-thread\n"); | |
if (!(glXMakeCurrent(dpy,None,None))) | |
{ | |
fprintf(stderr, "glXMakeCurrent failed (None)!\n"); | |
return 0; | |
} | |
printf("Destroying off-thread\n"); | |
glXDestroyGLXPixmap(dpy, px); | |
return 0; | |
} | |
int main(int argc,char**argv) | |
{ | |
Display *dpy; | |
XVisualInfo *vi; | |
GLXContext cx; | |
Colormap cmap; | |
XSetWindowAttributes swa; | |
Window win; | |
GLXPixmap px; | |
XEvent event; | |
GC gc; | |
XInitThreads(); | |
/* get a connection */ | |
dpy = XOpenDisplay(0); | |
/* get an appropriate visual */ | |
vi = glXChooseVisual(dpy,DefaultScreen(dpy),attributeList); | |
if (vi == NULL) | |
{ | |
printf("couldn't find the visual \n"); | |
return 0; | |
} | |
/* create a GLX context */ | |
if (!(cx = glXCreateContext(dpy,vi,0,GL_FALSE))) | |
{ | |
fprintf(stderr, "glXGetContext failed!\n"); | |
return 0; | |
} | |
/* create color map */ | |
if (!(cmap = XCreateColormap(dpy,RootWindow(dpy,vi->screen), | |
vi->visual,AllocNone))) | |
{ | |
fprintf(stderr, "XCreateColormap failed!\n"); | |
return 0; | |
} | |
/* create window */ | |
swa.colormap = cmap; | |
swa.border_pixel = 0; | |
swa.event_mask = StructureNotifyMask; | |
win = XCreateWindow(dpy,RootWindow(dpy,vi->screen),0,0,500,500,0,vi->depth, | |
InputOutput,vi->visual,CWBorderPixel|CWColormap|CWEventMask, | |
&swa); | |
XMapWindow(dpy,win); | |
XIfEvent(dpy,&event,WaitForNotify,(char*)win); | |
pix = XCreatePixmap (dpy, RootWindow(dpy, vi->screen), 500, 500, | |
vi->depth); | |
{ | |
pthread_t thread; | |
pthread_create(&thread, NULL, off_thread, (void*)dpy); | |
pthread_join(thread, NULL); | |
} | |
gc = XCreateGC (dpy, pix, 0, NULL); | |
printf("Re-creating glx pixmap on-thread\n"); | |
px = glXCreateGLXPixmap (dpy, vi, pix); | |
/* connect the context to the glx pixmap */ | |
if (!(glXMakeCurrent(dpy,px,cx))) | |
{ | |
fprintf(stderr, "glXMakeCurrent failed (pixmap)!\n"); | |
return 0; | |
} | |
glColor3f(1.0, 0.0, 0.0); | |
glClearColor (0.0, 0.0, 0.0, 0.0); | |
glClear(GL_COLOR_BUFFER_BIT); | |
glMatrixMode (GL_PROJECTION); | |
glLoadIdentity (); | |
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); | |
glBegin(GL_POLYGON); | |
glVertex2f(-0.5, -0.5); | |
glVertex2f(-0.5, 0.5); | |
glVertex2f(0.5, 0.5); | |
glVertex2f(0.5, -0.5); | |
glEnd(); | |
glFlush(); | |
glXWaitGL(); | |
XCopyArea (dpy, pix, win, gc, 0, 0, 500, 500, 0, 0); | |
XFlush(dpy); | |
sleep(5); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment