00001
00002 #include <assert.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <stdio.h>
00006 #include <stdint.h>
00007
00008 #include "eglconfig.h"
00009 #include "eglcontext.h"
00010 #include "egldisplay.h"
00011 #include "egldriver.h"
00012 #include "eglglobals.h"
00013 #include "eglmode.h"
00014 #include "eglscreen.h"
00015 #include "eglsurface.h"
00016 #include "egllog.h"
00017
00018 #include "intel_egl.h"
00019
00020 #include "xf86drm.h"
00021 #include "xf86drmMode.h"
00022
00023 #include "intel_context.h"
00024
00025 #include "state_tracker/st_public.h"
00026
00027 #define MAX_SCREENS 16
00028
00029 static void
00030 drm_get_device_id(struct egl_drm_device *device)
00031 {
00032 char path[512];
00033 FILE *file;
00034
00035
00036 int minor = 0;
00037
00038 snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
00039 file = fopen(path, "r");
00040 if (!file) {
00041 _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
00042 return;
00043 }
00044
00045 fgets(path, sizeof( path ), file);
00046 sscanf(path, "%x", &device->deviceID);
00047 fclose(file);
00048 }
00049
00050 static struct egl_drm_device*
00051 egl_drm_create_device(int drmFD)
00052 {
00053 struct egl_drm_device *device = malloc(sizeof(*device));
00054 memset(device, 0, sizeof(*device));
00055 device->drmFD = drmFD;
00056
00057 device->version = drmGetVersion(device->drmFD);
00058
00059 drm_get_device_id(device);
00060
00061 if (!intel_create_device(device)) {
00062 free(device);
00063 return NULL;
00064 }
00065
00066 return device;
00067 }
00068
00069 static void
00070 _egl_context_modes_destroy(__GLcontextModes *modes)
00071 {
00072 _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
00073
00074 while (modes) {
00075 __GLcontextModes * const next = modes->next;
00076 free(modes);
00077 modes = next;
00078 }
00079 }
00085 static __GLcontextModes *
00086 _egl_context_modes_create(unsigned count, size_t minimum_size)
00087 {
00088
00089 const size_t size = (minimum_size > sizeof(__GLcontextModes))
00090 ? minimum_size : sizeof(__GLcontextModes);
00091 __GLcontextModes * head = NULL;
00092 __GLcontextModes ** next;
00093 unsigned i;
00094
00095 _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
00096
00097 next = & head;
00098 for (i = 0 ; i < count ; i++) {
00099 *next = (__GLcontextModes *) calloc(1, size);
00100 if (*next == NULL) {
00101 _egl_context_modes_destroy(head);
00102 head = NULL;
00103 break;
00104 }
00105
00106 (*next)->doubleBufferMode = 1;
00107 (*next)->visualID = GLX_DONT_CARE;
00108 (*next)->visualType = GLX_DONT_CARE;
00109 (*next)->visualRating = GLX_NONE;
00110 (*next)->transparentPixel = GLX_NONE;
00111 (*next)->transparentRed = GLX_DONT_CARE;
00112 (*next)->transparentGreen = GLX_DONT_CARE;
00113 (*next)->transparentBlue = GLX_DONT_CARE;
00114 (*next)->transparentAlpha = GLX_DONT_CARE;
00115 (*next)->transparentIndex = GLX_DONT_CARE;
00116 (*next)->xRenderable = GLX_DONT_CARE;
00117 (*next)->fbconfigID = GLX_DONT_CARE;
00118 (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
00119 (*next)->bindToTextureRgb = GLX_DONT_CARE;
00120 (*next)->bindToTextureRgba = GLX_DONT_CARE;
00121 (*next)->bindToMipmapTexture = GLX_DONT_CARE;
00122 (*next)->bindToTextureTargets = 0;
00123 (*next)->yInverted = GLX_DONT_CARE;
00124
00125 next = & ((*next)->next);
00126 }
00127
00128 return head;
00129 }
00130
00131 struct drm_screen;
00132
00133 struct drm_driver
00134 {
00135 _EGLDriver base;
00136
00137 drmModeResPtr res;
00138
00139 struct drm_screen *screens[MAX_SCREENS];
00140 size_t count_screens;
00141
00142 struct egl_drm_device *device;
00143 };
00144
00145 struct drm_surface
00146 {
00147 _EGLSurface base;
00148
00149 struct egl_drm_drawable *drawable;
00150 };
00151
00152 struct drm_context
00153 {
00154 _EGLContext base;
00155
00156 struct egl_drm_context *context;
00157 };
00158
00159 struct drm_screen
00160 {
00161 _EGLScreen base;
00162
00163
00164 drmModeConnectorPtr connector;
00165
00166
00167 int shown;
00168
00169
00170 struct drm_surface *surf;
00171
00172
00173 drmBO buffer;
00174
00175
00176 drmModeFBPtr fb;
00177 uint32_t fbID;
00178
00179
00180 drmModeCrtcPtr crtc;
00181 uint32_t crtcID;
00182
00183 struct drm_mode_modeinfo *mode;
00184
00185
00186 struct egl_drm_frontbuffer front;
00187 };
00188
00189 static void
00190 drm_update_res(struct drm_driver *drm_drv)
00191 {
00192 drmModeFreeResources(drm_drv->res);
00193 drm_drv->res = drmModeGetResources(drm_drv->device->drmFD);
00194 }
00195
00196 static void
00197 drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
00198 {
00199 struct drm_mode_modeinfo *m;
00200 int i;
00201
00202 for (i = 0; i < connector->count_modes; i++) {
00203 m = &connector->modes[i];
00204 _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
00205 }
00206 }
00207
00208
00209 static EGLBoolean
00210 drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
00211 {
00212 _EGLDisplay *disp = _eglLookupDisplay(dpy);
00213 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00214 struct drm_screen *screen = NULL;
00215 drmModeConnectorPtr connector = NULL;
00216 drmModeResPtr res = NULL;
00217 unsigned count_connectors = 0;
00218 int num_screens = 0;
00219
00220 EGLint i;
00221 int fd;
00222
00223 fd = drmOpen("i915", NULL);
00224 if (fd < 0) {
00225 return EGL_FALSE;
00226 }
00227
00228 drm_drv->device = egl_drm_create_device(fd);
00229 if (!drm_drv->device) {
00230 drmClose(fd);
00231 return EGL_FALSE;
00232 }
00233
00234 drm_update_res(drm_drv);
00235 res = drm_drv->res;
00236 if (res)
00237 count_connectors = res->count_connectors;
00238
00239 for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
00240 connector = drmModeGetConnector(fd, res->connectors[i]);
00241
00242 if (!connector)
00243 continue;
00244
00245 if (connector->connection != DRM_MODE_CONNECTED) {
00246 drmModeFreeConnector(connector);
00247 continue;
00248 }
00249
00250 screen = malloc(sizeof(struct drm_screen));
00251 memset(screen, 0, sizeof(*screen));
00252 screen->connector = connector;
00253 _eglInitScreen(&screen->base);
00254 _eglAddScreen(disp, &screen->base);
00255 drm_add_modes_from_connector(&screen->base, connector);
00256 drm_drv->screens[num_screens++] = screen;
00257 }
00258 drm_drv->count_screens = num_screens;
00259
00260
00261 _EGLConfig *config = calloc(1, sizeof(*config));
00262 memset(config, 1, sizeof(*config));
00263 _eglInitConfig(config, 1);
00264 _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
00265 _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
00266 _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
00267 _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
00268 _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
00269 _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
00270 _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
00271 _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
00272 _eglAddConfig(disp, config);
00273
00274 drv->Initialized = EGL_TRUE;
00275
00276 *major = 1;
00277 *minor = 4;
00278
00279 return EGL_TRUE;
00280 }
00281
00282 static void
00283 drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
00284 {
00285 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00286 unsigned int i;
00287
00288 intel_bind_frontbuffer(screen->surf->drawable, NULL);
00289 screen->surf = NULL;
00290
00291 for (i = 0; i < drm_drv->res->count_crtcs; i++) {
00292 drmModeSetCrtc(
00293 drm_drv->device->drmFD,
00294 drm_drv->res->crtcs[i],
00295 0,
00296 0, 0,
00297 NULL, 0,
00298 NULL);
00299 }
00300
00301 drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
00302 drmModeFreeFB(screen->fb);
00303 screen->fb = NULL;
00304
00305 drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
00306
00307 screen->shown = 0;
00308 }
00309
00310 static EGLBoolean
00311 drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
00312 {
00313 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00314 struct drm_screen *screen;
00315 int i = 0;
00316
00317 intel_destroy_device(drm_drv->device);
00318 drmFreeVersion(drm_drv->device->version);
00319
00320 for (i = 0; i < drm_drv->count_screens; i++) {
00321 screen = drm_drv->screens[i];
00322
00323 if (screen->shown)
00324 drm_takedown_shown_screen(drv, screen);
00325
00326 drmModeFreeConnector(screen->connector);
00327 _eglDestroyScreen(&screen->base);
00328 drm_drv->screens[i] = NULL;
00329 }
00330
00331 drmClose(drm_drv->device->drmFD);
00332
00333 free(drm_drv->device);
00334
00335 _eglCleanupDisplay(_eglLookupDisplay(dpy));
00336 free(drm_drv);
00337
00338 return EGL_TRUE;
00339 }
00340
00341
00342 static struct drm_context *
00343 lookup_drm_context(EGLContext context)
00344 {
00345 _EGLContext *c = _eglLookupContext(context);
00346 return (struct drm_context *) c;
00347 }
00348
00349
00350 static struct drm_surface *
00351 lookup_drm_surface(EGLSurface surface)
00352 {
00353 _EGLSurface *s = _eglLookupSurface(surface);
00354 return (struct drm_surface *) s;
00355 }
00356
00357 static struct drm_screen *
00358 lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
00359 {
00360 _EGLScreen *s = _eglLookupScreen(dpy, screen);
00361 return (struct drm_screen *) s;
00362 }
00363
00364 static __GLcontextModes*
00365 visual_from_config(_EGLConfig *conf)
00366 {
00367 __GLcontextModes *visual;
00368 (void)conf;
00369
00370 visual = _egl_context_modes_create(1, sizeof(*visual));
00371 visual->redBits = 8;
00372 visual->greenBits = 8;
00373 visual->blueBits = 8;
00374 visual->alphaBits = 8;
00375
00376 visual->rgbBits = 32;
00377 visual->doubleBufferMode = 1;
00378
00379 visual->depthBits = 24;
00380 visual->haveDepthBuffer = visual->depthBits > 0;
00381 visual->stencilBits = 8;
00382 visual->haveStencilBuffer = visual->stencilBits > 0;
00383
00384 return visual;
00385 }
00386
00387
00388
00389 static EGLContext
00390 drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
00391 {
00392 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00393 struct drm_context *c;
00394 struct drm_egl_context *share = NULL;
00395 _EGLConfig *conf;
00396 int i;
00397 int ret;
00398 __GLcontextModes *visual;
00399 struct egl_drm_context *context;
00400
00401 conf = _eglLookupConfig(drv, dpy, config);
00402 if (!conf) {
00403 _eglError(EGL_BAD_CONFIG, "eglCreateContext");
00404 return EGL_NO_CONTEXT;
00405 }
00406
00407 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
00408 switch (attrib_list[i]) {
00409
00410 default:
00411 _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
00412 return EGL_NO_CONTEXT;
00413 }
00414 }
00415
00416 c = (struct drm_context *) calloc(1, sizeof(struct drm_context));
00417 if (!c)
00418 return EGL_NO_CONTEXT;
00419
00420 _eglInitContext(drv, dpy, &c->base, config, attrib_list);
00421
00422 context = malloc(sizeof(*context));
00423 memset(context, 0, sizeof(*context));
00424
00425 if (!context)
00426 goto err_c;
00427
00428 context->device = drm_drv->device;
00429 visual = visual_from_config(conf);
00430
00431 ret = intel_create_context(context, visual, share);
00432 free(visual);
00433
00434 if (!ret)
00435 goto err_gl;
00436
00437 c->context = context;
00438
00439
00440 _eglSaveContext(&c->base);
00441 assert(_eglGetContextHandle(&c->base));
00442
00443 return _eglGetContextHandle(&c->base);
00444 err_gl:
00445 free(context);
00446 err_c:
00447 free(c);
00448 return EGL_NO_CONTEXT;
00449 }
00450
00451 static EGLBoolean
00452 drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
00453 {
00454 struct drm_context *fc = lookup_drm_context(context);
00455 _eglRemoveContext(&fc->base);
00456 if (fc->base.IsBound) {
00457 fc->base.DeletePending = EGL_TRUE;
00458 } else {
00459 intel_destroy_context(fc->context);
00460 free(fc->context);
00461 free(fc);
00462 }
00463 return EGL_TRUE;
00464 }
00465
00466
00467 static EGLSurface
00468 drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
00469 {
00470 return EGL_NO_SURFACE;
00471 }
00472
00473
00474 static EGLSurface
00475 drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
00476 {
00477 return EGL_NO_SURFACE;
00478 }
00479
00480
00481 static EGLSurface
00482 drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
00483 const EGLint *attrib_list)
00484 {
00485 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00486 int i;
00487 int ret;
00488 int width = -1;
00489 int height = -1;
00490 struct drm_surface *surf = NULL;
00491 struct egl_drm_drawable *drawable = NULL;
00492 __GLcontextModes *visual;
00493 _EGLConfig *conf;
00494
00495 conf = _eglLookupConfig(drv, dpy, config);
00496 if (!conf) {
00497 _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
00498 return EGL_NO_CONTEXT;
00499 }
00500
00501 for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
00502 switch (attrib_list[i]) {
00503 case EGL_WIDTH:
00504 width = attrib_list[++i];
00505 break;
00506 case EGL_HEIGHT:
00507 height = attrib_list[++i];
00508 break;
00509 default:
00510 _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
00511 return EGL_NO_SURFACE;
00512 }
00513 }
00514
00515 if (width < 1 || height < 1) {
00516 _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
00517 return EGL_NO_SURFACE;
00518 }
00519
00520 surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
00521 if (!surf)
00522 goto err;
00523
00524 if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
00525 goto err_surf;
00526
00527 drawable = malloc(sizeof(*drawable));
00528 memset(drawable, 0, sizeof(*drawable));
00529
00530 drawable->w = width;
00531 drawable->h = height;
00532
00533 visual = visual_from_config(conf);
00534
00535 drawable->device = drm_drv->device;
00536 ret = intel_create_drawable(drawable, visual);
00537 free(visual);
00538
00539 if (!ret)
00540 goto err_draw;
00541
00542 surf->drawable = drawable;
00543
00544 _eglSaveSurface(&surf->base);
00545 return surf->base.Handle;
00546
00547 err_draw:
00548 free(drawable);
00549 err_surf:
00550 free(surf);
00551 err:
00552 return EGL_NO_SURFACE;
00553 }
00554
00555 static EGLSurface
00556 drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
00557 const EGLint *attrib_list)
00558 {
00559 EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
00560
00561 return surf;
00562 }
00563
00564 static struct drm_mode_modeinfo *
00565 drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
00566 {
00567 int i;
00568 struct drm_mode_modeinfo *m;
00569
00570 for (i = 0; i < connector->count_modes; i++) {
00571 m = &connector->modes[i];
00572 if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
00573 break;
00574 m = &connector->modes[0];
00575 }
00576
00577 return m;
00578 }
00579 static void
00580 draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr)
00581 {
00582 int i, j;
00583
00584 for (i = x; i < x + w; i++)
00585 for(j = y; j < y + h; j++)
00586 ptr[(i * pitch / 4) + j] = v;
00587
00588 }
00589
00590 static void
00591 prettyColors(int fd, unsigned int handle, size_t pitch)
00592 {
00593 drmBO bo;
00594 unsigned int *ptr;
00595 void *p;
00596 int i;
00597
00598 drmBOReference(fd, handle, &bo);
00599 drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p);
00600 ptr = (unsigned int*)p;
00601
00602 for (i = 0; i < (bo.size / 4); i++)
00603 ptr[i] = 0xFFFFFFFF;
00604
00605 for (i = 0; i < 4; i++)
00606 draw(i * 40, i * 40, 40, 40, pitch, 0, ptr);
00607
00608
00609 draw(200, 100, 40, 40, pitch, 0xff00ff, ptr);
00610 draw(100, 200, 40, 40, pitch, 0xff00ff, ptr);
00611
00612 drmBOUnmap(fd, &bo);
00613 }
00614
00615 static EGLBoolean
00616 drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
00617 EGLScreenMESA screen,
00618 EGLSurface surface, EGLModeMESA m)
00619 {
00620 struct drm_driver *drm_drv = (struct drm_driver *)drv;
00621 struct drm_surface *surf = lookup_drm_surface(surface);
00622 struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
00623 _EGLMode *mode = _eglLookupMode(dpy, m);
00624 size_t pitch = mode->Width * 4;
00625 size_t size = mode->Height * pitch;
00626 int ret;
00627 unsigned int i,j,k;
00628
00629 if (scrn->shown)
00630 drm_takedown_shown_screen(drv, scrn);
00631
00632 ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
00633 DRM_BO_FLAG_READ |
00634 DRM_BO_FLAG_WRITE |
00635 DRM_BO_FLAG_MEM_TT |
00636 DRM_BO_FLAG_MEM_VRAM |
00637 DRM_BO_FLAG_NO_EVICT,
00638 DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
00639
00640 if (ret)
00641 return EGL_FALSE;
00642
00643 prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
00644
00645 ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height,
00646 32, 32, pitch,
00647 scrn->buffer.handle,
00648 &scrn->fbID);
00649
00650 if (ret)
00651 goto err_bo;
00652
00653 scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID);
00654 if (!scrn->fb)
00655 goto err_bo;
00656
00657 for (j = 0; j < drm_drv->res->count_connectors; j++) {
00658 drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]);
00659 scrn->mode = drm_find_mode(con, mode);
00660 if (!scrn->mode)
00661 goto err_fb;
00662
00663 for (k = 0; k < con->count_encoders; k++) {
00664 drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]);
00665 for (i = 0; i < drm_drv->res->count_crtcs; i++) {
00666 if (enc->possible_crtcs & (1<<i)) {
00667 ret = drmModeSetCrtc(
00668 drm_drv->device->drmFD,
00669 drm_drv->res->crtcs[i],
00670 scrn->fbID,
00671 0, 0,
00672 &drm_drv->res->connectors[j], 1,
00673 scrn->mode);
00674
00675 i = drm_drv->res->count_crtcs;
00676 }
00677 }
00678 }
00679 }
00680
00681 scrn->front.handle = scrn->buffer.handle;
00682 scrn->front.pitch = pitch;
00683 scrn->front.width = mode->Width;
00684 scrn->front.height = mode->Height;
00685
00686 scrn->surf = surf;
00687 intel_bind_frontbuffer(surf->drawable, &scrn->front);
00688
00689 scrn->shown = 1;
00690
00691 return EGL_TRUE;
00692
00693 err_fb:
00694
00695
00696 err_bo:
00697 drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer);
00698 return EGL_FALSE;
00699 }
00700
00701 static EGLBoolean
00702 drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
00703 {
00704 struct drm_surface *fs = lookup_drm_surface(surface);
00705 _eglRemoveSurface(&fs->base);
00706 if (fs->base.IsBound) {
00707 fs->base.DeletePending = EGL_TRUE;
00708 } else {
00709 intel_bind_frontbuffer(fs->drawable, NULL);
00710 intel_destroy_drawable(fs->drawable);
00711 free(fs->drawable);
00712 free(fs);
00713 }
00714 return EGL_TRUE;
00715 }
00716
00717
00718 static EGLBoolean
00719 drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
00720 {
00721 struct drm_surface *readSurf = lookup_drm_surface(read);
00722 struct drm_surface *drawSurf = lookup_drm_surface(draw);
00723 struct drm_context *ctx = lookup_drm_context(context);
00724 EGLBoolean b;
00725
00726 b = _eglMakeCurrent(drv, dpy, draw, read, context);
00727 if (!b)
00728 return EGL_FALSE;
00729
00730 if (ctx) {
00731 if (!drawSurf || !readSurf)
00732 return EGL_FALSE;
00733
00734 intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
00735 } else {
00736 intel_make_current(NULL, NULL, NULL);
00737 }
00738
00739 return EGL_TRUE;
00740 }
00741
00742 static EGLBoolean
00743 drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
00744 {
00745 struct drm_surface *surf = lookup_drm_surface(draw);
00746 if (!surf)
00747 return EGL_FALSE;
00748
00749
00750 if (!_eglSwapBuffers(drv, dpy, draw))
00751 return EGL_FALSE;
00752
00753 intel_swap_buffers(surf->drawable);
00754 return EGL_TRUE;
00755 }
00756
00757
00762 _EGLDriver *
00763 _eglMain(_EGLDisplay *dpy, const char *args)
00764 {
00765 struct drm_driver *drm;
00766
00767 drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
00768 if (!drm) {
00769 return NULL;
00770 }
00771
00772
00773 _eglInitDriverFallbacks(&drm->base);
00774
00775 drm->base.API.Initialize = drm_initialize;
00776 drm->base.API.Terminate = drm_terminate;
00777 drm->base.API.CreateContext = drm_create_context;
00778 drm->base.API.MakeCurrent = drm_make_current;
00779 drm->base.API.CreateWindowSurface = drm_create_window_surface;
00780 drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
00781 drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
00782 drm->base.API.DestroySurface = drm_destroy_surface;
00783 drm->base.API.DestroyContext = drm_destroy_context;
00784 drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
00785 drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
00786 drm->base.API.SwapBuffers = drm_swap_buffers;
00787
00788 drm->base.ClientAPIsMask = EGL_OPENGL_BIT ;
00789 drm->base.Name = "DRM/Gallium";
00790
00791
00792 drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
00793 drm->base.Extensions.MESA_copy_context = EGL_TRUE;
00794
00795 return &drm->base;
00796 }