egl: don't fill client apis string forever.
[mesa.git] / src / egl / main / eglscreen.c
index 8b8966f3ffd2ba3a2c07699b5a8198c7eebff547..42ac621fcd98d5f3602d96c7414140413200c084 100644 (file)
@@ -1,3 +1,33 @@
+/**************************************************************************
+ *
+ * Copyright 2008 VMware, Inc.
+ * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
+ * Copyright 2010 LunarG, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
 /*
  * Ideas for screen management extension to EGL.
  *
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
+#include "c11/threads.h"
 
 #include "egldisplay.h"
 #include "eglcurrent.h"
 #include "eglmode.h"
-#include "eglconfig.h"
 #include "eglsurface.h"
 #include "eglscreen.h"
-#include "eglmutex.h"
 
 
 #ifdef EGL_MESA_screen_surface
 
 
 /* ugh, no atomic op? */
-static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex);
+static mtx_t _eglNextScreenHandleMutex = _MTX_INITIALIZER_NP;
 static EGLScreenMESA _eglNextScreenHandle = 1;
 
 
@@ -41,9 +70,10 @@ _eglAllocScreenHandle(void)
 {
    EGLScreenMESA s;
 
-   _eglLockMutex(&_eglNextScreenHandleMutex);
-   s = _eglNextScreenHandle++;
-   _eglUnlockMutex(&_eglNextScreenHandleMutex);
+   mtx_lock(&_eglNextScreenHandleMutex);
+   s = _eglNextScreenHandle;
+   _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
+   mtx_unlock(&_eglNextScreenHandleMutex);
 
    return s;
 }
@@ -53,60 +83,80 @@ _eglAllocScreenHandle(void)
  * Initialize an _EGLScreen object to default values.
  */
 void
-_eglInitScreen(_EGLScreen *screen)
+_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes)
 {
    memset(screen, 0, sizeof(_EGLScreen));
+
+   screen->Display = dpy;
+   screen->NumModes = num_modes;
    screen->StepX = 1;
    screen->StepY = 1;
+
+   if (num_modes > _EGL_SCREEN_MAX_MODES)
+      num_modes = _EGL_SCREEN_MAX_MODES;
+   screen->Modes = calloc(num_modes, sizeof(*screen->Modes));
+   screen->NumModes = (screen->Modes) ? num_modes : 0;
 }
 
 
 /**
- * Given a public screen handle, return the internal _EGLScreen object.
+ * Link a screen to its display and return the handle of the link.
+ * The handle can be passed to client directly.
  */
-_EGLScreen *
-_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
+EGLScreenMESA
+_eglLinkScreen(_EGLScreen *screen)
 {
+   _EGLDisplay *display;
    EGLint i;
 
-   if (!display->Screens)
-      return NULL;
+   assert(screen && screen->Display);
+   display = screen->Display;
 
-   for (i = 0; i < display->Screens->Size; i++) {
-      _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
-      if (scr->Handle == screen)
-         return scr;
+   if (!display->Screens) {
+      display->Screens = _eglCreateArray("Screen", 4);
+      if (!display->Screens)
+         return (EGLScreenMESA) 0;
    }
-   return NULL;
+
+   screen->Handle = _eglAllocScreenHandle();
+   for (i = 0; i < screen->NumModes; i++)
+      screen->Modes[i].Handle = screen->Handle + i;
+
+   _eglAppendArray(display->Screens, (void *) screen);
+
+   return screen->Handle;
 }
 
 
 /**
- * Add the given _EGLScreen to the display's list of screens.
+ * Lookup a handle to find the linked config.
+ * Return NULL if the handle has no corresponding linked config.
  */
-void
-_eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
+_EGLScreen *
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 {
-   assert(display);
-   assert(screen);
+   EGLint i;
 
-   if (!display->Screens) {
-      display->Screens = _eglCreateArray("Screen", 4);
-      if (!display->Screens)
-         return;
+   if (!display || !display->Screens)
+      return NULL;
+
+   for (i = 0; i < display->Screens->Size; i++) {
+      _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
+      if (scr->Handle == screen) {
+         assert(scr->Display == display);
+         return scr;
+      }
    }
-   screen->Handle = _eglAllocScreenHandle();
-   _eglAppendArray(display->Screens, (void *) screen);
+   return NULL;
 }
 
 
-
 static EGLBoolean
 _eglFlattenScreen(void *elem, void *buffer)
 {
    _EGLScreen *scr = (_EGLScreen *) elem;
    EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
-   *handle = scr->Handle;
+   *handle = _eglGetScreenHandle(scr);
    return EGL_TRUE;
 }
 
@@ -122,66 +172,6 @@ _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens
 }
 
 
-/**
- * Drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
-                            const EGLint *attrib_list)
-{
-   return NULL;
-}
-
-
-/**
- * Show the given surface on the named screen.
- * If surface is EGL_NO_SURFACE, disable the screen's output.
- * 
- * This is just a placeholder function; drivers will always override
- * this with code that _really_ shows the surface.
- */
-EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
-                          _EGLScreen *scrn, _EGLSurface *surf,
-                          _EGLMode *mode)
-{
-   if (!surf) {
-      scrn->CurrentSurface = NULL;
-   }
-   else {
-      if (surf->Type != EGL_SCREEN_BIT_MESA) {
-         _eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
-         return EGL_FALSE;
-      }
-      if (surf->Width < mode->Width || surf->Height < mode->Height) {
-         _eglError(EGL_BAD_SURFACE,
-                   "eglShowSurfaceMESA(surface smaller than screen size)");
-         return EGL_FALSE;
-      }
-
-      scrn->CurrentSurface = surf;
-      scrn->CurrentMode = mode;
-   }
-   return EGL_TRUE;
-}
-
-
-/**
- * Set a screen's current display mode.
- * Note: mode = EGL_NO_MODE is valid (turns off the screen)
- *
- * This is just a placeholder function; drivers will always override
- * this with code that _really_ sets the mode.
- */
-EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
-                   _EGLMode *m)
-{
-   scrn->CurrentMode = m;
-   return EGL_TRUE;
-}
-
-
 /**
  * Set a screen's surface origin.
  */
@@ -242,33 +232,4 @@ _eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
 }
 
 
-/**
- * Delete the modes associated with given screen.
- */
-void
-_eglDestroyScreenModes(_EGLScreen *scrn)
-{
-   EGLint i;
-   for (i = 0; i < scrn->NumModes; i++) {
-      if (scrn->Modes[i].Name)
-         free((char *) scrn->Modes[i].Name); /* cast away const */
-   }
-   if (scrn->Modes)
-      free(scrn->Modes);
-   scrn->Modes = NULL;
-   scrn->NumModes = 0;
-}
-
-      
-/**
- * Default fallback routine - drivers should usually override this.
- */
-void
-_eglDestroyScreen(_EGLScreen *scrn)
-{
-   _eglDestroyScreenModes(scrn);
-   free(scrn);
-}
-
-
 #endif /* EGL_MESA_screen_surface */