From 715d784c1bff9ec037b26ae3e104dcff1c82357d Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 2 Oct 2009 14:52:59 +0800 Subject: [PATCH] glx: Make sure the DRI screen has non-empty configs. When creating a DRI screen, the visuals and fbconfigs are converted. It should be an error if the conversion fails. --- src/glx/x11/dri2_glx.c | 10 +++++-- src/glx/x11/dri_common.c | 59 +++++++++++++++++++++++++++++++++++++++------- src/glx/x11/dri_common.h | 4 +-- src/glx/x11/dri_glx.c | 10 +++++-- src/glx/x11/drisw_glx.c | 12 +++++++-- 5 files changed, 74 insertions(+), 21 deletions(-) diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 89efe3a..bbd3a33 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -496,10 +496,14 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, driBindExtensions(psc, 1); - psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); - psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); - psc->driver_configs = driver_configs; + if (!driConvertConfigs(psc)) { + ErrorMessageF("failed to convert screen configs\n"); + psc->core->destroyScreen(psc->__driScreen); + psc->__driScreen = NULL; + return NULL; + } + psp->destroyScreen = dri2DestroyScreen; psp->createContext = dri2CreateContext; diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c index 9c825ad..782f5d8 100644 --- a/src/glx/x11/dri_common.c +++ b/src/glx/x11/dri_common.c @@ -218,7 +218,7 @@ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) static int -scalarEqual(__GLcontextModes * mode, unsigned int attrib, unsigned int value) +scalarEqual(const __GLcontextModes * mode, unsigned int attrib, unsigned int value) { unsigned int glxValue; int i; @@ -234,7 +234,7 @@ scalarEqual(__GLcontextModes * mode, unsigned int attrib, unsigned int value) static int driConfigEqual(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig * driConfig) + const __GLcontextModes * modes, const __DRIconfig * driConfig) { unsigned int attrib, value, glxValue; int i; @@ -289,7 +289,7 @@ driConfigEqual(const __DRIcoreExtension * core, static __GLcontextModes * createDriMode(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig ** driConfigs) + const __GLcontextModes * modes, const __DRIconfig ** driConfigs) { __GLXDRIconfigPrivate *config; int i; @@ -312,11 +312,22 @@ createDriMode(const __DRIcoreExtension * core, return &config->modes; } -_X_HIDDEN __GLcontextModes * -driConvertConfigs(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig ** configs) +/** + * Filter and promote modes matching any of the configs to + * __GLXDRIconfigPrivate. + * + * \param modes - a list of modes to be filtered. + * \param configs - an array of DRI configs used as a filter. + * + * \returns + * A new list of __GLXDRIconfigPrivate casted to __GLcontextModes. + */ +static __GLcontextModes * +promoteModes(const __DRIcoreExtension * core, + const __GLcontextModes * modes, const __DRIconfig ** configs) { - __GLcontextModes head, *tail, *m; + __GLcontextModes head, *tail; + const __GLcontextModes *m; tail = &head; head.next = NULL; @@ -331,11 +342,41 @@ driConvertConfigs(const __DRIcoreExtension * core, tail = tail->next; } - _gl_context_modes_destroy(modes); - return head.next; } +/** + * Convert the visuals and fbconfigs of a __GLXscreenConfigs to + * __GLXDRIconfigPrivate. + * + * \param psc - a __GLXscreenConfigs to be converted. + * + * \returns + * Return true if both visuals and fbconfigs have been converted. + */ +_X_HIDDEN GLboolean +driConvertConfigs(__GLXscreenConfigs * psc) +{ + __GLcontextModes *visuals, *configs; + + configs = promoteModes(psc->core, psc->configs, psc->driver_configs); + if (!configs && psc->configs) + return GL_FALSE; + + visuals = promoteModes(psc->core, psc->visuals, psc->driver_configs); + if (!visuals && psc->visuals) { + _gl_context_modes_destroy(configs); + return GL_FALSE; + } + + _gl_context_modes_destroy(psc->configs); + _gl_context_modes_destroy(psc->visuals); + psc->configs = configs; + psc->visuals = visuals; + + return GL_TRUE; +} + _X_HIDDEN void driBindExtensions(__GLXscreenConfigs * psc, int dri2) { diff --git a/src/glx/x11/dri_common.h b/src/glx/x11/dri_common.h index 61ac9c6..ef15f42 100644 --- a/src/glx/x11/dri_common.h +++ b/src/glx/x11/dri_common.h @@ -44,9 +44,7 @@ struct __GLXDRIconfigPrivateRec const __DRIconfig *driConfig; }; -extern __GLcontextModes *driConvertConfigs(const __DRIcoreExtension * core, - __GLcontextModes * modes, - const __DRIconfig ** configs); +extern GLboolean driConvertConfigs(__GLXscreenConfigs * psc); extern const __DRIsystemTimeExtension systemTimeExtension; diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c index ab24bd8..41913a7 100644 --- a/src/glx/x11/dri_glx.c +++ b/src/glx/x11/dri_glx.c @@ -426,10 +426,11 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc, goto handle_error; } - psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); - psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); - psc->driver_configs = driver_configs; + if (!driConvertConfigs(psc)) { + ErrorMessageF("Convertion screen configs failed"); + goto handle_error; + } /* Visuals with depth != screen depth are subject to automatic compositing * in the X server, so DRI1 can't render to them properly. Mark them as @@ -456,6 +457,9 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc, return psp; handle_error: + if (psp) + (*psc->core->destroyScreen) (psp); + if (pSAREA != MAP_FAILED) drmUnmap(pSAREA, SAREA_MAX); diff --git a/src/glx/x11/drisw_glx.c b/src/glx/x11/drisw_glx.c index 15e1586..44c65bc 100644 --- a/src/glx/x11/drisw_glx.c +++ b/src/glx/x11/drisw_glx.c @@ -398,10 +398,11 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, driBindExtensions(psc, 0); - psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs); - psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs); - psc->driver_configs = driver_configs; + if (!driConvertConfigs(psc)) { + ErrorMessageF("failed to convert screen configs\n"); + goto handle_error; + } psp->destroyScreen = driDestroyScreen; psp->createContext = driCreateContext; @@ -413,6 +414,11 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen, return psp; handle_error: + if (psc->__driScreen) { + psc->core->destroyScreen(psc->__driScreen); + psc->__driScreen = NULL; + } + Xfree(psp); if (psc->driver) -- 1.6.3.3