mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-12 00:30:44 +02:00
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.
This commit is contained in:
parent
37213ceacc
commit
e32ac5b8a9
5 changed files with 42 additions and 63 deletions
|
|
@ -31,12 +31,19 @@ _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;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
return &scrn->Modes[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,45 +51,6 @@ _eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Parse the attrib_list to fill in the fields of the given _eglMode
|
||||
* Return EGL_FALSE if any errors, EGL_TRUE otherwise.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
_EGLMode *mode = &gscr->base.Modes[j];
|
||||
|
||||
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]);
|
||||
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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue