Mesa (master): egl: Fix _eglModeLookup.

Chia-I Wu olv at kemper.freedesktop.org
Sat Oct 23 03:32:58 UTC 2010


Module: Mesa
Branch: master
Commit: e32ac5b8a963202dcdfb91354f77979765083000
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e32ac5b8a963202dcdfb91354f77979765083000

Author: Chia-I Wu <olv at lunarg.com>
Date:   Sat Oct 23 02:52:14 2010 +0800

egl: Fix _eglModeLookup.

Internally a mode belongs to a screen.  But functions like
eglGetModeAttribMESA treat a mode as a display resource: a mode can be
looked up without a screen.  Considering how KMS works, it is better to
stick to the current implementation.

To properly support looking up a mode without a screen, this commit
assigns each mode (of all screens) a unique ID.

---

 src/egl/main/eglmode.c                          |   58 +++++-----------------
 src/egl/main/eglmode.h                          |    5 --
 src/egl/main/eglscreen.c                        |   17 ++++++-
 src/egl/main/eglscreen.h                        |    5 ++-
 src/gallium/state_trackers/egl/common/egl_g3d.c |   22 ++++----
 5 files changed, 43 insertions(+), 64 deletions(-)

diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
index ed107d5..29d7964 100644
--- a/src/egl/main/eglmode.c
+++ b/src/egl/main/eglmode.c
@@ -31,56 +31,24 @@ _eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
    /* loop over all screens on the display */
    for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) {
       const _EGLScreen *scrn = disp->Screens->Elements[scrnum];
-      EGLint i;
-      /* search list of modes for handle */
-      for (i = 0; i < scrn->NumModes; i++) {
-         if (scrn->Modes[i].Handle == mode) {
-            return scrn->Modes + i;
-         }
-      }
-   }
+      EGLint idx;
 
-   return NULL;
-}
+      /*
+       * the mode ids of a screen ranges from scrn->Handle to scrn->Handle +
+       * scrn->NumModes
+       */
+      if (mode >= scrn->Handle &&
+          mode < scrn->Handle + _EGL_SCREEN_MAX_MODES) {
+         idx = mode - scrn->Handle;
 
+         assert(idx < scrn->NumModes && scrn->Modes[idx].Handle == mode);
 
-/**
- * Add a new mode with the given attributes (width, height, depth, refreshRate)
- * to the given screen.
- * Assign a new mode ID/handle to the mode as well.
- * \return pointer to the new _EGLMode
- */
-_EGLMode *
-_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
-               EGLint refreshRate, const char *name)
-{
-   EGLint n;
-   _EGLMode *newModes;
-
-   assert(screen);
-   assert(width > 0);
-   assert(height > 0);
-   assert(refreshRate > 0);
-
-   n = screen->NumModes;
-   newModes = (_EGLMode *) realloc(screen->Modes, (n+1) * sizeof(_EGLMode));
-   if (newModes) {
-      screen->Modes = newModes;
-      screen->Modes[n].Handle = n + 1;
-      screen->Modes[n].Width = width;
-      screen->Modes[n].Height = height;
-      screen->Modes[n].RefreshRate = refreshRate;
-      screen->Modes[n].Optimal = EGL_FALSE;
-      screen->Modes[n].Interlaced = EGL_FALSE;
-      screen->Modes[n].Name = _eglstrdup(name);
-      screen->NumModes++;
-      return screen->Modes + n;
-   }
-   else {
-      return NULL;
+         return &scrn->Modes[idx];
+      }
    }
-}
 
+   return NULL;
+}
 
 
 /**
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index 9167cbc..ed4eb2c 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -32,11 +32,6 @@ extern _EGLMode *
 _eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
 
 
-PUBLIC _EGLMode *
-_eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
-               EGLint refreshRate, const char *name);
-
-
 extern EGLBoolean
 _eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                    const EGLint *attrib_list, EGLModeMESA *modes,
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index 0bbead8..fc3ab32 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -42,7 +42,8 @@ _eglAllocScreenHandle(void)
    EGLScreenMESA s;
 
    _eglLockMutex(&_eglNextScreenHandleMutex);
-   s = _eglNextScreenHandle++;
+   s = _eglNextScreenHandle;
+   _eglNextScreenHandle += _EGL_SCREEN_MAX_MODES;
    _eglUnlockMutex(&_eglNextScreenHandleMutex);
 
    return s;
@@ -53,12 +54,19 @@ _eglAllocScreenHandle(void)
  * Initialize an _EGLScreen object to default values.
  */
 void
-_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy)
+_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 = (_EGLMode *) calloc(num_modes, sizeof(*screen->Modes));
+   screen->NumModes = (screen->Modes) ? num_modes : 0;
 }
 
 
@@ -70,6 +78,7 @@ EGLScreenMESA
 _eglLinkScreen(_EGLScreen *screen)
 {
    _EGLDisplay *display;
+   EGLint i;
 
    assert(screen && screen->Display);
    display = screen->Display;
@@ -79,7 +88,11 @@ _eglLinkScreen(_EGLScreen *screen)
       if (!display->Screens)
          return (EGLScreenMESA) 0;
    }
+
    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;
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 44fe20d..2a99f23 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -8,6 +8,9 @@
 #ifdef EGL_MESA_screen_surface
 
 
+#define _EGL_SCREEN_MAX_MODES 16
+
+
 /**
  * Per-screen information.
  * Note that an EGL screen doesn't have a size.  A screen may be set to
@@ -35,7 +38,7 @@ struct _egl_screen
 
 
 PUBLIC void
-_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy);
+_eglInitScreen(_EGLScreen *screen, _EGLDisplay *dpy, EGLint num_modes);
 
 
 PUBLIC EGLScreenMESA
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 772c65d..30ddcd5 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -126,18 +126,18 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
          continue;
       }
 
-      _eglInitScreen(&gscr->base, dpy);
-
-      for (j = 0; j < num_modes; j++) {
+      _eglInitScreen(&gscr->base, dpy, num_modes);
+      for (j = 0; j < gscr->base.NumModes; j++) {
          const struct native_mode *nmode = native_modes[j];
-         _EGLMode *mode;
-
-         mode = _eglAddNewMode(&gscr->base, nmode->width, nmode->height,
-               nmode->refresh_rate, nmode->desc);
-         if (!mode)
-            break;
-         /* gscr->native_modes and gscr->base.Modes should be consistent */
-         assert(mode == &gscr->base.Modes[j]);
+         _EGLMode *mode = &gscr->base.Modes[j];
+
+         mode->Width = nmode->width;
+         mode->Height = nmode->height;
+         mode->RefreshRate = nmode->refresh_rate;
+         mode->Optimal = EGL_FALSE;
+         mode->Interlaced = EGL_FALSE;
+         /* no need to strdup() */
+         mode->Name = nmode->desc;
       }
 
       gscr->native = nconn;




More information about the mesa-commit mailing list