eglconfig.c revision 3464ebd5
13464ebd5Sriastradh/**************************************************************************
23464ebd5Sriastradh *
33464ebd5Sriastradh * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
43464ebd5Sriastradh * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
53464ebd5Sriastradh * Copyright 2010-2011 LunarG, Inc.
63464ebd5Sriastradh * All Rights Reserved.
73464ebd5Sriastradh *
83464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
93464ebd5Sriastradh * copy of this software and associated documentation files (the
103464ebd5Sriastradh * "Software"), to deal in the Software without restriction, including
113464ebd5Sriastradh * without limitation the rights to use, copy, modify, merge, publish,
123464ebd5Sriastradh * distribute, sub license, and/or sell copies of the Software, and to
133464ebd5Sriastradh * permit persons to whom the Software is furnished to do so, subject to
143464ebd5Sriastradh * the following conditions:
153464ebd5Sriastradh *
163464ebd5Sriastradh * The above copyright notice and this permission notice (including the
173464ebd5Sriastradh * next paragraph) shall be included in all copies or substantial portions
183464ebd5Sriastradh * of the Software.
193464ebd5Sriastradh *
203464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
213464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
223464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
233464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
243464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
253464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
263464ebd5Sriastradh * DEALINGS IN THE SOFTWARE.
273464ebd5Sriastradh *
283464ebd5Sriastradh **************************************************************************/
293464ebd5Sriastradh
303464ebd5Sriastradh
314a49301eSmrg/**
324a49301eSmrg * EGL Configuration (pixel format) functions.
334a49301eSmrg */
344a49301eSmrg
354a49301eSmrg
364a49301eSmrg#include <stdlib.h>
374a49301eSmrg#include <string.h>
384a49301eSmrg#include <assert.h>
394a49301eSmrg#include "eglconfig.h"
404a49301eSmrg#include "egldisplay.h"
41cdc920a0Smrg#include "eglcurrent.h"
424a49301eSmrg#include "egllog.h"
434a49301eSmrg
444a49301eSmrg
454a49301eSmrg#define MIN2(A, B)  (((A) < (B)) ? (A) : (B))
464a49301eSmrg
474a49301eSmrg
484a49301eSmrg/**
494a49301eSmrg * Init the given _EGLconfig to default values.
504a49301eSmrg * \param id  the configuration's ID.
514a49301eSmrg *
524a49301eSmrg * Note that id must be positive for the config to be valid.
534a49301eSmrg * It is also recommended that when there are N configs, their
544a49301eSmrg * IDs are from 1 to N respectively.
554a49301eSmrg */
564a49301eSmrgvoid
573464ebd5Sriastradh_eglInitConfig(_EGLConfig *conf, _EGLDisplay *dpy, EGLint id)
584a49301eSmrg{
593464ebd5Sriastradh   memset(conf, 0, sizeof(*conf));
604a49301eSmrg
613464ebd5Sriastradh   conf->Display = dpy;
62cdc920a0Smrg
634a49301eSmrg   /* some attributes take non-zero default values */
643464ebd5Sriastradh   conf->ConfigID = id;
653464ebd5Sriastradh   conf->ConfigCaveat = EGL_NONE;
663464ebd5Sriastradh   conf->TransparentType = EGL_NONE;
673464ebd5Sriastradh   conf->NativeVisualType = EGL_NONE;
683464ebd5Sriastradh   conf->ColorBufferType = EGL_RGB_BUFFER;
694a49301eSmrg}
704a49301eSmrg
714a49301eSmrg
724a49301eSmrg/**
733464ebd5Sriastradh * Link a config to its display and return the handle of the link.
744a49301eSmrg * The handle can be passed to client directly.
754a49301eSmrg *
764a49301eSmrg * Note that we just save the ptr to the config (we don't copy the config).
774a49301eSmrg */
783464ebd5SriastradhPUBLIC EGLConfig
793464ebd5Sriastradh_eglLinkConfig(_EGLConfig *conf)
804a49301eSmrg{
813464ebd5Sriastradh   _EGLDisplay *dpy = conf->Display;
824a49301eSmrg
834a49301eSmrg   /* sanity check */
843464ebd5Sriastradh   assert(dpy && conf->ConfigID > 0);
854a49301eSmrg
863464ebd5Sriastradh   if (!dpy->Configs) {
873464ebd5Sriastradh      dpy->Configs = _eglCreateArray("Config", 16);
883464ebd5Sriastradh      if (!dpy->Configs)
894a49301eSmrg         return (EGLConfig) NULL;
904a49301eSmrg   }
914a49301eSmrg
923464ebd5Sriastradh   _eglAppendArray(dpy->Configs, (void *) conf);
934a49301eSmrg
944a49301eSmrg   return (EGLConfig) conf;
954a49301eSmrg}
964a49301eSmrg
974a49301eSmrg
983464ebd5Sriastradh/**
993464ebd5Sriastradh * Lookup a handle to find the linked config.
1003464ebd5Sriastradh * Return NULL if the handle has no corresponding linked config.
1013464ebd5Sriastradh */
1023464ebd5Sriastradh_EGLConfig *
1033464ebd5Sriastradh_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy)
1044a49301eSmrg{
1053464ebd5Sriastradh   _EGLConfig *conf;
1064a49301eSmrg
1073464ebd5Sriastradh   if (!dpy)
1083464ebd5Sriastradh      return NULL;
1093464ebd5Sriastradh
1103464ebd5Sriastradh   conf = (_EGLConfig *) _eglFindArray(dpy->Configs, (void *) config);
1113464ebd5Sriastradh   if (conf)
1123464ebd5Sriastradh      assert(conf->Display == dpy);
1133464ebd5Sriastradh
1143464ebd5Sriastradh   return conf;
1154a49301eSmrg}
1164a49301eSmrg
1174a49301eSmrg
1184a49301eSmrgenum {
1194a49301eSmrg   /* types */
1204a49301eSmrg   ATTRIB_TYPE_INTEGER,
1214a49301eSmrg   ATTRIB_TYPE_BOOLEAN,
1224a49301eSmrg   ATTRIB_TYPE_BITMASK,
1234a49301eSmrg   ATTRIB_TYPE_ENUM,
1244a49301eSmrg   ATTRIB_TYPE_PSEUDO, /* non-queryable */
1254a49301eSmrg   ATTRIB_TYPE_PLATFORM, /* platform-dependent */
1264a49301eSmrg   /* criteria */
1274a49301eSmrg   ATTRIB_CRITERION_EXACT,
1284a49301eSmrg   ATTRIB_CRITERION_ATLEAST,
1294a49301eSmrg   ATTRIB_CRITERION_MASK,
1304a49301eSmrg   ATTRIB_CRITERION_SPECIAL,
131cdc920a0Smrg   ATTRIB_CRITERION_IGNORE
1324a49301eSmrg};
1334a49301eSmrg
1344a49301eSmrg
1354a49301eSmrg/* EGL spec Table 3.1 and 3.4 */
1364a49301eSmrgstatic const struct {
1374a49301eSmrg   EGLint attr;
1384a49301eSmrg   EGLint type;
1394a49301eSmrg   EGLint criterion;
1404a49301eSmrg   EGLint default_value;
1414a49301eSmrg} _eglValidationTable[] =
1424a49301eSmrg{
1433464ebd5Sriastradh   /* core */
1444a49301eSmrg   { EGL_BUFFER_SIZE,               ATTRIB_TYPE_INTEGER,
1454a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1464a49301eSmrg                                    0 },
1474a49301eSmrg   { EGL_RED_SIZE,                  ATTRIB_TYPE_INTEGER,
1484a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1494a49301eSmrg                                    0 },
1504a49301eSmrg   { EGL_GREEN_SIZE,                ATTRIB_TYPE_INTEGER,
1514a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1524a49301eSmrg                                    0 },
1534a49301eSmrg   { EGL_BLUE_SIZE,                 ATTRIB_TYPE_INTEGER,
1544a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1554a49301eSmrg                                    0 },
1564a49301eSmrg   { EGL_LUMINANCE_SIZE,            ATTRIB_TYPE_INTEGER,
1574a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1584a49301eSmrg                                    0 },
1594a49301eSmrg   { EGL_ALPHA_SIZE,                ATTRIB_TYPE_INTEGER,
1604a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1614a49301eSmrg                                    0 },
1624a49301eSmrg   { EGL_ALPHA_MASK_SIZE,           ATTRIB_TYPE_INTEGER,
1634a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1644a49301eSmrg                                    0 },
1654a49301eSmrg   { EGL_BIND_TO_TEXTURE_RGB,       ATTRIB_TYPE_BOOLEAN,
1664a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1674a49301eSmrg                                    EGL_DONT_CARE },
1684a49301eSmrg   { EGL_BIND_TO_TEXTURE_RGBA,      ATTRIB_TYPE_BOOLEAN,
1694a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1704a49301eSmrg                                    EGL_DONT_CARE },
1714a49301eSmrg   { EGL_COLOR_BUFFER_TYPE,         ATTRIB_TYPE_ENUM,
1724a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1734a49301eSmrg                                    EGL_RGB_BUFFER },
1744a49301eSmrg   { EGL_CONFIG_CAVEAT,             ATTRIB_TYPE_ENUM,
1754a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1764a49301eSmrg                                    EGL_DONT_CARE },
1774a49301eSmrg   { EGL_CONFIG_ID,                 ATTRIB_TYPE_INTEGER,
1784a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1794a49301eSmrg                                    EGL_DONT_CARE },
1804a49301eSmrg   { EGL_CONFORMANT,                ATTRIB_TYPE_BITMASK,
1814a49301eSmrg                                    ATTRIB_CRITERION_MASK,
1824a49301eSmrg                                    0 },
1834a49301eSmrg   { EGL_DEPTH_SIZE,                ATTRIB_TYPE_INTEGER,
1844a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
1854a49301eSmrg                                    0 },
1864a49301eSmrg   { EGL_LEVEL,                     ATTRIB_TYPE_PLATFORM,
1874a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
1884a49301eSmrg                                    0 },
1894a49301eSmrg   { EGL_MAX_PBUFFER_WIDTH,         ATTRIB_TYPE_INTEGER,
1904a49301eSmrg                                    ATTRIB_CRITERION_IGNORE,
1914a49301eSmrg                                    0 },
1924a49301eSmrg   { EGL_MAX_PBUFFER_HEIGHT,        ATTRIB_TYPE_INTEGER,
1934a49301eSmrg                                    ATTRIB_CRITERION_IGNORE,
1944a49301eSmrg                                    0 },
1954a49301eSmrg   { EGL_MAX_PBUFFER_PIXELS,        ATTRIB_TYPE_INTEGER,
1964a49301eSmrg                                    ATTRIB_CRITERION_IGNORE,
1974a49301eSmrg                                    0 },
1984a49301eSmrg   { EGL_MAX_SWAP_INTERVAL,         ATTRIB_TYPE_INTEGER,
1994a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2004a49301eSmrg                                    EGL_DONT_CARE },
2014a49301eSmrg   { EGL_MIN_SWAP_INTERVAL,         ATTRIB_TYPE_INTEGER,
2024a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2034a49301eSmrg                                    EGL_DONT_CARE },
2044a49301eSmrg   { EGL_NATIVE_RENDERABLE,         ATTRIB_TYPE_BOOLEAN,
2054a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2064a49301eSmrg                                    EGL_DONT_CARE },
2074a49301eSmrg   { EGL_NATIVE_VISUAL_ID,          ATTRIB_TYPE_PLATFORM,
2084a49301eSmrg                                    ATTRIB_CRITERION_IGNORE,
2094a49301eSmrg                                    0 },
2104a49301eSmrg   { EGL_NATIVE_VISUAL_TYPE,        ATTRIB_TYPE_PLATFORM,
2114a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2124a49301eSmrg                                    EGL_DONT_CARE },
2134a49301eSmrg   { EGL_RENDERABLE_TYPE,           ATTRIB_TYPE_BITMASK,
2144a49301eSmrg                                    ATTRIB_CRITERION_MASK,
2154a49301eSmrg                                    EGL_OPENGL_ES_BIT },
2164a49301eSmrg   { EGL_SAMPLE_BUFFERS,            ATTRIB_TYPE_INTEGER,
2174a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
2184a49301eSmrg                                    0 },
2194a49301eSmrg   { EGL_SAMPLES,                   ATTRIB_TYPE_INTEGER,
2204a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
2214a49301eSmrg                                    0 },
2224a49301eSmrg   { EGL_STENCIL_SIZE,              ATTRIB_TYPE_INTEGER,
2234a49301eSmrg                                    ATTRIB_CRITERION_ATLEAST,
2244a49301eSmrg                                    0 },
2254a49301eSmrg   { EGL_SURFACE_TYPE,              ATTRIB_TYPE_BITMASK,
2264a49301eSmrg                                    ATTRIB_CRITERION_MASK,
2274a49301eSmrg                                    EGL_WINDOW_BIT },
2284a49301eSmrg   { EGL_TRANSPARENT_TYPE,          ATTRIB_TYPE_ENUM,
2294a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2304a49301eSmrg                                    EGL_NONE },
2314a49301eSmrg   { EGL_TRANSPARENT_RED_VALUE,     ATTRIB_TYPE_INTEGER,
2324a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2334a49301eSmrg                                    EGL_DONT_CARE },
2344a49301eSmrg   { EGL_TRANSPARENT_GREEN_VALUE,   ATTRIB_TYPE_INTEGER,
2354a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2364a49301eSmrg                                    EGL_DONT_CARE },
2374a49301eSmrg   { EGL_TRANSPARENT_BLUE_VALUE,    ATTRIB_TYPE_INTEGER,
2384a49301eSmrg                                    ATTRIB_CRITERION_EXACT,
2394a49301eSmrg                                    EGL_DONT_CARE },
2404a49301eSmrg   { EGL_MATCH_NATIVE_PIXMAP,       ATTRIB_TYPE_PSEUDO,
2414a49301eSmrg                                    ATTRIB_CRITERION_SPECIAL,
2424a49301eSmrg                                    EGL_NONE },
2433464ebd5Sriastradh   /* extensions */
2443464ebd5Sriastradh   { EGL_Y_INVERTED_NOK,            ATTRIB_TYPE_BOOLEAN,
2453464ebd5Sriastradh                                    ATTRIB_CRITERION_EXACT,
2463464ebd5Sriastradh                                    EGL_DONT_CARE }
2474a49301eSmrg};
2484a49301eSmrg
2494a49301eSmrg
2504a49301eSmrg/**
2514a49301eSmrg * Return true if a config is valid.  When for_matching is true,
2524a49301eSmrg * EGL_DONT_CARE is accepted as a valid attribute value, and checks
2534a49301eSmrg * for conflicting attribute values are skipped.
2544a49301eSmrg *
2554a49301eSmrg * Note that some attributes are platform-dependent and are not
2564a49301eSmrg * checked.
2574a49301eSmrg */
2584a49301eSmrgEGLBoolean
2594a49301eSmrg_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
2604a49301eSmrg{
2614a49301eSmrg   EGLint i, attr, val;
2624a49301eSmrg   EGLBoolean valid = EGL_TRUE;
2634a49301eSmrg
2644a49301eSmrg   /* check attributes by their types */
2654a49301eSmrg   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
2664a49301eSmrg      EGLint mask;
2674a49301eSmrg
2684a49301eSmrg      attr = _eglValidationTable[i].attr;
2693464ebd5Sriastradh      val = _eglGetConfigKey(conf, attr);
2704a49301eSmrg
2714a49301eSmrg      switch (_eglValidationTable[i].type) {
2724a49301eSmrg      case ATTRIB_TYPE_INTEGER:
2734a49301eSmrg         switch (attr) {
2744a49301eSmrg         case EGL_CONFIG_ID:
2754a49301eSmrg            /* config id must be positive */
2764a49301eSmrg            if (val <= 0)
2774a49301eSmrg               valid = EGL_FALSE;
2784a49301eSmrg            break;
2794a49301eSmrg         case EGL_SAMPLE_BUFFERS:
2804a49301eSmrg            /* there can be at most 1 sample buffer */
2813464ebd5Sriastradh            if (val > 1 || val < 0)
2824a49301eSmrg               valid = EGL_FALSE;
2834a49301eSmrg            break;
2843464ebd5Sriastradh         default:
2853464ebd5Sriastradh            if (val < 0)
2863464ebd5Sriastradh               valid = EGL_FALSE;
2874a49301eSmrg            break;
2884a49301eSmrg         }
2894a49301eSmrg         break;
2904a49301eSmrg      case ATTRIB_TYPE_BOOLEAN:
2914a49301eSmrg         if (val != EGL_TRUE && val != EGL_FALSE)
2924a49301eSmrg            valid = EGL_FALSE;
2934a49301eSmrg         break;
2944a49301eSmrg      case ATTRIB_TYPE_ENUM:
2954a49301eSmrg         switch (attr) {
2964a49301eSmrg         case EGL_CONFIG_CAVEAT:
2974a49301eSmrg            if (val != EGL_NONE && val != EGL_SLOW_CONFIG &&
2984a49301eSmrg                val != EGL_NON_CONFORMANT_CONFIG)
2994a49301eSmrg               valid = EGL_FALSE;
3004a49301eSmrg            break;
3014a49301eSmrg         case EGL_TRANSPARENT_TYPE:
3024a49301eSmrg            if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB)
3034a49301eSmrg               valid = EGL_FALSE;
3044a49301eSmrg            break;
3054a49301eSmrg         case EGL_COLOR_BUFFER_TYPE:
3064a49301eSmrg            if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER)
3074a49301eSmrg               valid = EGL_FALSE;
3084a49301eSmrg            break;
3094a49301eSmrg         default:
3104a49301eSmrg            assert(0);
3114a49301eSmrg            break;
3124a49301eSmrg         }
3134a49301eSmrg         break;
3144a49301eSmrg      case ATTRIB_TYPE_BITMASK:
3154a49301eSmrg         switch (attr) {
3164a49301eSmrg         case EGL_SURFACE_TYPE:
3174a49301eSmrg            mask = EGL_PBUFFER_BIT |
3184a49301eSmrg                   EGL_PIXMAP_BIT |
3194a49301eSmrg                   EGL_WINDOW_BIT |
3204a49301eSmrg                   EGL_VG_COLORSPACE_LINEAR_BIT |
3214a49301eSmrg                   EGL_VG_ALPHA_FORMAT_PRE_BIT |
3224a49301eSmrg                   EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
3234a49301eSmrg                   EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
3243464ebd5Sriastradh#ifdef EGL_MESA_screen_surface
325cdc920a0Smrg            if (conf->Display->Extensions.MESA_screen_surface)
326cdc920a0Smrg               mask |= EGL_SCREEN_BIT_MESA;
3273464ebd5Sriastradh#endif
3284a49301eSmrg            break;
3294a49301eSmrg         case EGL_RENDERABLE_TYPE:
3304a49301eSmrg         case EGL_CONFORMANT:
3314a49301eSmrg            mask = EGL_OPENGL_ES_BIT |
3324a49301eSmrg                   EGL_OPENVG_BIT |
3334a49301eSmrg                   EGL_OPENGL_ES2_BIT |
3344a49301eSmrg                   EGL_OPENGL_BIT;
3354a49301eSmrg            break;
3364a49301eSmrg         default:
3374a49301eSmrg            assert(0);
3384a49301eSmrg            break;
3394a49301eSmrg         }
3404a49301eSmrg         if (val & ~mask)
3414a49301eSmrg            valid = EGL_FALSE;
3424a49301eSmrg         break;
3434a49301eSmrg      case ATTRIB_TYPE_PLATFORM:
3444a49301eSmrg         /* unable to check platform-dependent attributes here */
3454a49301eSmrg         break;
3464a49301eSmrg      case ATTRIB_TYPE_PSEUDO:
3474a49301eSmrg         /* pseudo attributes should not be set */
3484a49301eSmrg         if (val != 0)
3494a49301eSmrg            valid = EGL_FALSE;
3504a49301eSmrg         break;
3514a49301eSmrg      default:
3524a49301eSmrg         assert(0);
3534a49301eSmrg         break;
3544a49301eSmrg      }
3554a49301eSmrg
3564a49301eSmrg      if (!valid && for_matching) {
3574a49301eSmrg         /* accept EGL_DONT_CARE as a valid value */
3584a49301eSmrg         if (val == EGL_DONT_CARE)
3594a49301eSmrg            valid = EGL_TRUE;
3604a49301eSmrg         if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL)
3614a49301eSmrg            valid = EGL_TRUE;
3624a49301eSmrg      }
363cdc920a0Smrg      if (!valid) {
364cdc920a0Smrg         _eglLog(_EGL_DEBUG,
365cdc920a0Smrg               "attribute 0x%04x has an invalid value 0x%x", attr, val);
3664a49301eSmrg         break;
367cdc920a0Smrg      }
3684a49301eSmrg   }
3694a49301eSmrg
3704a49301eSmrg   /* any invalid attribute value should have been catched */
3714a49301eSmrg   if (!valid || for_matching)
3724a49301eSmrg      return valid;
3734a49301eSmrg
3744a49301eSmrg   /* now check for conflicting attribute values */
3754a49301eSmrg
3763464ebd5Sriastradh   switch (conf->ColorBufferType) {
3774a49301eSmrg   case EGL_RGB_BUFFER:
3783464ebd5Sriastradh      if (conf->LuminanceSize)
3794a49301eSmrg         valid = EGL_FALSE;
3803464ebd5Sriastradh      if (conf->RedSize + conf->GreenSize +
3813464ebd5Sriastradh            conf->BlueSize + conf->AlphaSize != conf->BufferSize)
3824a49301eSmrg         valid = EGL_FALSE;
3834a49301eSmrg      break;
3844a49301eSmrg   case EGL_LUMINANCE_BUFFER:
3853464ebd5Sriastradh      if (conf->RedSize || conf->GreenSize || conf->BlueSize)
3864a49301eSmrg         valid = EGL_FALSE;
3873464ebd5Sriastradh      if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
3884a49301eSmrg         valid = EGL_FALSE;
3894a49301eSmrg      break;
3904a49301eSmrg   }
391cdc920a0Smrg   if (!valid) {
392cdc920a0Smrg      _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
393cdc920a0Smrg      return EGL_FALSE;
394cdc920a0Smrg   }
3954a49301eSmrg
3963464ebd5Sriastradh   if (!conf->SampleBuffers && conf->Samples)
3974a49301eSmrg      valid = EGL_FALSE;
398cdc920a0Smrg   if (!valid) {
399cdc920a0Smrg      _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers");
400cdc920a0Smrg      return EGL_FALSE;
401cdc920a0Smrg   }
4024a49301eSmrg
4033464ebd5Sriastradh   if (!(conf->SurfaceType & EGL_WINDOW_BIT)) {
4043464ebd5Sriastradh      if (conf->NativeVisualID != 0 || conf->NativeVisualType != EGL_NONE)
4054a49301eSmrg         valid = EGL_FALSE;
4064a49301eSmrg   }
4073464ebd5Sriastradh   if (!(conf->SurfaceType & EGL_PBUFFER_BIT)) {
4083464ebd5Sriastradh      if (conf->BindToTextureRGB || conf->BindToTextureRGBA)
4094a49301eSmrg         valid = EGL_FALSE;
4104a49301eSmrg   }
411cdc920a0Smrg   if (!valid) {
412cdc920a0Smrg      _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding");
413cdc920a0Smrg      return EGL_FALSE;
414cdc920a0Smrg   }
4154a49301eSmrg
4164a49301eSmrg   return valid;
4174a49301eSmrg}
4184a49301eSmrg
4194a49301eSmrg
4204a49301eSmrg/**
4214a49301eSmrg * Return true if a config matches the criteria.  This and
4224a49301eSmrg * _eglParseConfigAttribList together implement the algorithm
4234a49301eSmrg * described in "Selection of EGLConfigs".
4244a49301eSmrg *
4254a49301eSmrg * Note that attributes that are special (currently, only
4264a49301eSmrg * EGL_MATCH_NATIVE_PIXMAP) are ignored.
4274a49301eSmrg */
4284a49301eSmrgEGLBoolean
4294a49301eSmrg_eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
4304a49301eSmrg{
4314a49301eSmrg   EGLint attr, val, i;
4324a49301eSmrg   EGLBoolean matched = EGL_TRUE;
4334a49301eSmrg
4344a49301eSmrg   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
4354a49301eSmrg      EGLint cmp;
4364a49301eSmrg      if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_IGNORE)
4374a49301eSmrg         continue;
4384a49301eSmrg
4394a49301eSmrg      attr = _eglValidationTable[i].attr;
4403464ebd5Sriastradh      cmp = _eglGetConfigKey(criteria, attr);
4414a49301eSmrg      if (cmp == EGL_DONT_CARE)
4424a49301eSmrg         continue;
4434a49301eSmrg
4443464ebd5Sriastradh      val = _eglGetConfigKey(conf, attr);
4454a49301eSmrg      switch (_eglValidationTable[i].criterion) {
4464a49301eSmrg      case ATTRIB_CRITERION_EXACT:
4474a49301eSmrg         if (val != cmp)
4484a49301eSmrg            matched = EGL_FALSE;
4494a49301eSmrg         break;
4504a49301eSmrg      case ATTRIB_CRITERION_ATLEAST:
4514a49301eSmrg         if (val < cmp)
4524a49301eSmrg            matched = EGL_FALSE;
4534a49301eSmrg         break;
4544a49301eSmrg      case ATTRIB_CRITERION_MASK:
4554a49301eSmrg         if ((val & cmp) != cmp)
4564a49301eSmrg            matched = EGL_FALSE;
4574a49301eSmrg         break;
4584a49301eSmrg      case ATTRIB_CRITERION_SPECIAL:
4594a49301eSmrg         /* ignored here */
4604a49301eSmrg         break;
4614a49301eSmrg      default:
4624a49301eSmrg         assert(0);
4634a49301eSmrg         break;
4644a49301eSmrg      }
4654a49301eSmrg
466cdc920a0Smrg      if (!matched) {
4673464ebd5Sriastradh#ifndef DEBUG
4683464ebd5Sriastradh         /* only print the common errors when DEBUG is not defined */
4693464ebd5Sriastradh         if (attr != EGL_RENDERABLE_TYPE)
4703464ebd5Sriastradh            break;
4713464ebd5Sriastradh#endif
472cdc920a0Smrg         _eglLog(_EGL_DEBUG,
473cdc920a0Smrg               "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
474cdc920a0Smrg               val, attr, cmp);
4754a49301eSmrg         break;
476cdc920a0Smrg      }
4774a49301eSmrg   }
4784a49301eSmrg
4794a49301eSmrg   return matched;
4804a49301eSmrg}
4814a49301eSmrg
4823464ebd5Sriastradhstatic INLINE EGLBoolean
4833464ebd5Sriastradh_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
4843464ebd5Sriastradh{
4853464ebd5Sriastradh   if (_eglOffsetOfConfig(attr) < 0)
4863464ebd5Sriastradh      return EGL_FALSE;
4873464ebd5Sriastradh
4883464ebd5Sriastradh   switch (attr) {
4893464ebd5Sriastradh   case EGL_Y_INVERTED_NOK:
4903464ebd5Sriastradh      return conf->Display->Extensions.NOK_texture_from_pixmap;
4913464ebd5Sriastradh   default:
4923464ebd5Sriastradh      break;
4933464ebd5Sriastradh   }
4943464ebd5Sriastradh
4953464ebd5Sriastradh   return EGL_TRUE;
4963464ebd5Sriastradh}
4974a49301eSmrg
4984a49301eSmrg/**
4994a49301eSmrg * Initialize a criteria config from the given attribute list.
5004a49301eSmrg * Return EGL_FALSE if any of the attribute is invalid.
5014a49301eSmrg */
5024a49301eSmrgEGLBoolean
5033464ebd5Sriastradh_eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy,
5043464ebd5Sriastradh                          const EGLint *attrib_list)
5054a49301eSmrg{
5064a49301eSmrg   EGLint attr, val, i;
5073464ebd5Sriastradh
5083464ebd5Sriastradh   _eglInitConfig(conf, dpy, EGL_DONT_CARE);
5094a49301eSmrg
5104a49301eSmrg   /* reset to default values */
5114a49301eSmrg   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
5124a49301eSmrg      attr = _eglValidationTable[i].attr;
5134a49301eSmrg      val = _eglValidationTable[i].default_value;
5143464ebd5Sriastradh      _eglSetConfigKey(conf, attr, val);
5154a49301eSmrg   }
5164a49301eSmrg
5174a49301eSmrg   /* parse the list */
5184a49301eSmrg   for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) {
5194a49301eSmrg      attr = attrib_list[i];
5204a49301eSmrg      val = attrib_list[i + 1];
5214a49301eSmrg
5223464ebd5Sriastradh      if (!_eglIsConfigAttribValid(conf, attr))
5233464ebd5Sriastradh	 return EGL_FALSE;
5244a49301eSmrg
5253464ebd5Sriastradh      _eglSetConfigKey(conf, attr, val);
5264a49301eSmrg   }
5274a49301eSmrg
5284a49301eSmrg   if (!_eglValidateConfig(conf, EGL_TRUE))
5294a49301eSmrg      return EGL_FALSE;
5304a49301eSmrg
5314a49301eSmrg   /* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */
5323464ebd5Sriastradh   if (conf->Level == EGL_DONT_CARE)
5334a49301eSmrg      return EGL_FALSE;
5344a49301eSmrg
5354a49301eSmrg   /* ignore other attributes when EGL_CONFIG_ID is given */
5363464ebd5Sriastradh   if (conf->ConfigID != EGL_DONT_CARE) {
5373464ebd5Sriastradh      for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
5383464ebd5Sriastradh         attr = _eglValidationTable[i].attr;
5393464ebd5Sriastradh         if (attr != EGL_CONFIG_ID)
5403464ebd5Sriastradh            _eglSetConfigKey(conf, attr, EGL_DONT_CARE);
5413464ebd5Sriastradh      }
5424a49301eSmrg   }
5434a49301eSmrg   else {
5443464ebd5Sriastradh      if (!(conf->SurfaceType & EGL_WINDOW_BIT))
5453464ebd5Sriastradh         conf->NativeVisualType = EGL_DONT_CARE;
5464a49301eSmrg
5473464ebd5Sriastradh      if (conf->TransparentType == EGL_NONE) {
5483464ebd5Sriastradh         conf->TransparentRedValue = EGL_DONT_CARE;
5493464ebd5Sriastradh         conf->TransparentGreenValue = EGL_DONT_CARE;
5503464ebd5Sriastradh         conf->TransparentBlueValue = EGL_DONT_CARE;
5514a49301eSmrg      }
5524a49301eSmrg   }
5534a49301eSmrg
5544a49301eSmrg   return EGL_TRUE;
5554a49301eSmrg}
5564a49301eSmrg
5574a49301eSmrg
5584a49301eSmrg/**
5594a49301eSmrg * Decide the ordering of conf1 and conf2, under the given criteria.
5604a49301eSmrg * When compare_id is true, this implements the algorithm described
5614a49301eSmrg * in "Sorting of EGLConfigs".  When compare_id is false,
5624a49301eSmrg * EGL_CONFIG_ID is not compared.
5634a49301eSmrg *
5644a49301eSmrg * It returns a negative integer if conf1 is considered to come
5654a49301eSmrg * before conf2;  a positive integer if conf2 is considered to come
5664a49301eSmrg * before conf1;  zero if the ordering cannot be decided.
5674a49301eSmrg *
5684a49301eSmrg * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is
5694a49301eSmrg * ignored here.
5704a49301eSmrg */
5714a49301eSmrgEGLint
5724a49301eSmrg_eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
5734a49301eSmrg                   const _EGLConfig *criteria, EGLBoolean compare_id)
5744a49301eSmrg{
5754a49301eSmrg   const EGLint compare_attribs[] = {
5764a49301eSmrg      EGL_BUFFER_SIZE,
5774a49301eSmrg      EGL_SAMPLE_BUFFERS,
5784a49301eSmrg      EGL_SAMPLES,
5794a49301eSmrg      EGL_DEPTH_SIZE,
5804a49301eSmrg      EGL_STENCIL_SIZE,
5814a49301eSmrg      EGL_ALPHA_MASK_SIZE,
5824a49301eSmrg   };
5834a49301eSmrg   EGLint val1, val2;
5844a49301eSmrg   EGLint i;
5854a49301eSmrg
5864a49301eSmrg   if (conf1 == conf2)
5874a49301eSmrg      return 0;
5884a49301eSmrg
5894a49301eSmrg   /* the enum values have the desired ordering */
5904a49301eSmrg   assert(EGL_NONE < EGL_SLOW_CONFIG);
5914a49301eSmrg   assert(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
5923464ebd5Sriastradh   val1 = conf1->ConfigCaveat - conf2->ConfigCaveat;
5933464ebd5Sriastradh   if (val1)
5943464ebd5Sriastradh      return val1;
5954a49301eSmrg
5964a49301eSmrg   /* the enum values have the desired ordering */
5974a49301eSmrg   assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
5983464ebd5Sriastradh   val1 = conf1->ColorBufferType - conf2->ColorBufferType;
5993464ebd5Sriastradh   if (val1)
6003464ebd5Sriastradh      return val1;
6014a49301eSmrg
6024a49301eSmrg   if (criteria) {
6034a49301eSmrg      val1 = val2 = 0;
6043464ebd5Sriastradh      if (conf1->ColorBufferType == EGL_RGB_BUFFER) {
6053464ebd5Sriastradh         if (criteria->RedSize > 0) {
6063464ebd5Sriastradh            val1 += conf1->RedSize;
6073464ebd5Sriastradh            val2 += conf2->RedSize;
6084a49301eSmrg         }
6093464ebd5Sriastradh         if (criteria->GreenSize > 0) {
6103464ebd5Sriastradh            val1 += conf1->GreenSize;
6113464ebd5Sriastradh            val2 += conf2->GreenSize;
6124a49301eSmrg         }
6133464ebd5Sriastradh         if (criteria->BlueSize > 0) {
6143464ebd5Sriastradh            val1 += conf1->BlueSize;
6153464ebd5Sriastradh            val2 += conf2->BlueSize;
6164a49301eSmrg         }
6174a49301eSmrg      }
6184a49301eSmrg      else {
6193464ebd5Sriastradh         if (criteria->LuminanceSize > 0) {
6203464ebd5Sriastradh            val1 += conf1->LuminanceSize;
6213464ebd5Sriastradh            val2 += conf2->LuminanceSize;
6224a49301eSmrg         }
6234a49301eSmrg      }
6243464ebd5Sriastradh      if (criteria->AlphaSize > 0) {
6253464ebd5Sriastradh         val1 += conf1->AlphaSize;
6263464ebd5Sriastradh         val2 += conf2->AlphaSize;
6274a49301eSmrg      }
6284a49301eSmrg   }
6294a49301eSmrg   else {
6304a49301eSmrg      /* assume the default criteria, which gives no specific ordering */
6314a49301eSmrg      val1 = val2 = 0;
6324a49301eSmrg   }
6334a49301eSmrg
6344a49301eSmrg   /* for color bits, larger one is preferred */
6354a49301eSmrg   if (val1 != val2)
6364a49301eSmrg      return (val2 - val1);
6374a49301eSmrg
6384a49301eSmrg   for (i = 0; i < ARRAY_SIZE(compare_attribs); i++) {
6393464ebd5Sriastradh      val1 = _eglGetConfigKey(conf1, compare_attribs[i]);
6403464ebd5Sriastradh      val2 = _eglGetConfigKey(conf2, compare_attribs[i]);
6414a49301eSmrg      if (val1 != val2)
6424a49301eSmrg         return (val1 - val2);
6434a49301eSmrg   }
6444a49301eSmrg
6454a49301eSmrg   /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
6464a49301eSmrg
6473464ebd5Sriastradh   return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;
6484a49301eSmrg}
6494a49301eSmrg
6504a49301eSmrg
6514a49301eSmrgstatic INLINE
6524a49301eSmrgvoid _eglSwapConfigs(const _EGLConfig **conf1, const _EGLConfig **conf2)
6534a49301eSmrg{
6544a49301eSmrg   const _EGLConfig *tmp = *conf1;
6554a49301eSmrg   *conf1 = *conf2;
6564a49301eSmrg   *conf2 = tmp;
6574a49301eSmrg}
6584a49301eSmrg
6594a49301eSmrg
6604a49301eSmrg/**
6614a49301eSmrg * Quick sort an array of configs.  This differs from the standard
6624a49301eSmrg * qsort() in that the compare function accepts an additional
6634a49301eSmrg * argument.
6644a49301eSmrg */
6654a49301eSmrgvoid
6664a49301eSmrg_eglSortConfigs(const _EGLConfig **configs, EGLint count,
6674a49301eSmrg                EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
6684a49301eSmrg                                  void *),
6694a49301eSmrg                void *priv_data)
6704a49301eSmrg{
6714a49301eSmrg   const EGLint pivot = 0;
6724a49301eSmrg   EGLint i, j;
6734a49301eSmrg
6744a49301eSmrg   if (count <= 1)
6754a49301eSmrg      return;
6764a49301eSmrg
6774a49301eSmrg   _eglSwapConfigs(&configs[pivot], &configs[count / 2]);
6784a49301eSmrg   i = 1;
6794a49301eSmrg   j = count - 1;
6804a49301eSmrg   do {
6814a49301eSmrg      while (i < count && compare(configs[i], configs[pivot], priv_data) < 0)
6824a49301eSmrg         i++;
6834a49301eSmrg      while (compare(configs[j], configs[pivot], priv_data) > 0)
6844a49301eSmrg         j--;
6854a49301eSmrg      if (i < j) {
6864a49301eSmrg         _eglSwapConfigs(&configs[i], &configs[j]);
6874a49301eSmrg         i++;
6884a49301eSmrg         j--;
6894a49301eSmrg      }
6904a49301eSmrg      else if (i == j) {
6914a49301eSmrg         i++;
6924a49301eSmrg         j--;
6934a49301eSmrg         break;
6944a49301eSmrg      }
6954a49301eSmrg   } while (i <= j);
6964a49301eSmrg   _eglSwapConfigs(&configs[pivot], &configs[j]);
6974a49301eSmrg
6984a49301eSmrg   _eglSortConfigs(configs, j, compare, priv_data);
6994a49301eSmrg   _eglSortConfigs(configs + i, count - i, compare, priv_data);
7004a49301eSmrg}
7014a49301eSmrg
7024a49301eSmrg
7034a49301eSmrgstatic int
7044a49301eSmrg_eglFallbackCompare(const _EGLConfig *conf1, const _EGLConfig *conf2,
7054a49301eSmrg                   void *priv_data)
7064a49301eSmrg{
7074a49301eSmrg   const _EGLConfig *criteria = (const _EGLConfig *) priv_data;
7084a49301eSmrg   return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE);
7094a49301eSmrg}
7104a49301eSmrg
7114a49301eSmrg
7124a49301eSmrg/**
7134a49301eSmrg * Typical fallback routine for eglChooseConfig
7144a49301eSmrg */
7154a49301eSmrgEGLBoolean
7164a49301eSmrg_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
7174a49301eSmrg                 EGLConfig *configs, EGLint config_size, EGLint *num_configs)
7184a49301eSmrg{
7194a49301eSmrg   _EGLConfig **configList, criteria;
7204a49301eSmrg   EGLint i, count;
7214a49301eSmrg
7224a49301eSmrg   if (!num_configs)
7234a49301eSmrg      return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs");
7244a49301eSmrg
7253464ebd5Sriastradh   if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
7264a49301eSmrg      return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
7274a49301eSmrg
7283464ebd5Sriastradh   /* get the number of matched configs */
7293464ebd5Sriastradh   count = _eglFilterArray(disp->Configs, NULL, 0,
7303464ebd5Sriastradh         (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
7313464ebd5Sriastradh   if (!count) {
7323464ebd5Sriastradh      *num_configs = count;
7333464ebd5Sriastradh      return EGL_TRUE;
7343464ebd5Sriastradh   }
7353464ebd5Sriastradh
7363464ebd5Sriastradh   configList = malloc(sizeof(*configList) * count);
7374a49301eSmrg   if (!configList)
7384a49301eSmrg      return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
7394a49301eSmrg
7403464ebd5Sriastradh   /* get the matched configs */
7413464ebd5Sriastradh   _eglFilterArray(disp->Configs, (void **) configList, count,
7423464ebd5Sriastradh         (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
7434a49301eSmrg
7444a49301eSmrg   /* perform sorting of configs */
7454a49301eSmrg   if (configs && count) {
7464a49301eSmrg      _eglSortConfigs((const _EGLConfig **) configList, count,
7474a49301eSmrg                      _eglFallbackCompare, (void *) &criteria);
7484a49301eSmrg      count = MIN2(count, config_size);
7494a49301eSmrg      for (i = 0; i < count; i++)
7504a49301eSmrg         configs[i] = _eglGetConfigHandle(configList[i]);
7514a49301eSmrg   }
7524a49301eSmrg
7534a49301eSmrg   free(configList);
7544a49301eSmrg
7554a49301eSmrg   *num_configs = count;
7564a49301eSmrg
7574a49301eSmrg   return EGL_TRUE;
7584a49301eSmrg}
7594a49301eSmrg
7604a49301eSmrg
7614a49301eSmrg/**
7624a49301eSmrg * Fallback for eglGetConfigAttrib.
7634a49301eSmrg */
7644a49301eSmrgEGLBoolean
7654a49301eSmrg_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
7664a49301eSmrg                    EGLint attribute, EGLint *value)
7674a49301eSmrg{
7684a49301eSmrg   if (!_eglIsConfigAttribValid(conf, attribute))
7694a49301eSmrg      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
7703464ebd5Sriastradh
7713464ebd5Sriastradh   /* nonqueryable attributes */
7723464ebd5Sriastradh   switch (attribute) {
7733464ebd5Sriastradh   case EGL_MATCH_NATIVE_PIXMAP:
7743464ebd5Sriastradh      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
7753464ebd5Sriastradh      break;
7763464ebd5Sriastradh   default:
7773464ebd5Sriastradh      break;
7783464ebd5Sriastradh   }
7793464ebd5Sriastradh
7804a49301eSmrg   if (!value)
7814a49301eSmrg      return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib");
7824a49301eSmrg
7833464ebd5Sriastradh   *value = _eglGetConfigKey(conf, attribute);
7844a49301eSmrg   return EGL_TRUE;
7854a49301eSmrg}
7864a49301eSmrg
7874a49301eSmrg
7883464ebd5Sriastradhstatic EGLBoolean
7893464ebd5Sriastradh_eglFlattenConfig(void *elem, void *buffer)
7903464ebd5Sriastradh{
7913464ebd5Sriastradh   _EGLConfig *conf = (_EGLConfig *) elem;
7923464ebd5Sriastradh   EGLConfig *handle = (EGLConfig *) buffer;
7933464ebd5Sriastradh   *handle = _eglGetConfigHandle(conf);
7943464ebd5Sriastradh   return EGL_TRUE;
7953464ebd5Sriastradh}
7963464ebd5Sriastradh
7974a49301eSmrg/**
7984a49301eSmrg * Fallback for eglGetConfigs.
7994a49301eSmrg */
8004a49301eSmrgEGLBoolean
8014a49301eSmrg_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
8024a49301eSmrg               EGLint config_size, EGLint *num_config)
8034a49301eSmrg{
8044a49301eSmrg   if (!num_config)
8054a49301eSmrg      return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
8064a49301eSmrg
8073464ebd5Sriastradh   *num_config = _eglFlattenArray(disp->Configs, (void *) configs,
8083464ebd5Sriastradh         sizeof(configs[0]), config_size, _eglFlattenConfig);
8094a49301eSmrg
8104a49301eSmrg   return EGL_TRUE;
8114a49301eSmrg}
812