egl: Move fallback routines to eglfallbacks.c.
[mesa.git] / src / egl / main / eglscreen.c
index 14a1e9f8fe3a10672c531241f3267ca421ab4ceb..2ae403494e2a60c13052ba700a6b54debcf4ca72 100644 (file)
 #include <string.h>
 
 #include "egldisplay.h"
-#include "eglglobals.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 EGLScreenMESA _eglNextScreenHandle = 1;
 
 
 /**
  * Return a new screen handle/ID.
  * NOTE: we never reuse these!
  */
-EGLScreenMESA
+static EGLScreenMESA
 _eglAllocScreenHandle(void)
 {
-   EGLScreenMESA s = _eglGlobal.FreeScreenHandle;
-   _eglGlobal.FreeScreenHandle++;
+   EGLScreenMESA s;
+
+   _eglLockMutex(&_eglNextScreenHandleMutex);
+   s = _eglNextScreenHandle++;
+   _eglUnlockMutex(&_eglNextScreenHandleMutex);
+
    return s;
 }
 
@@ -56,9 +69,13 @@ _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 {
    EGLint i;
 
-   for (i = 0; i < display->NumScreens; i++) {
-      if (display->Screens[i]->Handle == screen)
-         return display->Screens[i];
+   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)
+         return scr;
    }
    return NULL;
 }
@@ -70,100 +87,37 @@ _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 void
 _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
 {
-   EGLint n;
-
    assert(display);
    assert(screen);
 
+   if (!display->Screens) {
+      display->Screens = _eglCreateArray("Screen", 4);
+      if (!display->Screens)
+         return;
+   }
    screen->Handle = _eglAllocScreenHandle();
-   n = display->NumScreens;
-   display->Screens = realloc(display->Screens, (n+1) * sizeof(_EGLScreen *));
-   display->Screens[n] = screen;
-   display->NumScreens++;
+   _eglAppendArray(display->Screens, (void *) screen);
 }
 
 
 
-EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
-                   EGLint max_screens, EGLint *num_screens)
+static EGLBoolean
+_eglFlattenScreen(void *elem, void *buffer)
 {
-   EGLint n;
-
-   if (display->NumScreens > max_screens) {
-      n = max_screens;
-   }
-   else {
-      n = display->NumScreens;
-   }
-
-   if (screens) {
-      EGLint i;
-      for (i = 0; i < n; i++)
-         screens[i] = display->Screens[i]->Handle;
-   }
-   if (num_screens)
-      *num_screens = n;
-
+   _EGLScreen *scr = (_EGLScreen *) elem;
+   EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
+   *handle = scr->Handle;
    return EGL_TRUE;
 }
 
 
-/**
- * Example function - drivers should do a proper implementation.
- */
-_EGLSurface *
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
-                            const EGLint *attrib_list)
-{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
-   _EGLSurface *surf;
-
-   surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
-   if (!surf)
-      return NULL;
-
-   if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA,
-                        conf, attrib_list)) {
-      free(surf);
-      return NULL;
-   }
-
-   return surf;
-#endif
-   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)
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
+                   EGLint max_screens, EGLint *num_screens)
 {
-   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;
-   }
+   *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
+         sizeof(screens[0]), max_screens, _eglFlattenScreen);
+
    return EGL_TRUE;
 }
 
@@ -272,3 +226,5 @@ _eglDestroyScreen(_EGLScreen *scrn)
    free(scrn);
 }
 
+
+#endif /* EGL_MESA_screen_surface */