Example #1
0
/**
 * A helper function for implementing eglChooseConfig.  See _eglFilterArray and
 * _eglSortConfigs for the meanings of match and compare.
 */
EGLBoolean
_eglFilterConfigArray(_EGLArray *array, EGLConfig *configs,
                      EGLint config_size, EGLint *num_configs,
                      EGLBoolean (*match)(const _EGLConfig *, void *),
                      EGLint (*compare)(const _EGLConfig *, const _EGLConfig *,
                                        void *),
                      void *priv_data)
{
   _EGLConfig **configList;
   EGLint i, count;

   if (!num_configs)
      return _eglError(EGL_BAD_PARAMETER, "eglChooseConfig");

   /* get the number of matched configs */
   count = _eglFilterArray(array, NULL, 0,
         (_EGLArrayForEach) match, priv_data);
   if (!count) {
      *num_configs = count;
      return EGL_TRUE;
   }

   configList = malloc(sizeof(*configList) * count);
   if (!configList)
      return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");

   /* get the matched configs */
   _eglFilterArray(array, (void **) configList, count,
         (_EGLArrayForEach) match, priv_data);

   /* perform sorting of configs */
   if (configs && count) {
      _eglSortConfigs((const _EGLConfig **) configList, count,
                      compare, priv_data);
      count = MIN2(count, config_size);
      for (i = 0; i < count; i++)
         configs[i] = _eglGetConfigHandle(configList[i]);
   }

   free(configList);

   *num_configs = count;

   return EGL_TRUE;
}
Example #2
0
struct dri2_egl_config *
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
		int depth, EGLint surface_type, const EGLint *attr_list,
		const unsigned int *rgba_masks)
{
   struct dri2_egl_config *conf;
   struct dri2_egl_display *dri2_dpy;
   _EGLConfig base;
   unsigned int attrib, value, double_buffer;
   EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
   unsigned int dri_masks[4] = { 0, 0, 0, 0 };
   _EGLConfig *matching_config;
   EGLint num_configs = 0;
   EGLint config_id;
   int i;

   dri2_dpy = disp->DriverData;
   _eglInitConfig(&base, disp, id);
   
   i = 0;
   double_buffer = 0;
   bind_to_texture_rgb = 0;
   bind_to_texture_rgba = 0;

   while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
      switch (attrib) {
      case __DRI_ATTRIB_RENDER_TYPE:
	 if (value & __DRI_ATTRIB_RGBA_BIT)
	    value = EGL_RGB_BUFFER;
	 else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
	    value = EGL_LUMINANCE_BUFFER;
	 else
	    /* not valid */;
	 _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value);
	 break;	 

      case __DRI_ATTRIB_CONFIG_CAVEAT:
         if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
            value = EGL_NON_CONFORMANT_CONFIG;
         else if (value & __DRI_ATTRIB_SLOW_BIT)
            value = EGL_SLOW_CONFIG;
	 else
	    value = EGL_NONE;
	 _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value);
         break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
	 bind_to_texture_rgb = value;
	 break;

      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
	 bind_to_texture_rgba = value;
	 break;

      case __DRI_ATTRIB_DOUBLE_BUFFER:
	 double_buffer = value;
	 break;

      case __DRI_ATTRIB_RED_MASK:
         dri_masks[0] = value;
         break;

      case __DRI_ATTRIB_GREEN_MASK:
         dri_masks[1] = value;
         break;

      case __DRI_ATTRIB_BLUE_MASK:
         dri_masks[2] = value;
         break;

      case __DRI_ATTRIB_ALPHA_MASK:
         dri_masks[3] = value;
         break;

      default:
	 key = dri2_to_egl_attribute_map[attrib];
	 if (key != 0)
	    _eglSetConfigKey(&base, key, value);
	 break;
      }
   }

   if (attr_list)
      for (i = 0; attr_list[i] != EGL_NONE; i += 2)
         _eglSetConfigKey(&base, attr_list[i], attr_list[i+1]);

   if (depth > 0 && depth != base.BufferSize)
      return NULL;

   if (rgba_masks && memcmp(rgba_masks, dri_masks, sizeof(dri_masks)))
      return NULL;

   base.NativeRenderable = EGL_TRUE;

   base.SurfaceType = surface_type;
   if (surface_type & (EGL_PBUFFER_BIT |
       (disp->Extensions.NOK_texture_from_pixmap ? EGL_PIXMAP_BIT : 0))) {
      base.BindToTextureRGB = bind_to_texture_rgb;
      if (base.AlphaSize > 0)
         base.BindToTextureRGBA = bind_to_texture_rgba;
   }

   base.RenderableType = disp->ClientAPIs;
   base.Conformant = disp->ClientAPIs;

   if (!_eglValidateConfig(&base, EGL_FALSE)) {
      _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
      return NULL;
   }

   config_id = base.ConfigID;
   base.ConfigID    = EGL_DONT_CARE;
   base.SurfaceType = EGL_DONT_CARE;
   num_configs = _eglFilterArray(disp->Configs, (void **) &matching_config, 1,
                                 (_EGLArrayForEach) dri2_match_config, &base);

   if (num_configs == 1) {
      conf = (struct dri2_egl_config *) matching_config;

      if (double_buffer && !conf->dri_double_config)
         conf->dri_double_config = dri_config;
      else if (!double_buffer && !conf->dri_single_config)
         conf->dri_single_config = dri_config;
      else
         /* a similar config type is already added (unlikely) => discard */
         return NULL;
   }
   else if (num_configs == 0) {
      conf = malloc(sizeof *conf);
      if (conf == NULL)
         return NULL;

      memcpy(&conf->base, &base, sizeof base);
      if (double_buffer) {
         conf->dri_double_config = dri_config;
         conf->dri_single_config = NULL;
      } else {
         conf->dri_single_config = dri_config;
         conf->dri_double_config = NULL;
      }
      conf->base.SurfaceType = 0;
      conf->base.ConfigID = config_id;

      _eglLinkConfig(&conf->base);
   }
   else {
      assert(0);
      return NULL;
   }

   if (double_buffer) {
      surface_type &= ~EGL_PIXMAP_BIT;

      if (dri2_dpy->swap_available) {
         conf->base.MinSwapInterval = 0;
         conf->base.MaxSwapInterval = 1000; /* XXX arbitrary value */
      }
   }

   conf->base.SurfaceType |= surface_type;

   return conf;
}