+/**************************************************************************
+ *
+ * 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;
{
EGLScreenMESA s;
- _eglLockMutex(&_eglNextScreenHandleMutex);
- s = _eglNextScreenHandle++;
- _eglUnlockMutex(&_eglNextScreenHandleMutex);
+ mtx_lock(&_eglNextScreenHandleMutex);
+ s = _eglNextScreenHandle;
+ _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
+ mtx_unlock(&_eglNextScreenHandleMutex);
return s;
}
* 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 || !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;
}
}
-/**
- * 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.
*/
}
-/**
- * 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 */