From 52c6f0ab9889e51e40a915c3caa10e7fb69c8f25 Mon Sep 17 00:00:00 2001 From: Matthew Allum Date: Fri, 31 Oct 2008 16:59:51 +0000 Subject: [PATCH] 2008-10-31 Matthew Allum * clutter/clutter-texture.c: (clutter_texture_set_filter_quality), (clutter_texture_get_filter_quality): Fix up some logic, typos. * clutter/glx/clutter-glx-texture-pixmap.c: Improve support for mipmaped TFP textures. --- ChangeLog | 9 +++ clutter/clutter-texture.c | 14 ++-- clutter/glx/clutter-glx-texture-pixmap.c | 84 ++++++++++++++++++++---- 3 files changed, 86 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d8f1be3b..c5da147a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-10-31 Matthew Allum + + * clutter/clutter-texture.c: (clutter_texture_set_filter_quality), + (clutter_texture_get_filter_quality): + Fix up some logic, typos. + + * clutter/glx/clutter-glx-texture-pixmap.c: + Improve support for mipmaped TFP textures. + 2008-10-31 Emmanuele Bassi Bug 1200 - Crash with invalid DISPLAY diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index f8e4cebe2..5182142aa 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -1393,10 +1393,12 @@ clutter_texture_set_filter_quality (ClutterTexture *texture, priv = texture->priv; old_quality = clutter_texture_get_filter_quality (texture); + if (filter_quality != old_quality) { priv->filter_quality = filter_quality; + /* Is this actually needed - causes problems with TFP mipmaps */ if (priv->texture != COGL_INVALID_HANDLE) cogl_texture_set_filters (priv->texture, clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), @@ -1409,7 +1411,7 @@ clutter_texture_set_filter_quality (ClutterTexture *texture, clutter_texture_unrealize (CLUTTER_ACTOR (texture)); clutter_texture_realize (CLUTTER_ACTOR (texture)); } - + g_object_notify (G_OBJECT (texture), "filter-quality"); if (CLUTTER_ACTOR_IS_VISIBLE (texture)) @@ -1436,15 +1438,7 @@ clutter_texture_get_filter_quality (ClutterTexture *texture) priv = texture->priv; - if (priv->texture == COGL_INVALID_HANDLE) - return texture->priv->max_tile_waste; - else - /* If we have a valid texture handle then use the filter quality - from that instead */ - - return cogl_filters_to_clutter_texture_quality ( - cogl_texture_get_min_filter (texture->priv->texture), - cogl_texture_get_mag_filter (texture->priv->texture)); + return priv->filter_quality; } /** diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c index ca006f790..3ae6f54f8 100644 --- a/clutter/glx/clutter-glx-texture-pixmap.c +++ b/clutter/glx/clutter-glx-texture-pixmap.c @@ -66,8 +66,12 @@ typedef void (*ReleaseTexImage) (Display *display, GLXDrawable drawable, int buffer); +typedef void (*GenerateMipmap) (GLenum target); + + static BindTexImage _gl_bind_tex_image = NULL; static ReleaseTexImage _gl_release_tex_image = NULL; +static GenerateMipmap _gl_generate_mipmap = NULL; static gboolean _have_tex_from_pixmap_ext = FALSE; static gboolean _ext_check_done = FALSE; @@ -80,7 +84,7 @@ struct _ClutterGLXTexturePixmapPrivate gboolean use_fallback; gboolean bound; - + gint can_mipmap; }; static void @@ -115,6 +119,14 @@ texture_bind (ClutterGLXTexturePixmap *tex) /* FIXME: fire off an error here? */ glBindTexture (target, handle); + if (clutter_texture_get_filter_quality (CLUTTER_TEXTURE (tex)) + == CLUTTER_TEXTURE_QUALITY_HIGH && tex->priv->can_mipmap) + { + cogl_texture_set_filters (cogl_tex, + CGL_LINEAR_MIPMAP_LINEAR, + CGL_LINEAR); + } + return TRUE; } @@ -148,6 +160,9 @@ clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self) _have_tex_from_pixmap_ext = TRUE; } + _gl_generate_mipmap = + (GenerateMipmap)cogl_get_proc_address ("glGenerateMipmapEXT"); + _ext_check_done = TRUE; } } @@ -200,7 +215,7 @@ create_cogl_texture (ClutterTexture *texture, if (handle) { clutter_texture_set_cogl_texture (texture, handle); - + CLUTTER_ACTOR_SET_FLAGS (texture, CLUTTER_ACTOR_REALIZED); clutter_glx_texture_pixmap_update_area @@ -292,13 +307,23 @@ clutter_glx_texture_pixmap_unrealize (ClutterActor *actor) } static GLXFBConfig * -get_fbconfig_for_depth (guint depth) +get_fbconfig_for_depth (ClutterGLXTexturePixmap *texture, guint depth) { GLXFBConfig *fbconfigs, *ret = NULL; int n_elements, i, found; Display *dpy; int db, stencil, alpha, mipmap, rgba, value; + static GLXFBConfig *cached_config = NULL; + static gboolean have_cached_config = FALSE; + static int cached_mipmap = 0; + + if (have_cached_config) + { + texture->priv->can_mipmap = cached_mipmap; + return cached_config; + } + dpy = clutter_x11_get_default_display (); fbconfigs = glXGetFBConfigs (dpy, @@ -312,7 +337,6 @@ get_fbconfig_for_depth (guint depth) found = n_elements; - for (i = 0; i < n_elements; i++) { XVisualInfo *vi; @@ -383,6 +407,19 @@ get_fbconfig_for_depth (guint depth) stencil = value; + if (_gl_generate_mipmap) + { + glXGetFBConfigAttrib (dpy, + fbconfigs[i], + GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value); + + if (value < mipmap) + continue; + + mipmap = value; + } + found = i; } @@ -395,6 +432,10 @@ get_fbconfig_for_depth (guint depth) if (n_elements) XFree (fbconfigs); + have_cached_config = TRUE; + cached_config = ret; + texture->priv->can_mipmap = cached_mipmap = mipmap; + return ret; } @@ -473,7 +514,7 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) goto cleanup; } - fbconfig = get_fbconfig_for_depth (depth); + fbconfig = get_fbconfig_for_depth (texture, depth); if (!fbconfig) { @@ -499,9 +540,9 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)); - if (quality == CLUTTER_TEXTURE_QUALITY_HIGH) - mipmap = 1; - + if (quality == CLUTTER_TEXTURE_QUALITY_HIGH && priv->can_mipmap) + mipmap = priv->can_mipmap; + attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = mipmap; @@ -525,8 +566,6 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) glx_pixmap = None; } - g_free (fbconfig); - cleanup: if (priv->glx_pixmap) @@ -536,7 +575,8 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture) { priv->glx_pixmap = glx_pixmap; - create_cogl_texture (CLUTTER_TEXTURE (texture), pixmap_width, pixmap_height); + create_cogl_texture (CLUTTER_TEXTURE (texture), + pixmap_width, pixmap_height); CLUTTER_NOTE (TEXTURE, "Created GLXPixmap"); @@ -605,6 +645,28 @@ clutter_glx_texture_pixmap_update_area (ClutterX11TexturePixmap *texture, CLUTTER_NOTE (TEXTURE, "Update bind_tex_image failed"); priv->bound = TRUE; + + if (_gl_generate_mipmap + && priv->can_mipmap + && clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)) + == CLUTTER_TEXTURE_QUALITY_HIGH) + { + /* FIXME: It may make more sense to set a flag here and only + * generate the mipmap on a pre paint.. compressing need + * to call generate mipmap + * May break clones however.. + */ + GLuint handle = 0; + GLenum target = 0; + CoglHandle cogl_tex; + cogl_tex = clutter_texture_get_cogl_texture + (CLUTTER_TEXTURE(texture)); + + cogl_texture_get_gl_texture (cogl_tex, &handle, &target); + + _gl_generate_mipmap (target); + } + } else g_warning ("Failed to bind initial tex");