egl: Some per-driver data should be per-display.
[mesa.git] / src / gallium / state_trackers / egl / egl_tracker.c
index a22ef381b966a3a6ea7084d897deed7857b05b83..ced002c53593eecb111d25a8433fe9582c73c5b9 100644 (file)
@@ -21,12 +21,20 @@ extern const struct dri_extension card_extensions[];
  * Exported functions
  */
 
+static void
+drm_unload(_EGLDriver *drv)
+{
+       struct drm_device *dev = (struct drm_device *)drv;
+       dev->api->destroy(dev->api);
+       free(dev);
+}
+
 /**
  * The bootstrap function.  Return a new drm_driver object and
  * plug in API functions.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
 {
        struct drm_device *drm;
 
@@ -35,6 +43,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
                return NULL;
        }
 
+       drm->api = drm_api_create();
+
        /* First fill in the dispatch table with defaults */
        _eglInitDriverFallbacks(&drm->base);
        /* then plug in our Drm-specific functions */
@@ -51,12 +61,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
        drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
        drm->base.API.SwapBuffers = drm_swap_buffers;
 
-       drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
        drm->base.Name = "DRM/Gallium/Win";
-
-       /* enable supported extensions */
-       drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
-       drm->base.Extensions.MESA_copy_context = EGL_TRUE;
+       drm->base.Unload = drm_unload;
 
        return &drm->base;
 }
@@ -66,10 +72,13 @@ drm_get_device_id(struct drm_device *device)
 {
        char path[512];
        FILE *file;
+       char *ret;
 
        /* TODO get the real minor */
        int minor = 0;
 
+       device->deviceID = 0;
+
        snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
        file = fopen(path, "r");
        if (!file) {
@@ -77,7 +86,10 @@ drm_get_device_id(struct drm_device *device)
                return;
        }
 
-       fgets(path, sizeof( path ), file);
+       ret = fgets(path, sizeof( path ), file);
+       if (!ret)
+               return;
+
        sscanf(path, "%x", &device->deviceID);
        fclose(file);
 }
@@ -101,10 +113,28 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
        }
 }
 
+static void
+drm_find_dpms(struct drm_device *dev, struct drm_screen *screen)
+{
+       drmModeConnectorPtr c = screen->connector;
+       drmModePropertyPtr p;
+       int i;
+
+       for (i = 0; i < c->count_props; i++) {
+               p = drmModeGetProperty(dev->drmFD, c->props[i]);
+               if (!strcmp(p->name, "DPMS"))
+                       break;
+
+               drmModeFreeProperty(p);
+               p = NULL;
+       }
+
+       screen->dpms = p;
+}
+
 EGLBoolean
-drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
 {
-       _EGLDisplay *disp = _eglLookupDisplay(dpy);
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_screen *screen = NULL;
        drmModeConnectorPtr connector = NULL;
@@ -121,7 +151,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
        dev->drmFD = fd;
        drm_get_device_id(dev);
 
-       dev->screen = drm_api_hooks.create_screen(dev->drmFD, dev->deviceID);
+       dev->screen = dev->api->create_screen(dev->api, dev->drmFD, NULL);
        if (!dev->screen)
                goto err_screen;
        dev->winsys = dev->screen->winsys;
@@ -154,6 +184,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
                _eglInitScreen(&screen->base);
                _eglAddScreen(disp, &screen->base);
                drm_add_modes_from_connector(&screen->base, connector);
+               drm_find_dpms(dev, screen);
                dev->screens[num_screens++] = screen;
        }
        dev->count_screens = num_screens;
@@ -172,7 +203,10 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
        _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
        _eglAddConfig(disp, config);
 
-       drv->Initialized = EGL_TRUE;
+       disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+       /* enable supported extensions */
+       disp->Extensions.MESA_screen_surface = EGL_TRUE;
+       disp->Extensions.MESA_copy_context = EGL_TRUE;
 
        *major = 1;
        *minor = 4;
@@ -186,12 +220,14 @@ err_fd:
 }
 
 EGLBoolean
-drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_screen *screen;
        int i = 0;
 
+       _eglReleaseDisplayResources(drv, dpy);
+
        drmFreeVersion(dev->version);
 
        for (i = 0; i < dev->count_screens; i++) {
@@ -200,6 +236,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
                if (screen->shown)
                        drm_takedown_shown_screen(drv, screen);
 
+               drmModeFreeProperty(screen->dpms);
                drmModeFreeConnector(screen->connector);
                _eglDestroyScreen(&screen->base);
                dev->screens[i] = NULL;
@@ -210,8 +247,7 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
 
        drmClose(dev->drmFD);
 
-       _eglCleanupDisplay(_eglLookupDisplay(dpy));
-       free(dev);
+       _eglCleanupDisplay(dpy);
 
        return EGL_TRUE;
 }