How to create a gbm buffer under X.

To create a GBM buffer you first need to create a drm device and then use its device descriptor to create a gbm device. To do this under X you need a way to tell xserver which device you use to avoid permission issues. Here’s an example where I create a gbm buffer under X and then authenticate to the X server:

int fd = -1;
static struct gbm_device *gbm_dev;
struct gbm_bo *bo;

int main() {

/* 
   create an SDL2 window (gles2 context)
   you probably don't need all these attributes, depends on the project
*/

SDL_Window *win;
SDL_GLContext ctx;
if(SDL_Init(SDL_INIT_VIDEO) == -1) {
	fprintf(stderr, "failed to initialize sdl\n");
	return 1;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_EGL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
win = SDL_CreateWindow("foo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
         640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if(!win) {
	fprintf(stderr, "failed to create window: %s\n", SDL_GetError());
	return 1;
}
if(!(ctx = SDL_GL_CreateContext(win))) {
	fprintf(stderr, "failed to create OpenGL context: %s\n", SDL_GetError());
	return 1;
}

/* open the drm device */

if((fd = drm_open_matching("*:*", 0)) < 0) {
        fprintf(stderr, "can't open device: %s\n", strerror(errno));
	return 1;
}

/* do some magic */

drm_magic_t magic;
if(drmGetMagic(fd, &magic) == -1) {
	fprintf(stderr, "failed to get magic\n");
	return 1;
}

/* get the SDL window info that is needed for the authentication */

SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version);
if(!SDL_GetWindowWMInfo(win, &wminfo)) {
	fprintf(stderr, "failed to get window-system info from SDL\n");
	return 1;
}

/* perform the authentication using libxcb which has an 1 by 1 match 
between xserver events/responses and c api */

xcb_connection_t *xcbconn = XGetXCBConnection(wminfo.info.x11.display);
assert(xcbconn);
xcb_dri2_authenticate_cookie_t cookie;
cookie = xcb_dri2_authenticate(xcbconn, wminfo.info.x11.window, magic);
xcb_dri2_authenticate_reply_t *authreply;
xcb_generic_error_t *err;
authreply = xcb_dri2_authenticate_reply(xcbconn, cookie, &err);
if(err) {
	fprintf(stderr, "some xcb error ...\n");
	return 1;
}
printf("got xcb_dri2_authenticate_reply back: %u\n", 
       (unsigned int)authreply->authenticated);

/* create the gbm buffer */

if(!(gbm_dev = gbm_create_device(fd))) {
	fprintf(stderr, "can't create gbm device: %s\n", strerror(errno));
	return 1;
}
if(!(bo = gbm_bo_create(gbm_dev, 640, 480, GBM_BO_FORMAT_XRGB8888, 
        GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING))) {
	fprintf(stderr, "Unable to create gbm buffer object!\n");
	return 1;
}
printf("created gbm buffer\n");

/* rest of the program.. have fun! ;-)p */
...

}
Advertisements

2 thoughts on “How to create a gbm buffer under X.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s