예제 #1
0
static EGLBoolean
haiku_add_configs_for_visuals(_EGLDisplay *dpy)
{
	printf("Adding configs\n");

	struct haiku_egl_config* conf;
	conf = CALLOC_STRUCT(haiku_egl_config);

	_eglInitConfig(&conf->base, dpy, 1);
	_eglLog(_EGL_DEBUG,"Config inited\n");
	_eglSetConfigKey(&conf->base, EGL_RED_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_BLUE_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_GREEN_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_LUMINANCE_SIZE, 0);
	_eglSetConfigKey(&conf->base, EGL_ALPHA_SIZE, 8);
	_eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
	EGLint r = (_eglGetConfigKey(&conf->base, EGL_RED_SIZE) 
		+ _eglGetConfigKey(&conf->base, EGL_GREEN_SIZE)
		+ _eglGetConfigKey(&conf->base, EGL_BLUE_SIZE)
		+ _eglGetConfigKey(&conf->base, EGL_ALPHA_SIZE));
	_eglSetConfigKey(&conf->base, EGL_BUFFER_SIZE, r);
	_eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, EGL_NONE);
	_eglSetConfigKey(&conf->base, EGL_CONFIG_ID, 1);
	_eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
	_eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
	_eglSetConfigKey(&conf->base, EGL_STENCIL_SIZE, 0);
	_eglSetConfigKey(&conf->base, EGL_TRANSPARENT_TYPE, EGL_NONE);
	_eglSetConfigKey(&conf->base, EGL_NATIVE_RENDERABLE, EGL_TRUE); // Let's say yes
	_eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0); // No visual
	_eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE, EGL_NONE); // No visual
	_eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, 0x8);
	_eglSetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_SAMPLES, _eglGetConfigKey(&conf->base, EGL_SAMPLE_BUFFERS) == 0 ? 0 : 0);
	_eglSetConfigKey(&conf->base, EGL_DEPTH_SIZE, 24); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_LEVEL, 0);
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_WIDTH, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_HEIGHT, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_MAX_PBUFFER_PIXELS, 0); // TODO: How to get the right value ?
	_eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT /*| EGL_PIXMAP_BIT | EGL_PBUFFER_BIT*/);

	printf("Config configuated\n");
	if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
		_eglLog(_EGL_DEBUG, "Haiku failed to validate config");
		return EGL_FALSE;
	}
	printf("Validated config\n");
   
	_eglLinkConfig(&conf->base);
	if (!_eglGetArraySize(dpy->Configs)) {
		_eglLog(_EGL_WARNING, "Haiku: failed to create any config");
		return EGL_FALSE;
	}
	printf("Config successful!\n");
   
	return EGL_TRUE;
}
예제 #2
0
/**
 * Return true if a config matches the criteria.  This and
 * _eglParseConfigAttribList together implement the algorithm
 * described in "Selection of EGLConfigs".
 *
 * Note that attributes that are special (currently, only
 * EGL_MATCH_NATIVE_PIXMAP) are ignored.
 */
EGLBoolean
_eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
{
   EGLint attr, val, i;
   EGLBoolean matched = EGL_TRUE;

   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
      EGLint cmp;
      if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_IGNORE)
         continue;

      attr = _eglValidationTable[i].attr;
      cmp = _eglGetConfigKey(criteria, attr);
      if (cmp == EGL_DONT_CARE)
         continue;

      val = _eglGetConfigKey(conf, attr);
      switch (_eglValidationTable[i].criterion) {
      case ATTRIB_CRITERION_EXACT:
         if (val != cmp)
            matched = EGL_FALSE;
         break;
      case ATTRIB_CRITERION_ATLEAST:
         if (val < cmp)
            matched = EGL_FALSE;
         break;
      case ATTRIB_CRITERION_MASK:
         if ((val & cmp) != cmp)
            matched = EGL_FALSE;
         break;
      case ATTRIB_CRITERION_SPECIAL:
         /* ignored here */
         break;
      case ATTRIB_CRITERION_IGNORE:
         unreachable("already handled above");
         break;
      }

      if (!matched) {
#ifndef DEBUG
         /* only print the common errors when DEBUG is not defined */
         if (attr != EGL_RENDERABLE_TYPE)
            break;
#endif
         _eglLog(_EGL_DEBUG,
               "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
               val, attr, cmp);
         break;
      }
   }

   return matched;
}
예제 #3
0
/**
 * Fallback for eglGetConfigAttrib.
 */
EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                    EGLint attribute, EGLint *value)
{
   if (!_eglIsConfigAttribValid(conf, attribute))
      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");

   /* nonqueryable attributes */
   switch (attribute) {
   case EGL_MATCH_NATIVE_PIXMAP:
      return _eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
      break;
   default:
      break;
   }

   if (!value)
      return _eglError(EGL_BAD_PARAMETER, "eglGetConfigAttrib");

   *value = _eglGetConfigKey(conf, attribute);
   return EGL_TRUE;
}
예제 #4
0
/**
 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
 */
static _EGLSurface *
dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
		    _EGLConfig *conf, EGLNativeWindowType native_window,
		    const EGLint *attrib_list)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
   struct dri2_egl_surface *dri2_surf;
   xcb_get_geometry_cookie_t cookie;
   xcb_get_geometry_reply_t *reply;
   xcb_screen_iterator_t s;
   xcb_generic_error_t *error;
   xcb_drawable_t window = (uintptr_t )native_window;

   (void) drv;

   dri2_surf = malloc(sizeof *dri2_surf);
   if (!dri2_surf) {
      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
      return NULL;
   }
   
   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
      goto cleanup_surf;

   dri2_surf->region = XCB_NONE;
   if (type == EGL_PBUFFER_BIT) {
      dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn);
      s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
      xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize,
			dri2_surf->drawable, s.data->root,
			dri2_surf->base.Width, dri2_surf->base.Height);
   } else {
      dri2_surf->drawable = window;
   }

   if (dri2_dpy->dri2) {
      dri2_surf->dri_drawable = 
	 (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
					       type == EGL_WINDOW_BIT ?
					       dri2_conf->dri_double_config : 
					       dri2_conf->dri_single_config,
					       dri2_surf);
   } else {
      assert(dri2_dpy->swrast);
      dri2_surf->dri_drawable = 
	 (*dri2_dpy->swrast->createNewDrawable) (dri2_dpy->dri_screen,
						 dri2_conf->dri_double_config,
						 dri2_surf);
   }

   if (dri2_surf->dri_drawable == NULL) {
      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
      goto cleanup_pixmap;
   }
   
   if (dri2_dpy->dri2) {
      xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
   } else {
      swrastCreateDrawable(dri2_dpy, dri2_surf, _eglGetConfigKey(conf, EGL_BUFFER_SIZE));
   }

   if (type != EGL_PBUFFER_BIT) {
      cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
      reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
      if (reply == NULL || error != NULL) {
	 _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
	 free(error);
	 goto cleanup_dri_drawable;
      }

      dri2_surf->base.Width = reply->width;
      dri2_surf->base.Height = reply->height;
      free(reply);
   }

   /* we always copy the back buffer to front */
   dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE;

   return &dri2_surf->base;

 cleanup_dri_drawable:
   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
 cleanup_pixmap:
   if (type == EGL_PBUFFER_BIT)
      xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable);
 cleanup_surf:
   free(dri2_surf);

   return NULL;
}
예제 #5
0
/**
 * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
 */
static _EGLSurface *
dri2_x11_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
                        _EGLConfig *conf, void *native_surface,
                        const EGLint *attrib_list)
{
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
   struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
   struct dri2_egl_surface *dri2_surf;
   xcb_get_geometry_cookie_t cookie;
   xcb_get_geometry_reply_t *reply;
   xcb_screen_iterator_t s;
   xcb_generic_error_t *error;
   xcb_drawable_t drawable;
   xcb_screen_t *screen;
   const __DRIconfig *config;

   STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface));
   drawable = (uintptr_t) native_surface;

   (void) drv;

   dri2_surf = malloc(sizeof *dri2_surf);
   if (!dri2_surf) {
      _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
      return NULL;
   }
   
   if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
      goto cleanup_surf;

   dri2_surf->region = XCB_NONE;
   if (type == EGL_PBUFFER_BIT) {
      s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
      screen = get_xcb_screen(s, dri2_dpy->screen);
      if (!screen) {
         _eglError(EGL_BAD_ALLOC, "failed to get xcb screen");
         goto cleanup_surf;
      }

      dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn);
      xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize,
                       dri2_surf->drawable, screen->root,
			dri2_surf->base.Width, dri2_surf->base.Height);
   } else {
      if (!drawable) {
         if (type == EGL_WINDOW_BIT)
            _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_create_surface");
         else
            _eglError(EGL_BAD_NATIVE_PIXMAP, "dri2_create_surface");
         goto cleanup_surf;
      }
      dri2_surf->drawable = drawable;
   }

   config = dri2_get_dri_config(dri2_conf, type,
                                dri2_surf->base.GLColorspace);

   if (dri2_dpy->dri2) {
      dri2_surf->dri_drawable =
	 (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
					      dri2_surf);
   } else {
      assert(dri2_dpy->swrast);
      dri2_surf->dri_drawable = 
         (*dri2_dpy->swrast->createNewDrawable)(dri2_dpy->dri_screen, config,
                                                dri2_surf);
   }

   if (dri2_surf->dri_drawable == NULL) {
      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
      goto cleanup_pixmap;
   }

   if (type != EGL_PBUFFER_BIT) {
      cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
      reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
      if (error != NULL) {
         if (error->error_code == BadAlloc)
            _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
         else if (type == EGL_WINDOW_BIT)
            _eglError(EGL_BAD_NATIVE_WINDOW, "xcb_get_geometry");
         else
            _eglError(EGL_BAD_NATIVE_PIXMAP, "xcb_get_geometry");
         free(error);
         goto cleanup_dri_drawable;
      } else if (reply == NULL) {
         _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
         goto cleanup_dri_drawable;
      }

      dri2_surf->base.Width = reply->width;
      dri2_surf->base.Height = reply->height;
      dri2_surf->depth = reply->depth;
      free(reply);
   }

   if (dri2_dpy->dri2) {
      xcb_void_cookie_t cookie;
      int conn_error;

      cookie = xcb_dri2_create_drawable_checked(dri2_dpy->conn,
                                                dri2_surf->drawable);
      error = xcb_request_check(dri2_dpy->conn, cookie);
      conn_error = xcb_connection_has_error(dri2_dpy->conn);
      if (conn_error || error != NULL) {
         if (type == EGL_PBUFFER_BIT || conn_error || error->error_code == BadAlloc)
            _eglError(EGL_BAD_ALLOC, "xcb_dri2_create_drawable_checked");
         else if (type == EGL_WINDOW_BIT)
            _eglError(EGL_BAD_NATIVE_WINDOW,
                      "xcb_dri2_create_drawable_checked");
         else
            _eglError(EGL_BAD_NATIVE_PIXMAP,
                      "xcb_dri2_create_drawable_checked");
         free(error);
         goto cleanup_dri_drawable;
      }
   } else {
      if (type == EGL_PBUFFER_BIT) {
         dri2_surf->depth = _eglGetConfigKey(conf, EGL_BUFFER_SIZE);
      }
      swrastCreateDrawable(dri2_dpy, dri2_surf);
   }

   /* we always copy the back buffer to front */
   dri2_surf->base.PostSubBufferSupportedNV = EGL_TRUE;

   return &dri2_surf->base;

 cleanup_dri_drawable:
   dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
 cleanup_pixmap:
   if (type == EGL_PBUFFER_BIT)
      xcb_free_pixmap(dri2_dpy->conn, dri2_surf->drawable);
 cleanup_surf:
   free(dri2_surf);

   return NULL;
}
예제 #6
0
/**
 * Decide the ordering of conf1 and conf2, under the given criteria.
 * When compare_id is true, this implements the algorithm described
 * in "Sorting of EGLConfigs".  When compare_id is false,
 * EGL_CONFIG_ID is not compared.
 *
 * It returns a negative integer if conf1 is considered to come
 * before conf2;  a positive integer if conf2 is considered to come
 * before conf1;  zero if the ordering cannot be decided.
 *
 * Note that EGL_NATIVE_VISUAL_TYPE is platform-dependent and is
 * ignored here.
 */
EGLint
_eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
                   const _EGLConfig *criteria, EGLBoolean compare_id)
{
   const EGLint compare_attribs[] = {
      EGL_BUFFER_SIZE,
      EGL_SAMPLE_BUFFERS,
      EGL_SAMPLES,
      EGL_DEPTH_SIZE,
      EGL_STENCIL_SIZE,
      EGL_ALPHA_MASK_SIZE,
   };
   EGLint val1, val2;
   EGLint i;

   if (conf1 == conf2)
      return 0;

   /* the enum values have the desired ordering */
   STATIC_ASSERT(EGL_NONE < EGL_SLOW_CONFIG);
   STATIC_ASSERT(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG);
   val1 = conf1->ConfigCaveat - conf2->ConfigCaveat;
   if (val1)
      return val1;

   /* the enum values have the desired ordering */
   STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
   val1 = conf1->ColorBufferType - conf2->ColorBufferType;
   if (val1)
      return val1;

   if (criteria) {
      val1 = val2 = 0;
      if (conf1->ColorBufferType == EGL_RGB_BUFFER) {
         if (criteria->RedSize > 0) {
            val1 += conf1->RedSize;
            val2 += conf2->RedSize;
         }
         if (criteria->GreenSize > 0) {
            val1 += conf1->GreenSize;
            val2 += conf2->GreenSize;
         }
         if (criteria->BlueSize > 0) {
            val1 += conf1->BlueSize;
            val2 += conf2->BlueSize;
         }
      }
      else {
         if (criteria->LuminanceSize > 0) {
            val1 += conf1->LuminanceSize;
            val2 += conf2->LuminanceSize;
         }
      }
      if (criteria->AlphaSize > 0) {
         val1 += conf1->AlphaSize;
         val2 += conf2->AlphaSize;
      }
   }
   else {
      /* assume the default criteria, which gives no specific ordering */
      val1 = val2 = 0;
   }

   /* for color bits, larger one is preferred */
   if (val1 != val2)
      return (val2 - val1);

   for (i = 0; i < ARRAY_SIZE(compare_attribs); i++) {
      val1 = _eglGetConfigKey(conf1, compare_attribs[i]);
      val2 = _eglGetConfigKey(conf2, compare_attribs[i]);
      if (val1 != val2)
         return (val1 - val2);
   }

   /* EGL_NATIVE_VISUAL_TYPE cannot be compared here */

   return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;
}
예제 #7
0
/**
 * Return true if a config is valid.  When for_matching is true,
 * EGL_DONT_CARE is accepted as a valid attribute value, and checks
 * for conflicting attribute values are skipped.
 *
 * Note that some attributes are platform-dependent and are not
 * checked.
 */
EGLBoolean
_eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
{
   _EGLDisplay *disp = conf->Display;
   EGLint i, attr, val;
   EGLBoolean valid = EGL_TRUE;

   /* check attributes by their types */
   for (i = 0; i < ARRAY_SIZE(_eglValidationTable); i++) {
      EGLint mask;

      attr = _eglValidationTable[i].attr;
      val = _eglGetConfigKey(conf, attr);

      switch (_eglValidationTable[i].type) {
      case ATTRIB_TYPE_INTEGER:
         switch (attr) {
         case EGL_CONFIG_ID:
            /* config id must be positive */
            if (val <= 0)
               valid = EGL_FALSE;
            break;
         case EGL_SAMPLE_BUFFERS:
            /* there can be at most 1 sample buffer */
            if (val > 1 || val < 0)
               valid = EGL_FALSE;
            break;
         default:
            if (val < 0)
               valid = EGL_FALSE;
            break;
         }
         break;
      case ATTRIB_TYPE_BOOLEAN:
         if (val != EGL_TRUE && val != EGL_FALSE)
            valid = EGL_FALSE;
         break;
      case ATTRIB_TYPE_ENUM:
         switch (attr) {
         case EGL_CONFIG_CAVEAT:
            if (val != EGL_NONE && val != EGL_SLOW_CONFIG &&
                val != EGL_NON_CONFORMANT_CONFIG)
               valid = EGL_FALSE;
            break;
         case EGL_TRANSPARENT_TYPE:
            if (val != EGL_NONE && val != EGL_TRANSPARENT_RGB)
               valid = EGL_FALSE;
            break;
         case EGL_COLOR_BUFFER_TYPE:
            if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER)
               valid = EGL_FALSE;
            break;
         case EGL_COLOR_COMPONENT_TYPE_EXT:
            if (val != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT &&
                val != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
               valid = EGL_FALSE;
            break;
         default:
            unreachable("check _eglValidationTable[]");
            break;
         }
         break;
      case ATTRIB_TYPE_BITMASK:
         switch (attr) {
         case EGL_SURFACE_TYPE:
            mask = EGL_PBUFFER_BIT |
                   EGL_PIXMAP_BIT |
                   EGL_WINDOW_BIT |
                   EGL_VG_COLORSPACE_LINEAR_BIT |
                   EGL_VG_ALPHA_FORMAT_PRE_BIT |
                   EGL_MULTISAMPLE_RESOLVE_BOX_BIT |
                   EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
            if (disp->Extensions.KHR_mutable_render_buffer)
               mask |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
            break;
         case EGL_RENDERABLE_TYPE:
         case EGL_CONFORMANT:
            mask = EGL_OPENGL_ES_BIT |
                   EGL_OPENVG_BIT |
                   EGL_OPENGL_ES2_BIT |
                   EGL_OPENGL_ES3_BIT_KHR |
                   EGL_OPENGL_BIT;
            break;
         default:
            unreachable("check _eglValidationTable[]");
            mask = 0;
            break;
         }
         if (val & ~mask)
            valid = EGL_FALSE;
         break;
      case ATTRIB_TYPE_PLATFORM:
         /* unable to check platform-dependent attributes here */
         break;
      case ATTRIB_TYPE_PSEUDO:
         /* pseudo attributes should not be set */
         if (val != 0)
            valid = EGL_FALSE;
         break;
      }

      if (!valid && for_matching) {
         /* accept EGL_DONT_CARE as a valid value */
         if (val == EGL_DONT_CARE)
            valid = EGL_TRUE;
         if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL)
            valid = EGL_TRUE;
      }
      if (!valid) {
         _eglLog(_EGL_DEBUG,
               "attribute 0x%04x has an invalid value 0x%x", attr, val);
         break;
      }
   }

   /* any invalid attribute value should have been catched */
   if (!valid || for_matching)
      return valid;

   /* now check for conflicting attribute values */

   switch (conf->ColorBufferType) {
   case EGL_RGB_BUFFER:
      if (conf->LuminanceSize)
         valid = EGL_FALSE;
      if (conf->RedSize + conf->GreenSize +
            conf->BlueSize + conf->AlphaSize != conf->BufferSize)
         valid = EGL_FALSE;
      break;
   case EGL_LUMINANCE_BUFFER:
      if (conf->RedSize || conf->GreenSize || conf->BlueSize)
         valid = EGL_FALSE;
      if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
         valid = EGL_FALSE;
      break;
   }
   if (!valid) {
      _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
      return EGL_FALSE;
   }

   if (!conf->SampleBuffers && conf->Samples)
      valid = EGL_FALSE;
   if (!valid) {
      _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers");
      return EGL_FALSE;
   }

   if (!(conf->SurfaceType & EGL_WINDOW_BIT)) {
      if (conf->NativeVisualID != 0 || conf->NativeVisualType != EGL_NONE)
         valid = EGL_FALSE;
   }
   if (!(conf->SurfaceType & EGL_PBUFFER_BIT)) {
      if (conf->BindToTextureRGB || conf->BindToTextureRGBA)
         valid = EGL_FALSE;
   }
   if (!valid) {
      _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding");
      return EGL_FALSE;
   }

   return valid;
}
예제 #8
0
static void
dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
		int depth, xcb_visualtype_t *visual)
{
   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;
   int i;

   dri2_dpy = disp->DriverData;
   _eglInitConfig(&base, disp, id);
   
   i = 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;

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

   /* In EGL, double buffer or not isn't a config attribute.  Pixmaps
    * surfaces are always single buffered, pbuffer surfaces are always
    * back buffers and windows can be either, selected by passing an
    * attribute at window surface construction time.  To support this
    * we ignore all double buffer configs and manipulate the buffer we
    * return in the getBuffer callback to get the behaviour we want. */

   if (double_buffer)
      return;

   if (visual != NULL) {
      if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
	 return;

      _eglSetConfigKey(&base, EGL_SURFACE_TYPE,
		       EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT |
		       EGL_SWAP_BEHAVIOR_PRESERVED_BIT);

      _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_ID, visual->visual_id);
      _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_TYPE, visual->_class);
   } else {
      _eglSetConfigKey(&base, EGL_SURFACE_TYPE,
		       EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
   }

   _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE);
   _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
   if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0)
      _eglSetConfigKey(&base,
		       EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);

   /* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */
   _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
   _eglSetConfigKey(&base, EGL_CONFORMANT, EGL_OPENGL_BIT);

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

   conf = malloc(sizeof *conf);
   if (conf != NULL) {
      memcpy(&conf->base, &base, sizeof base);
      conf->dri_config = dri_config;
      _eglAddConfig(disp, &conf->base);
   }
}