mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 11:32:04 +00:00
Bug 1297 - Bring back support for GL_ARB_texture_rectangle
* clutter/cogl/gl/cogl-texture.c (cogl_texture_new_from_foreign, (_cogl_texture_quad_hw, cogl_texture_polygon), (_cogl_texture_quad_sw): Support GL_ARB_texture_rectangle textures * clutter/glx/clutter-glx-texture-pixmap.c: Use rectangle textures when NPOTs are not available or it is forced by the CLUTTER_PIXMAP_TEXTURE_RECTANGLE environment variable. * clutter/cogl/gl/cogl.c (cogl_enable): Allow enabling GL_TEXTURE_RECTANGLE_ARB.
This commit is contained in:
parent
89e7552ca3
commit
98035e4d8a
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
|||||||
|
2008-12-04 Neil Roberts <neil@linux.intel.com>
|
||||||
|
|
||||||
|
Bug 1297 - Bring back support for GL_ARB_texture_rectangle
|
||||||
|
|
||||||
|
* clutter/cogl/gl/cogl-texture.c (cogl_texture_new_from_foreign,
|
||||||
|
(_cogl_texture_quad_hw, cogl_texture_polygon),
|
||||||
|
(_cogl_texture_quad_sw): Support GL_ARB_texture_rectangle textures
|
||||||
|
|
||||||
|
* clutter/glx/clutter-glx-texture-pixmap.c: Use rectangle textures
|
||||||
|
when NPOTs are not available or it is forced by the
|
||||||
|
CLUTTER_PIXMAP_TEXTURE_RECTANGLE environment variable.
|
||||||
|
|
||||||
|
* clutter/cogl/gl/cogl.c (cogl_enable): Allow enabling
|
||||||
|
GL_TEXTURE_RECTANGLE_ARB.
|
||||||
|
|
||||||
2008-12-04 Neil Roberts <neil@linux.intel.com>
|
2008-12-04 Neil Roberts <neil@linux.intel.com>
|
||||||
|
|
||||||
Bug 1172 - Disjoint paths and clip to path
|
Bug 1172 - Disjoint paths and clip to path
|
||||||
|
@ -1427,16 +1427,22 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
CoglTexture *tex;
|
CoglTexture *tex;
|
||||||
CoglTexSliceSpan x_span;
|
CoglTexSliceSpan x_span;
|
||||||
CoglTexSliceSpan y_span;
|
CoglTexSliceSpan y_span;
|
||||||
|
|
||||||
/* Allow 2-dimensional textures only */
|
/* GL_ARB_texture_rectangle textures are supported if they are
|
||||||
if (gl_target != GL_TEXTURE_2D)
|
created from foreign because some chipsets have trouble with
|
||||||
|
GL_ARB_texture_non_power_of_two. There is no Cogl call to create
|
||||||
|
them directly to emphasize the fact that they don't work fully
|
||||||
|
(for example, no mipmapping and complicated shader support) */
|
||||||
|
|
||||||
|
/* Allow 2-dimensional or rectangle textures only */
|
||||||
|
if (gl_target != GL_TEXTURE_2D && gl_target != CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Make sure it is a valid GL texture object */
|
/* Make sure it is a valid GL texture object */
|
||||||
gl_istexture = glIsTexture (gl_handle);
|
gl_istexture = glIsTexture (gl_handle);
|
||||||
if (gl_istexture == GL_FALSE)
|
if (gl_istexture == GL_FALSE)
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Make sure binding succeeds */
|
/* Make sure binding succeeds */
|
||||||
gl_error = glGetError ();
|
gl_error = glGetError ();
|
||||||
glBindTexture (gl_target, gl_handle);
|
glBindTexture (gl_target, gl_handle);
|
||||||
@ -1928,8 +1934,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
GLfloat tex_coords[8];
|
GLfloat tex_coords[8];
|
||||||
GLfloat quad_coords[8];
|
GLfloat quad_coords[8];
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||||
| COGL_ENABLE_VERTEX_ARRAY
|
|
||||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
@ -1937,9 +1942,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
|
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
|
||||||
|
else
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
||||||
|
|
||||||
if (ctx->color_alpha < 255
|
if (ctx->color_alpha < 255
|
||||||
|| tex->bitmap.format & COGL_A_BIT)
|
|| tex->bitmap.format & COGL_A_BIT)
|
||||||
{
|
{
|
||||||
@ -2020,17 +2029,19 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
|
|
||||||
slice_qy2 = first_qy +
|
slice_qy2 = first_qy +
|
||||||
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
|
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
|
||||||
|
|
||||||
/* Localize slice texture coordinates */
|
/* Localize slice texture coordinates */
|
||||||
slice_ty1 = iter_y.intersect_start - iter_y.pos;
|
slice_ty1 = iter_y.intersect_start - iter_y.pos;
|
||||||
slice_ty2 = iter_y.intersect_end - iter_y.pos;
|
slice_ty2 = iter_y.intersect_end - iter_y.pos;
|
||||||
|
|
||||||
/* Normalize texture coordinates to current slice
|
/* Normalize texture coordinates to current slice
|
||||||
(rectangle texture targets take denormalized) */
|
(rectangle texture targets take denormalized) */
|
||||||
slice_ty1 /= iter_y.span->size;
|
if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
slice_ty2 /= iter_y.span->size;
|
{
|
||||||
|
slice_ty1 /= iter_y.span->size;
|
||||||
|
slice_ty2 /= iter_y.span->size;
|
||||||
|
}
|
||||||
|
|
||||||
/* Iterate until whole quad width covered */
|
/* Iterate until whole quad width covered */
|
||||||
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
|
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
|
||||||
first_tx, tx1, tx2) ;
|
first_tx, tx1, tx2) ;
|
||||||
@ -2050,12 +2061,15 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
|||||||
/* Localize slice texture coordinates */
|
/* Localize slice texture coordinates */
|
||||||
slice_tx1 = iter_x.intersect_start - iter_x.pos;
|
slice_tx1 = iter_x.intersect_start - iter_x.pos;
|
||||||
slice_tx2 = iter_x.intersect_end - iter_x.pos;
|
slice_tx2 = iter_x.intersect_end - iter_x.pos;
|
||||||
|
|
||||||
/* Normalize texture coordinates to current slice
|
/* Normalize texture coordinates to current slice
|
||||||
(rectangle texture targets take denormalized) */
|
(rectangle texture targets take denormalized) */
|
||||||
slice_tx1 /= iter_x.span->size;
|
if (tex->gl_target != CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
slice_tx2 /= iter_x.span->size;
|
{
|
||||||
|
slice_tx1 /= iter_x.span->size;
|
||||||
|
slice_tx2 /= iter_x.span->size;
|
||||||
|
}
|
||||||
|
|
||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
|
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
|
||||||
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1));
|
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1));
|
||||||
@ -2111,8 +2125,7 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
CoglTexSliceSpan *x_span;
|
CoglTexSliceSpan *x_span;
|
||||||
CoglTexSliceSpan *y_span;
|
CoglTexSliceSpan *y_span;
|
||||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||||
| COGL_ENABLE_VERTEX_ARRAY
|
|
||||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||||
|
|
||||||
#if COGL_DEBUG
|
#if COGL_DEBUG
|
||||||
@ -2122,6 +2135,11 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
|
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
|
||||||
|
else
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
||||||
|
|
||||||
if (ctx->color_alpha < 255
|
if (ctx->color_alpha < 255
|
||||||
|| tex->bitmap.format & COGL_A_BIT)
|
|| tex->bitmap.format & COGL_A_BIT)
|
||||||
{
|
{
|
||||||
@ -2162,8 +2180,17 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
|||||||
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
|
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
|
||||||
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
|
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
|
||||||
|
|
||||||
|
/* Denormalize texture coordinates for rectangle textures */
|
||||||
|
if (tex->gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
{
|
||||||
|
tx1 *= x_span->size;
|
||||||
|
tx2 *= x_span->size;
|
||||||
|
ty1 *= y_span->size;
|
||||||
|
ty2 *= y_span->size;
|
||||||
|
}
|
||||||
|
|
||||||
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
||||||
|
|
||||||
/* Draw textured quad */
|
/* Draw textured quad */
|
||||||
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
|
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
|
||||||
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
|
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
|
||||||
@ -2215,7 +2242,8 @@ cogl_texture_rectangle (CoglHandle handle,
|
|||||||
(no waste) or all of the coordinates are in the range [0,1] then
|
(no waste) or all of the coordinates are in the range [0,1] then
|
||||||
we can use hardware tiling */
|
we can use hardware tiling */
|
||||||
if (tex->slice_gl_handles->len == 1
|
if (tex->slice_gl_handles->len == 1
|
||||||
&& (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
|
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
|
||||||
|
&& tex->gl_target == GL_TEXTURE_2D)
|
||||||
|| (tx1 >= 0 && tx1 <= COGL_FIXED_1
|
|| (tx1 >= 0 && tx1 <= COGL_FIXED_1
|
||||||
&& tx2 >= 0 && tx2 <= COGL_FIXED_1
|
&& tx2 >= 0 && tx2 <= COGL_FIXED_1
|
||||||
&& ty1 >= 0 && ty1 <= COGL_FIXED_1
|
&& ty1 >= 0 && ty1 <= COGL_FIXED_1
|
||||||
@ -2289,11 +2317,14 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare GL state */
|
/* Prepare GL state */
|
||||||
enable_flags = (COGL_ENABLE_TEXTURE_2D
|
enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||||
| COGL_ENABLE_VERTEX_ARRAY
|
|
||||||
| COGL_ENABLE_TEXCOORD_ARRAY
|
| COGL_ENABLE_TEXCOORD_ARRAY
|
||||||
| COGL_ENABLE_BLEND);
|
| COGL_ENABLE_BLEND);
|
||||||
|
|
||||||
|
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
|
||||||
|
else
|
||||||
|
enable_flags |= COGL_ENABLE_TEXTURE_2D;
|
||||||
|
|
||||||
if (ctx->enable_backface_culling)
|
if (ctx->enable_backface_culling)
|
||||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||||
@ -2335,19 +2366,31 @@ cogl_texture_polygon (CoglHandle handle,
|
|||||||
OpenGL */
|
OpenGL */
|
||||||
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
||||||
{
|
{
|
||||||
|
CoglFixed tx, ty;
|
||||||
|
|
||||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
|
|
||||||
|
tx = ((vertices[i].tx
|
||||||
|
- (COGL_FIXED_FROM_INT (x_span->start)
|
||||||
|
/ tex->bitmap.width))
|
||||||
|
* tex->bitmap.width / x_span->size);
|
||||||
|
ty = ((vertices[i].ty
|
||||||
|
- (COGL_FIXED_FROM_INT (y_span->start)
|
||||||
|
/ tex->bitmap.height))
|
||||||
|
* tex->bitmap.height / y_span->size);
|
||||||
|
|
||||||
|
/* Scale the coordinates up for rectangle textures */
|
||||||
|
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
{
|
||||||
|
tx *= x_span->size;
|
||||||
|
ty *= y_span->size;
|
||||||
|
}
|
||||||
|
|
||||||
p->v[0] = CFX_F(vertices[i].x);
|
p->v[0] = CFX_F(vertices[i].x);
|
||||||
p->v[1] = CFX_F(vertices[i].y);
|
p->v[1] = CFX_F(vertices[i].y);
|
||||||
p->v[2] = CFX_F(vertices[i].z);
|
p->v[2] = CFX_F(vertices[i].z);
|
||||||
p->t[0] = CFX_F((vertices[i].tx
|
p->t[0] = CFX_F(tx);
|
||||||
- (COGL_FIXED_FROM_INT (x_span->start)
|
p->t[1] = CFX_F(ty);
|
||||||
/ tex->bitmap.width))
|
|
||||||
* tex->bitmap.width / x_span->size);
|
|
||||||
p->t[1] = CFX_F((vertices[i].ty
|
|
||||||
- (COGL_FIXED_FROM_INT (y_span->start)
|
|
||||||
/ tex->bitmap.height))
|
|
||||||
* tex->bitmap.height / y_span->size);
|
|
||||||
p->c[0] = cogl_color_get_red_byte(&vertices[i].color);
|
p->c[0] = cogl_color_get_red_byte(&vertices[i].color);
|
||||||
p->c[1] = cogl_color_get_green_byte(&vertices[i].color);
|
p->c[1] = cogl_color_get_green_byte(&vertices[i].color);
|
||||||
p->c[2] = cogl_color_get_blue_byte(&vertices[i].color);
|
p->c[2] = cogl_color_get_blue_byte(&vertices[i].color);
|
||||||
|
@ -318,7 +318,13 @@ cogl_enable (gulong flags)
|
|||||||
cogl_toggle_flag (ctx, flags,
|
cogl_toggle_flag (ctx, flags,
|
||||||
COGL_ENABLE_BACKFACE_CULLING,
|
COGL_ENABLE_BACKFACE_CULLING,
|
||||||
GL_CULL_FACE);
|
GL_CULL_FACE);
|
||||||
|
|
||||||
|
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
||||||
|
cogl_toggle_flag (ctx, flags,
|
||||||
|
COGL_ENABLE_TEXTURE_RECT,
|
||||||
|
GL_TEXTURE_RECTANGLE_ARB);
|
||||||
|
#endif
|
||||||
|
|
||||||
cogl_toggle_client_flag (ctx, flags,
|
cogl_toggle_client_flag (ctx, flags,
|
||||||
COGL_ENABLE_VERTEX_ARRAY,
|
COGL_ENABLE_VERTEX_ARRAY,
|
||||||
GL_VERTEX_ARRAY);
|
GL_VERTEX_ARRAY);
|
||||||
|
@ -40,6 +40,13 @@
|
|||||||
*
|
*
|
||||||
* The class requires the GLX_EXT_texture_from_pixmap OpenGL extension
|
* The class requires the GLX_EXT_texture_from_pixmap OpenGL extension
|
||||||
* (http://people.freedesktop.org/~davidr/GLX_EXT_texture_from_pixmap.txt)
|
* (http://people.freedesktop.org/~davidr/GLX_EXT_texture_from_pixmap.txt)
|
||||||
|
*
|
||||||
|
* The GL_ARB_texture_non_power_of_two extension will be used if it is
|
||||||
|
* available. Otherwise it will try to use the
|
||||||
|
* GL_ARB_texture_rectangle extension. If both are available you can
|
||||||
|
* force it to prefer the rectangle extension by setting the
|
||||||
|
* CLUTTER_PIXMAP_TEXTURE_RECTANGLE to 'force'. To prevent it ever
|
||||||
|
* using the rectangle extension you can set it to 'disable'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +55,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "../x11/clutter-x11-texture-pixmap.h"
|
#include "../x11/clutter-x11-texture-pixmap.h"
|
||||||
#include "clutter-glx-texture-pixmap.h"
|
#include "clutter-glx-texture-pixmap.h"
|
||||||
#include "clutter-glx.h"
|
#include "clutter-glx.h"
|
||||||
@ -68,12 +77,20 @@ typedef void (*ReleaseTexImage) (Display *display,
|
|||||||
|
|
||||||
typedef void (*GenerateMipmap) (GLenum target);
|
typedef void (*GenerateMipmap) (GLenum target);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
CLUTTER_GLX_RECTANGLE_DISALLOW,
|
||||||
|
CLUTTER_GLX_RECTANGLE_ALLOW,
|
||||||
|
CLUTTER_GLX_RECTANGLE_FORCE
|
||||||
|
} RectangleState;
|
||||||
|
|
||||||
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 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;
|
||||||
|
static gboolean _have_tex_rectangle = FALSE;
|
||||||
|
static RectangleState _rectangle_state = CLUTTER_GLX_RECTANGLE_ALLOW;
|
||||||
|
|
||||||
struct _ClutterGLXTexturePixmapPrivate
|
struct _ClutterGLXTexturePixmapPrivate
|
||||||
{
|
{
|
||||||
@ -86,6 +103,8 @@ struct _ClutterGLXTexturePixmapPrivate
|
|||||||
gboolean bound;
|
gboolean bound;
|
||||||
gint can_mipmap;
|
gint can_mipmap;
|
||||||
gint mipmap_generate_queued;
|
gint mipmap_generate_queued;
|
||||||
|
|
||||||
|
gboolean using_rectangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -170,7 +189,9 @@ clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self)
|
|||||||
|
|
||||||
if (_ext_check_done == FALSE)
|
if (_ext_check_done == FALSE)
|
||||||
{
|
{
|
||||||
|
const char *gl_extensions = NULL;
|
||||||
const gchar *glx_extensions = NULL;
|
const gchar *glx_extensions = NULL;
|
||||||
|
const char *rect_env;
|
||||||
|
|
||||||
glx_extensions =
|
glx_extensions =
|
||||||
glXQueryExtensionsString (clutter_x11_get_default_display (),
|
glXQueryExtensionsString (clutter_x11_get_default_display (),
|
||||||
@ -191,16 +212,59 @@ clutter_glx_texture_pixmap_init (ClutterGLXTexturePixmap *self)
|
|||||||
_gl_generate_mipmap =
|
_gl_generate_mipmap =
|
||||||
(GenerateMipmap)cogl_get_proc_address ("glGenerateMipmapEXT");
|
(GenerateMipmap)cogl_get_proc_address ("glGenerateMipmapEXT");
|
||||||
|
|
||||||
|
gl_extensions = (char *) glGetString (GL_EXTENSIONS);
|
||||||
|
_have_tex_rectangle = cogl_check_extension ("GL_ARB_texture_rectangle",
|
||||||
|
gl_extensions);
|
||||||
|
|
||||||
|
if ((rect_env = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE")))
|
||||||
|
{
|
||||||
|
if (strcasecmp (rect_env, "force") == 0)
|
||||||
|
_rectangle_state = CLUTTER_GLX_RECTANGLE_FORCE;
|
||||||
|
else if (strcasecmp (rect_env, "disable") == 0)
|
||||||
|
_rectangle_state = CLUTTER_GLX_RECTANGLE_DISALLOW;
|
||||||
|
else if (rect_env[0])
|
||||||
|
g_warning ("Unknown value for CLUTTER_PIXMAP_TEXTURE_RECTANGLE, "
|
||||||
|
"should be 'force' or 'disable'");
|
||||||
|
}
|
||||||
|
|
||||||
_ext_check_done = TRUE;
|
_ext_check_done = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_glx_texture_pixmap_free_rectangle (ClutterGLXTexturePixmap *texture)
|
||||||
|
{
|
||||||
|
ClutterGLXTexturePixmapPrivate *priv = texture->priv;
|
||||||
|
CoglHandle cogl_tex;
|
||||||
|
|
||||||
|
/* Cogl won't free the GL texture resource if it was created with
|
||||||
|
new_from_foreign so we need to free it manually */
|
||||||
|
if (priv->using_rectangle)
|
||||||
|
{
|
||||||
|
cogl_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (texture));
|
||||||
|
|
||||||
|
if (cogl_tex != COGL_INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
GLuint gl_handle;
|
||||||
|
GLenum gl_target;
|
||||||
|
|
||||||
|
cogl_texture_get_gl_texture (cogl_tex, &gl_handle, &gl_target);
|
||||||
|
|
||||||
|
if (gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
glDeleteTextures (1, &gl_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->using_rectangle = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_glx_texture_pixmap_dispose (GObject *object)
|
clutter_glx_texture_pixmap_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
ClutterGLXTexturePixmapPrivate *priv;
|
ClutterGLXTexturePixmap *texture = CLUTTER_GLX_TEXTURE_PIXMAP (object);
|
||||||
|
ClutterGLXTexturePixmapPrivate *priv = texture->priv;
|
||||||
|
|
||||||
priv = CLUTTER_GLX_TEXTURE_PIXMAP (object)->priv;
|
clutter_glx_texture_pixmap_free_rectangle (texture);
|
||||||
|
|
||||||
if (priv->glx_pixmap != None)
|
if (priv->glx_pixmap != None)
|
||||||
{
|
{
|
||||||
@ -228,20 +292,70 @@ clutter_glx_texture_pixmap_notify (GObject *object, GParamSpec *pspec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
should_use_rectangle (void)
|
||||||
|
{
|
||||||
|
/* Use the rectangle only if it is available and either:
|
||||||
|
|
||||||
|
the CLUTTER_PIXMAP_TEXTURE_RECTANGLE environment variable is
|
||||||
|
set to 'force'
|
||||||
|
|
||||||
|
*or*
|
||||||
|
|
||||||
|
the env var is set to 'allow' (which is the default) and NPOTs
|
||||||
|
textures are not available */
|
||||||
|
return _have_tex_rectangle
|
||||||
|
&& ((_rectangle_state == CLUTTER_GLX_RECTANGLE_ALLOW
|
||||||
|
&& !clutter_feature_available (CLUTTER_FEATURE_TEXTURE_NPOT))
|
||||||
|
|| _rectangle_state == CLUTTER_GLX_RECTANGLE_FORCE);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
create_cogl_texture (ClutterTexture *texture,
|
create_cogl_texture (ClutterTexture *texture,
|
||||||
guint width,
|
guint width,
|
||||||
guint height)
|
guint height)
|
||||||
{
|
{
|
||||||
|
ClutterGLXTexturePixmap *texture_glx = CLUTTER_GLX_TEXTURE_PIXMAP (texture);
|
||||||
|
ClutterGLXTexturePixmapPrivate *priv = texture_glx->priv;
|
||||||
CoglHandle handle;
|
CoglHandle handle;
|
||||||
|
gboolean using_rectangle;
|
||||||
|
|
||||||
handle
|
/* We want to use the GL_ARB_texture_rectangle extension on some
|
||||||
= cogl_texture_new_with_size (width, height,
|
chipsets because GL_ARB_texture_non_power_of_two is not always
|
||||||
-1, FALSE,
|
supported or might be buggy */
|
||||||
COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT);
|
if (should_use_rectangle ())
|
||||||
|
{
|
||||||
|
GLuint tex = 0;
|
||||||
|
|
||||||
|
using_rectangle = TRUE;
|
||||||
|
|
||||||
|
glGenTextures (1, &tex);
|
||||||
|
glBindTexture (CGL_TEXTURE_RECTANGLE_ARB, tex);
|
||||||
|
glTexImage2D (CGL_TEXTURE_RECTANGLE_ARB, 0,
|
||||||
|
GL_RGBA, width, height,
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
|
||||||
|
handle = cogl_texture_new_from_foreign (tex, CGL_TEXTURE_RECTANGLE_ARB,
|
||||||
|
width, height,
|
||||||
|
0, 0,
|
||||||
|
COGL_PIXEL_FORMAT_RGBA_8888
|
||||||
|
| COGL_BGR_BIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle
|
||||||
|
= cogl_texture_new_with_size (width, height,
|
||||||
|
-1, FALSE,
|
||||||
|
COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT);
|
||||||
|
|
||||||
|
using_rectangle = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
|
clutter_glx_texture_pixmap_free_rectangle (texture_glx);
|
||||||
|
priv->using_rectangle = using_rectangle;
|
||||||
|
|
||||||
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);
|
||||||
@ -301,12 +415,14 @@ clutter_glx_texture_pixmap_realize (ClutterActor *actor)
|
|||||||
static void
|
static void
|
||||||
clutter_glx_texture_pixmap_unrealize (ClutterActor *actor)
|
clutter_glx_texture_pixmap_unrealize (ClutterActor *actor)
|
||||||
{
|
{
|
||||||
ClutterGLXTexturePixmapPrivate *priv;
|
ClutterGLXTexturePixmap *texture = CLUTTER_GLX_TEXTURE_PIXMAP (actor);
|
||||||
|
ClutterGLXTexturePixmapPrivate *priv = texture->priv;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
|
|
||||||
priv = CLUTTER_GLX_TEXTURE_PIXMAP (actor)->priv;
|
|
||||||
dpy = clutter_x11_get_default_display();
|
dpy = clutter_x11_get_default_display();
|
||||||
|
|
||||||
|
clutter_glx_texture_pixmap_free_rectangle (texture);
|
||||||
|
|
||||||
if (!_have_tex_from_pixmap_ext)
|
if (!_have_tex_from_pixmap_ext)
|
||||||
{
|
{
|
||||||
CLUTTER_ACTOR_CLASS (clutter_glx_texture_pixmap_parent_class)->
|
CLUTTER_ACTOR_CLASS (clutter_glx_texture_pixmap_parent_class)->
|
||||||
@ -575,7 +691,8 @@ clutter_glx_texture_pixmap_create_glx_pixmap (ClutterGLXTexturePixmap *texture)
|
|||||||
|
|
||||||
attribs[i++] = GLX_TEXTURE_TARGET_EXT;
|
attribs[i++] = GLX_TEXTURE_TARGET_EXT;
|
||||||
|
|
||||||
attribs[i++] = GLX_TEXTURE_2D_EXT;
|
attribs[i++] = (should_use_rectangle ()
|
||||||
|
? GLX_TEXTURE_RECTANGLE_EXT : GLX_TEXTURE_2D_EXT);
|
||||||
|
|
||||||
attribs[i++] = None;
|
attribs[i++] = None;
|
||||||
|
|
||||||
@ -637,13 +754,12 @@ clutter_glx_texture_pixmap_update_area (ClutterX11TexturePixmap *texture,
|
|||||||
gint width,
|
gint width,
|
||||||
gint height)
|
gint height)
|
||||||
{
|
{
|
||||||
ClutterGLXTexturePixmapPrivate *priv;
|
ClutterGLXTexturePixmap *texture_glx = CLUTTER_GLX_TEXTURE_PIXMAP (texture);
|
||||||
|
ClutterGLXTexturePixmapPrivate *priv = texture_glx->priv;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
|
|
||||||
|
|
||||||
CLUTTER_NOTE (TEXTURE, "Updating texture pixmap");
|
CLUTTER_NOTE (TEXTURE, "Updating texture pixmap");
|
||||||
|
|
||||||
priv = CLUTTER_GLX_TEXTURE_PIXMAP (texture)->priv;
|
|
||||||
dpy = clutter_x11_get_default_display();
|
dpy = clutter_x11_get_default_display();
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (texture))
|
if (!CLUTTER_ACTOR_IS_REALIZED (texture))
|
||||||
@ -652,6 +768,9 @@ clutter_glx_texture_pixmap_update_area (ClutterX11TexturePixmap *texture,
|
|||||||
if (priv->use_fallback)
|
if (priv->use_fallback)
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (TEXTURE, "Falling back to X11");
|
CLUTTER_NOTE (TEXTURE, "Falling back to X11");
|
||||||
|
|
||||||
|
clutter_glx_texture_pixmap_free_rectangle (texture_glx);
|
||||||
|
|
||||||
parent_class->update_area (texture,
|
parent_class->update_area (texture,
|
||||||
x, y,
|
x, y,
|
||||||
width, height);
|
width, height);
|
||||||
|
Loading…
Reference in New Issue
Block a user