static void clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) { ClutterGLXTexturePixmapPrivate *priv = texture->priv; GLXPixmap glx_pixmap = None; int attribs[7], i = 0, mipmap = 0; GLXFBConfig *fbconfig; Display *dpy; guint depth; Pixmap pixmap; guint pixmap_width, pixmap_height; ClutterBackendGLX *backend_glx; ClutterTextureQuality quality; CLUTTER_NOTE (TEXTURE, "Creating GLXPixmap"); backend_glx = CLUTTER_BACKEND_GLX(clutter_get_default_backend ()); dpy = clutter_x11_get_default_display (); if (priv->use_fallback == TRUE || !clutter_glx_texture_pixmap_using_extension (texture)) goto cleanup; priv->use_fallback = FALSE; g_object_get (texture, "pixmap-width", &pixmap_width, "pixmap-height", &pixmap_height, "pixmap-depth", &depth, "pixmap", &pixmap, NULL); if (!pixmap) { goto cleanup; } fbconfig = get_fbconfig_for_depth (depth); if (!fbconfig) { g_warning ("Could not find an FBConfig for selected pixmap"); goto cleanup; } attribs[i++] = GLX_TEXTURE_FORMAT_EXT; if (depth == 24) { attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; } else if (depth == 32) { attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; } else { g_warning ("Pixmap with depth bellow 24 are not supported"); goto cleanup; } quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)); if (quality == CLUTTER_TEXTURE_QUALITY_HIGH) mipmap = 1; attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = mipmap; attribs[i++] = GLX_TEXTURE_TARGET_EXT; attribs[i++] = GLX_TEXTURE_2D_EXT; attribs[i++] = None; clutter_x11_trap_x_errors (); glx_pixmap = glXCreatePixmap (dpy, *fbconfig, pixmap, attribs); XSync (dpy, FALSE); if (clutter_x11_untrap_x_errors ()) { CLUTTER_NOTE (TEXTURE, "Failed to create GLXPixmap"); /* Make sure we don't think the call actually succeeded */ glx_pixmap = None; } g_free (fbconfig); cleanup: if (priv->glx_pixmap) clutter_glx_texture_pixmap_free_glx_pixmap (texture); if (glx_pixmap != None) { priv->glx_pixmap = glx_pixmap; create_cogl_texture (CLUTTER_TEXTURE (texture), pixmap_width, pixmap_height); CLUTTER_NOTE (TEXTURE, "Created GLXPixmap"); return; } else { priv->use_fallback = TRUE; priv->glx_pixmap = None; /* Some fucky logic here - we've fallen back and need to make sure * we realize here.. */ clutter_actor_realize (CLUTTER_ACTOR (texture)); } }
static void try_create_glx_pixmap (CoglTexturePixmapX11 *tex_pixmap, gboolean mipmap) { Display *dpy; /* We have to initialize this *opaque* variable because gcc tries to * be too smart for its own good and warns that the variable may be * used uninitialized otherwise. */ GLXFBConfig fb_config = (GLXFBConfig)0; int attribs[7]; int i = 0; GLenum target; CoglXlibTrapState trap_state; _COGL_GET_CONTEXT (ctxt, NO_RETVAL); tex_pixmap->pixmap_bound = FALSE; tex_pixmap->glx_pixmap = None; if ((ctxt->winsys.feature_flags & COGL_WINSYS_FEATURE_TEXTURE_FROM_PIXMAP) == 0) return; dpy = _cogl_xlib_get_display (); if (!get_fbconfig_for_depth (tex_pixmap->depth, &fb_config, &tex_pixmap->glx_can_mipmap)) { COGL_NOTE (TEXTURE_PIXMAP, "No suitable FBConfig found for depth %i", tex_pixmap->depth); return; } if (should_use_rectangle ()) { target = GLX_TEXTURE_RECTANGLE_EXT; tex_pixmap->glx_can_mipmap = FALSE; } else target = GLX_TEXTURE_2D_EXT; if (!tex_pixmap->glx_can_mipmap) mipmap = FALSE; attribs[i++] = GLX_TEXTURE_FORMAT_EXT; if (tex_pixmap->depth == 24) attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; else if (tex_pixmap->depth == 32) attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; else return; attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = mipmap; attribs[i++] = GLX_TEXTURE_TARGET_EXT; attribs[i++] = target; attribs[i++] = None; /* We need to trap errors from glXCreatePixmap because it can sometimes fail during normal usage. For example on NVidia it gets upset if you try to create two GLXPixmaps for the same drawable. */ _cogl_xlib_trap_errors (&trap_state); tex_pixmap->glx_pixmap = glXCreatePixmap (dpy, fb_config, tex_pixmap->pixmap, attribs); tex_pixmap->glx_pixmap_has_mipmap = mipmap; XSync (dpy, False); if (_cogl_xlib_untrap_errors (&trap_state)) { COGL_NOTE (TEXTURE_PIXMAP, "Failed to create pixmap for %p", tex_pixmap); _cogl_xlib_trap_errors (&trap_state); glXDestroyPixmap (dpy, tex_pixmap->glx_pixmap); XSync (dpy, False); _cogl_xlib_untrap_errors (&trap_state); tex_pixmap->glx_pixmap = None; } }