intel_egl.c

Go to the documentation of this file.
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         /* TODO get the real minor */
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    /* This code copied from libGLX, and modified */
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;  /* base class/object */
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;  /* base class/object */
00148 
00149         struct egl_drm_drawable *drawable;
00150 };
00151 
00152 struct drm_context
00153 {
00154         _EGLContext base;  /* base class/object */
00155 
00156         struct egl_drm_context *context;
00157 };
00158 
00159 struct drm_screen
00160 {
00161         _EGLScreen base;
00162 
00163         /* currently only support one connector */
00164         drmModeConnectorPtr connector;
00165 
00166         /* Has this screen been shown */
00167         int shown;
00168 
00169         /* Surface that is currently attached to this screen */
00170         struct drm_surface *surf;
00171 
00172         /* backing buffer */
00173         drmBO buffer;
00174 
00175         /* framebuffer */
00176         drmModeFBPtr fb;
00177         uint32_t fbID;
00178 
00179         /* crtc and mode used */
00180         drmModeCrtcPtr crtc;
00181         uint32_t crtcID;
00182 
00183         struct drm_mode_modeinfo *mode;
00184 
00185         /* geometry of the screen */
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         /* for now we only have one config */
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, // FD
00296                         0, 0,
00297                         NULL, 0, // List of output ids
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                         /* no attribs defined for now */
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         /* generate handle and insert into hash table */
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]; /* if we can't find one, return first */
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                                         /* skip the other crtcs now */
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         /* TODO remove fb */
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         /* error checking */
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         /* First fill in the dispatch table with defaults */
00773         _eglInitDriverFallbacks(&drm->base);
00774         /* then plug in our Drm-specific functions */
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 /*| EGL_OPENGL_ES_BIT*/;
00789         drm->base.Name = "DRM/Gallium";
00790 
00791         /* enable supported extensions */
00792         drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
00793         drm->base.Extensions.MESA_copy_context = EGL_TRUE;
00794 
00795         return &drm->base;
00796 }

Generated on Tue Sep 29 06:25:17 2009 for Gallium3D by  doxygen 1.5.4