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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
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 */ ... } |
[Edited:]Β To see a complete example (as asked in the comments) you can checkout this code:
1 |
hg clone https://eleni.mutantstargoat.com/hg/index.cgi/gbm-sdl2-example |
yassou!
Hi, one simple question if u dont mind.
How can I draw the allocated gbm_bo on the screen?
I’ve uploaded an example here: https://eleni.mutantstargoat.com/hg/index.cgi/gbm-sdl2-example/ (
hg clone https://eleni.mutantstargoat.com/hg/index.cgi/gbm-sdl2-example
). Check the file test.cc.Wow. Thanks so much
Welcome!
Really appreciate the help. Just one question, it seems that you create two separate OpenGL contexts. The first one is the GBM context, while the other is the OpenGL context automatically built by the SDL2. Do you assume we share resources between the two contexts?
Best
Elliott
hmm, I only create the OpenGL context from SDL2 as you say (one context). Maybe you misunderstood something in the example (?). In which line did you think I create the “gbm context”?