2008-10-31 Matthew Allum <mallum@openedhand.com>

* 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.
This commit is contained in:
Matthew Allum 2008-10-31 16:59:51 +00:00
parent 91f2653b71
commit 52c6f0ab98
3 changed files with 86 additions and 21 deletions

View File

@ -1,3 +1,12 @@
2008-10-31 Matthew Allum <mallum@openedhand.com>
* 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 <ebassi@linux.intel.com> 2008-10-31 Emmanuele Bassi <ebassi@linux.intel.com>
Bug 1200 - Crash with invalid DISPLAY Bug 1200 - Crash with invalid DISPLAY

View File

@ -1393,10 +1393,12 @@ clutter_texture_set_filter_quality (ClutterTexture *texture,
priv = texture->priv; priv = texture->priv;
old_quality = clutter_texture_get_filter_quality (texture); old_quality = clutter_texture_get_filter_quality (texture);
if (filter_quality != old_quality) if (filter_quality != old_quality)
{ {
priv->filter_quality = filter_quality; priv->filter_quality = filter_quality;
/* Is this actually needed - causes problems with TFP mipmaps */
if (priv->texture != COGL_INVALID_HANDLE) if (priv->texture != COGL_INVALID_HANDLE)
cogl_texture_set_filters (priv->texture, cogl_texture_set_filters (priv->texture,
clutter_texture_quality_to_cogl_min_filter (priv->filter_quality), 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_unrealize (CLUTTER_ACTOR (texture));
clutter_texture_realize (CLUTTER_ACTOR (texture)); clutter_texture_realize (CLUTTER_ACTOR (texture));
} }
g_object_notify (G_OBJECT (texture), "filter-quality"); g_object_notify (G_OBJECT (texture), "filter-quality");
if (CLUTTER_ACTOR_IS_VISIBLE (texture)) if (CLUTTER_ACTOR_IS_VISIBLE (texture))
@ -1436,15 +1438,7 @@ clutter_texture_get_filter_quality (ClutterTexture *texture)
priv = texture->priv; priv = texture->priv;
if (priv->texture == COGL_INVALID_HANDLE) return priv->filter_quality;
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));
} }
/** /**

View File

@ -66,8 +66,12 @@ typedef void (*ReleaseTexImage) (Display *display,
GLXDrawable drawable, GLXDrawable drawable,
int buffer); int buffer);
typedef void (*GenerateMipmap) (GLenum target);
static BindTexImage _gl_bind_tex_image = NULL; static BindTexImage _gl_bind_tex_image = NULL;
static ReleaseTexImage _gl_release_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 _have_tex_from_pixmap_ext = FALSE;
static gboolean _ext_check_done = FALSE; static gboolean _ext_check_done = FALSE;
@ -80,7 +84,7 @@ struct _ClutterGLXTexturePixmapPrivate
gboolean use_fallback; gboolean use_fallback;
gboolean bound; gboolean bound;
gint can_mipmap;
}; };
static void static void
@ -115,6 +119,14 @@ texture_bind (ClutterGLXTexturePixmap *tex)
/* FIXME: fire off an error here? */ /* FIXME: fire off an error here? */
glBindTexture (target, handle); 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; return TRUE;
} }
@ -148,6 +160,9 @@ clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self)
_have_tex_from_pixmap_ext = TRUE; _have_tex_from_pixmap_ext = TRUE;
} }
_gl_generate_mipmap =
(GenerateMipmap)cogl_get_proc_address ("glGenerateMipmapEXT");
_ext_check_done = TRUE; _ext_check_done = TRUE;
} }
} }
@ -200,7 +215,7 @@ create_cogl_texture (ClutterTexture *texture,
if (handle) if (handle)
{ {
clutter_texture_set_cogl_texture (texture, handle); clutter_texture_set_cogl_texture (texture, handle);
CLUTTER_ACTOR_SET_FLAGS (texture, CLUTTER_ACTOR_REALIZED); CLUTTER_ACTOR_SET_FLAGS (texture, CLUTTER_ACTOR_REALIZED);
clutter_glx_texture_pixmap_update_area clutter_glx_texture_pixmap_update_area
@ -292,13 +307,23 @@ clutter_glx_texture_pixmap_unrealize (ClutterActor *actor)
} }
static GLXFBConfig * static GLXFBConfig *
get_fbconfig_for_depth (guint depth) get_fbconfig_for_depth (ClutterGLXTexturePixmap *texture, guint depth)
{ {
GLXFBConfig *fbconfigs, *ret = NULL; GLXFBConfig *fbconfigs, *ret = NULL;
int n_elements, i, found; int n_elements, i, found;
Display *dpy; Display *dpy;
int db, stencil, alpha, mipmap, rgba, value; 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 (); dpy = clutter_x11_get_default_display ();
fbconfigs = glXGetFBConfigs (dpy, fbconfigs = glXGetFBConfigs (dpy,
@ -312,7 +337,6 @@ get_fbconfig_for_depth (guint depth)
found = n_elements; found = n_elements;
for (i = 0; i < n_elements; i++) for (i = 0; i < n_elements; i++)
{ {
XVisualInfo *vi; XVisualInfo *vi;
@ -383,6 +407,19 @@ get_fbconfig_for_depth (guint depth)
stencil = value; 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; found = i;
} }
@ -395,6 +432,10 @@ get_fbconfig_for_depth (guint depth)
if (n_elements) if (n_elements)
XFree (fbconfigs); XFree (fbconfigs);
have_cached_config = TRUE;
cached_config = ret;
texture->priv->can_mipmap = cached_mipmap = mipmap;
return ret; return ret;
} }
@ -473,7 +514,7 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
goto cleanup; goto cleanup;
} }
fbconfig = get_fbconfig_for_depth (depth); fbconfig = get_fbconfig_for_depth (texture, depth);
if (!fbconfig) if (!fbconfig)
{ {
@ -499,9 +540,9 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture)); quality = clutter_texture_get_filter_quality (CLUTTER_TEXTURE (texture));
if (quality == CLUTTER_TEXTURE_QUALITY_HIGH) if (quality == CLUTTER_TEXTURE_QUALITY_HIGH && priv->can_mipmap)
mipmap = 1; mipmap = priv->can_mipmap;
attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = GLX_MIPMAP_TEXTURE_EXT;
attribs[i++] = mipmap; attribs[i++] = mipmap;
@ -525,8 +566,6 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
glx_pixmap = None; glx_pixmap = None;
} }
g_free (fbconfig);
cleanup: cleanup:
if (priv->glx_pixmap) if (priv->glx_pixmap)
@ -536,7 +575,8 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
{ {
priv->glx_pixmap = glx_pixmap; 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"); 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"); CLUTTER_NOTE (TEXTURE, "Update bind_tex_image failed");
priv->bound = TRUE; 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 else
g_warning ("Failed to bind initial tex"); g_warning ("Failed to bind initial tex");