[PATCH] Allow controlling the user of GL_ARB_texture_rectangle
- From: Owen W. Taylor <otaylor redhat com>
- Subject: [PATCH] Allow controlling the user of GL_ARB_texture_rectangle
- Date: Wed, 5 Nov 2008 18:27:30 -0500
cogl/cogl.h.in: Add cogl_texture_new_{with_size,from_data,from_file}_and_options()
These functions allow passing in a set of CoglTextureOptions flags.
Flags replace the auto_mipmap option and additionally control whether
GL_ARB_texture_rectangle is used at all, and is used in preference
to NPOT_textures.
cogl/gl/cogle-texture.c cogl/gles/cogle-texture.c: Implement the
_and_options() variants of the cogl_texture constructors.
glx/clutter-glx-texture-pixmap.c: By default enable GL_ARB_texture_rectangle
for our pixmap textures. Add environment variable
CLUTTER_PIXMAP_TEXTURE_RECTANGLE=[force,disable] to control.
---
clutter/cogl/cogl.h.in | 87 ++++++++++++++++++++++++++++++
clutter/cogl/gl/cogl-texture.c | 64 +++++++++++++++++++---
clutter/cogl/gles/cogl-texture.c | 45 ++++++++++++++-
clutter/glx/clutter-glx-texture-pixmap.c | 59 ++++++++++++++++++---
4 files changed, 236 insertions(+), 19 deletions(-)
diff --git a/clutter/cogl/cogl.h.in b/clutter/cogl/cogl.h.in
index 814ca33..ab3d482 100644
--- a/clutter/cogl/cogl.h.in
+++ b/clutter/cogl/cogl.h.in
@@ -197,6 +197,24 @@ typedef enum
} CoglBufferTarget;
/**
+ * CoglTextureOptions:
+ * @COGL_TEXTURE_ALLOW_RECTANGLE: Use GL_ARB_texture_rectangle if
+ * it's available and GL_ARB_texture_non_power_of_two isn't.
+ * @COGL_TEXTURE_FORCE_RECTANGLE:Use GL_ARB_texture_rectangle
+ * even if GL_ARB_texture_non_power_of_two is available.
+ * @COGL_TEXTURE_AUTO_MIPMAP: enable generation of mipmap pyramid
+ * from the base level image whenever it is updated.
+ *
+ */
+typedef enum
+{
+ COGL_TEXTURE_ALLOW_RECTANGLE = (1 << 1),
+ COGL_TEXTURE_FORCE_RECTANGLE = (1 << 2),
+ COGL_TEXTURE_AUTO_MIPMAP = (1 << 3)
+
+} CoglTextureOptions;
+
+/**
* CoglTextureVertex:
* @x: Model x-coordinate
* @y: Model y-coordinate
@@ -654,6 +672,27 @@ CoglHandle cogl_texture_new_with_size (guint width,
CoglPixelFormat internal_format);
/**
+ * cogl_texture_new_with_size_and_options:
+ * @width: width of texture in pixels.
+ * @height: height of texture in pixels.
+ * @max_waste: maximum extra horizontal and|or vertical margin pixels to make
+ * texture fit GPU limitations.
+ * @options: a set of bit flags that affect how the texture is created
+ * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
+ * texture.
+ *
+ * Create a new texture with specified dimensions, options, and pixel format.
+ *
+ * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE
+ * if texture creation failed.
+ */
+CoglHandle cogl_texture_new_with_size_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format);
+
+/**
* cogl_texture_new_from_file:
* @filename: the file to load
* @max_waste: maximum extra horizontal and|or vertical margin pixels to make
@@ -676,6 +715,27 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename,
GError **error);
/**
+ * cogl_texture_new_from_file_and_options:
+ * @filename: the file to load
+ * @max_waste: maximum extra horizontal and|or vertical margin pixels to make
+ * texture fit GPU limitations.
+ * @options: a set of bit flags that affect how the texture is created
+ * @internal_format: the #CoglPixelFormat to use for the GPU storage of the
+ * texture.
+ * @error: a #GError or NULL.
+ *
+ * Load an image file from disk with specified options.
+ *
+ * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE
+ * if creating the texture failed.
+ */
+CoglHandle cogl_texture_new_from_file_and_options (const gchar *filename,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format,
+ GError **error);
+
+/**
* cogl_texture_new_from_data:
* @width: width of texture in pixels.
* @height: height of texture in pixels.
@@ -704,6 +764,33 @@ CoglHandle cogl_texture_new_from_data (guint width,
const guchar *data);
/**
+ * cogl_texture_new_from_data_and_options:
+ * @width: width of texture in pixels.
+ * @height: height of texture in pixels.
+ * @max_waste: maximum extra horizontal and|or vertical margin pixels to make
+ * @options: a set of bit flags that affect how the texture is created.
+ * @format: the #CoglPixelFormat the buffer is stored in in RAM
+ * @internal_format: the #CoglPixelFormat that will be used for storing the
+ * buffer on the GPU.
+ * @rowstride: the memory offset in bytes between the starts of scanlines in
+ * @data.
+ * @data: pointer the memory region where the source buffer resides.
+ *
+ * Create a new cogl texture based on data residing in memory with specified options
+ *
+ * Returns: a #CoglHandle to the newly created texture or COGL_INVALID_HANDLE
+ * if creating the texture failed.
+ */
+CoglHandle cogl_texture_new_from_data_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat format,
+ CoglPixelFormat internal_format,
+ guint rowstride,
+ const guchar *data);
+
+/**
* cogl_texture_new_from_foreign:
* @gl_handle: opengl target type of foreign texture
* @gl_target: opengl handle of foreign texture.
diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c
index 7cae747..f5b37a2 100644
--- a/clutter/cogl/gl/cogl-texture.c
+++ b/clutter/cogl/gl/cogl-texture.c
@@ -788,7 +788,8 @@ _cogl_texture_size_supported (GLenum gl_target,
}
static gboolean
-_cogl_texture_slices_create (CoglTexture *tex)
+_cogl_texture_slices_create (CoglTexture *tex,
+ CoglTextureOptions options)
{
gint bpp;
gint max_width;
@@ -807,15 +808,20 @@ _cogl_texture_slices_create (CoglTexture *tex)
bpp = _cogl_get_format_bpp (tex->bitmap.format);
/* Initialize size of largest slice according to supported features*/
- if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
+ if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT) &&
+ ((options & COGL_TEXTURE_FORCE_RECTANGLE) == 0 ||
+ !cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE)))
{
+ g_printerr("NPOT!\n");
max_width = tex->bitmap.width;
max_height = tex->bitmap.height;
tex->gl_target = GL_TEXTURE_2D;
slices_for_size = _cogl_rect_slices_for_size;
}
- else if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE))
+ else if (cogl_features_available (COGL_FEATURE_TEXTURE_RECTANGLE) &&
+ ((options & (COGL_TEXTURE_ALLOW_RECTANGLE | COGL_TEXTURE_FORCE_RECTANGLE)) != 0))
{
+ g_printerr("RECTANGLE!\n");
max_width = tex->bitmap.width;
max_height = tex->bitmap.height;
tex->gl_target = GL_TEXTURE_RECTANGLE_ARB;
@@ -823,6 +829,7 @@ _cogl_texture_slices_create (CoglTexture *tex)
}
else
{
+ g_printerr("SLICED!\n");
max_width = cogl_util_next_p2 (tex->bitmap.width);
max_height = cogl_util_next_p2 (tex->bitmap.height);
tex->gl_target = GL_TEXTURE_2D;
@@ -1208,6 +1215,18 @@ cogl_texture_new_with_size (guint width,
gboolean auto_mipmap,
CoglPixelFormat internal_format)
{
+ return cogl_texture_new_with_size_and_options (width, height, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ internal_format);
+}
+
+CoglHandle
+cogl_texture_new_with_size_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format)
+{
CoglTexture *tex;
gint bpp;
gint rowstride;
@@ -1227,7 +1246,7 @@ cogl_texture_new_with_size (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap.width = width;
tex->bitmap.height = height;
@@ -1252,7 +1271,7 @@ cogl_texture_new_with_size (guint width,
&tex->gl_type);
/* Create slices for the given format and size */
- if (!_cogl_texture_slices_create (tex))
+ if (!_cogl_texture_slices_create (tex, options))
{
_cogl_texture_free (tex);
return COGL_INVALID_HANDLE;
@@ -1271,6 +1290,21 @@ cogl_texture_new_from_data (guint width,
guint rowstride,
const guchar *data)
{
+ return cogl_texture_new_from_data_and_options (width, height, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ format, internal_format, rowstride, data);
+}
+
+CoglHandle
+cogl_texture_new_from_data_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat format,
+ CoglPixelFormat internal_format,
+ guint rowstride,
+ const guchar *data)
+{
CoglTexture *tex;
gint bpp;
@@ -1291,7 +1325,7 @@ cogl_texture_new_from_data (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap.width = width;
tex->bitmap.height = height;
@@ -1319,7 +1353,7 @@ cogl_texture_new_from_data (guint width,
return COGL_INVALID_HANDLE;
}
- if (!_cogl_texture_slices_create (tex))
+ if (!_cogl_texture_slices_create (tex, options))
{
_cogl_texture_free (tex);
return COGL_INVALID_HANDLE;
@@ -1343,6 +1377,18 @@ cogl_texture_new_from_file (const gchar *filename,
CoglPixelFormat internal_format,
GError **error)
{
+ return cogl_texture_new_from_file_and_options (filename, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ internal_format, error);
+}
+
+CoglHandle
+cogl_texture_new_from_file_and_options (const gchar *filename,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format,
+ GError **error)
+{
CoglBitmap bmp;
CoglTexture *tex;
@@ -1368,7 +1414,7 @@ cogl_texture_new_from_file (const gchar *filename,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap = bmp;
tex->bitmap_owner = TRUE;
@@ -1395,7 +1441,7 @@ cogl_texture_new_from_file (const gchar *filename,
return COGL_INVALID_HANDLE;
}
- if (!_cogl_texture_slices_create (tex))
+ if (!_cogl_texture_slices_create (tex, options))
{
_cogl_texture_free (tex);
return COGL_INVALID_HANDLE;
diff --git a/clutter/cogl/gles/cogl-texture.c b/clutter/cogl/gles/cogl-texture.c
index 97cd258..bf0f004 100644
--- a/clutter/cogl/gles/cogl-texture.c
+++ b/clutter/cogl/gles/cogl-texture.c
@@ -1168,6 +1168,18 @@ cogl_texture_new_with_size (guint width,
gboolean auto_mipmap,
CoglPixelFormat internal_format)
{
+ return cogl_texture_new_with_size_and_options (width, height, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ internal_format);
+}
+
+CoglHandle
+cogl_texture_new_with_size_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format)
+{
CoglTexture *tex;
gint bpp;
gint rowstride;
@@ -1187,7 +1199,7 @@ cogl_texture_new_with_size (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap.width = width;
tex->bitmap.height = height;
@@ -1230,6 +1242,21 @@ cogl_texture_new_from_data (guint width,
guint rowstride,
const guchar *data)
{
+ return cogl_texture_new_from_data_and_options (width, height, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ format, internal_format, rowstride, data);
+}
+
+CoglHandle
+cogl_texture_new_from_data_and_options (guint width,
+ guint height,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat format,
+ CoglPixelFormat internal_format,
+ guint rowstride,
+ const guchar *data)
+{
CoglTexture *tex;
gint bpp;
@@ -1250,7 +1277,7 @@ cogl_texture_new_from_data (guint width,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap.width = width;
tex->bitmap.height = height;
@@ -1302,6 +1329,18 @@ cogl_texture_new_from_file (const gchar *filename,
CoglPixelFormat internal_format,
GError **error)
{
+ return cogl_texture_new_from_file_and_options (filename, max_waste,
+ auto_mipmap ? COGL_TEXTURE_AUTO_MIPMAP : 0,
+ internal_format, error);
+}
+
+CoglHandle
+cogl_texture_new_from_file_and_options (const gchar *filename,
+ gint max_waste,
+ CoglTextureOptions options,
+ CoglPixelFormat internal_format,
+ GError **error)
+{
CoglBitmap bmp;
CoglTexture *tex;
@@ -1327,7 +1366,7 @@ cogl_texture_new_from_file (const gchar *filename,
COGL_HANDLE_DEBUG_NEW (texture, tex);
tex->is_foreign = FALSE;
- tex->auto_mipmap = auto_mipmap;
+ tex->auto_mipmap = (options & COGL_TEXTURE_AUTO_MIPMAP) != 0;
tex->bitmap = bmp;
tex->bitmap_owner = TRUE;
diff --git a/clutter/glx/clutter-glx-texture-pixmap.c b/clutter/glx/clutter-glx-texture-pixmap.c
index 0083fbf..4a2f3fe 100644
--- a/clutter/glx/clutter-glx-texture-pixmap.c
+++ b/clutter/glx/clutter-glx-texture-pixmap.c
@@ -48,6 +48,8 @@
#include "config.h"
#endif
+#include <string.h>
+
#include "../x11/clutter-x11-texture-pixmap.h"
#include "clutter-glx-texture-pixmap.h"
#include "clutter-glx.h"
@@ -200,6 +202,36 @@ clutter_glx_texture_pixmap_notify (GObject *object, GParamSpec *pspec)
}
}
+static CoglTextureOptions
+get_texture_options (void)
+{
+ static gboolean initialized = FALSE;
+ static CoglTextureOptions options;
+
+ if (!initialized)
+ {
+ const char *env_string;
+
+ initialized = TRUE;
+
+ options = COGL_TEXTURE_ALLOW_RECTANGLE;
+
+ env_string = g_getenv ("CLUTTER_PIXMAP_TEXTURE_RECTANGLE");
+ if (env_string)
+ {
+ if (strcasecmp (env_string, "force") == 0)
+ options |= COGL_TEXTURE_FORCE_RECTANGLE;
+ else if (strcasecmp (env_string, "disable") == 0)
+ options &= ~COGL_TEXTURE_ALLOW_RECTANGLE;
+ else if (env_string[0])
+ g_warning ("Unknown value for CLUTTER_PIXMAP_TEXTURE_RECTANGLE, "
+ "should be 'force' or 'disable'");
+ }
+ }
+
+ return options;
+}
+
static gboolean
create_cogl_texture (ClutterTexture *texture,
guint width,
@@ -207,10 +239,10 @@ create_cogl_texture (ClutterTexture *texture,
{
CoglHandle handle;
- handle
- = cogl_texture_new_with_size (width, height,
- -1, FALSE,
- COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT);
+ handle = cogl_texture_new_with_size_and_options (width, height,
+ -1,
+ get_texture_options(),
+ COGL_PIXEL_FORMAT_RGBA_8888|COGL_BGR_BIT);
if (handle)
{
@@ -718,9 +750,22 @@ clutter_glx_texture_pixmap_using_extension (ClutterGLXTexturePixmap *texture)
priv = CLUTTER_GLX_TEXTURE_PIXMAP (texture)->priv;
- return (_have_tex_from_pixmap_ext
- && (clutter_feature_available (COGL_FEATURE_TEXTURE_NPOT)
- || clutter_feature_available (COGL_FEATURE_TEXTURE_RECTANGLE)));
+ if (!_have_tex_from_pixmap_ext)
+ return FALSE;
+
+ /* EXT_texture_from_pixmap is only useful if we have the
+ * ARGB_texture_non_power_of_two or ARB_texture_rectangle
+ */
+ if (clutter_feature_available (COGL_FEATURE_TEXTURE_NPOT))
+ return TRUE;
+
+ if (clutter_feature_available (COGL_FEATURE_TEXTURE_RECTANGLE))
+ {
+ CoglTextureOptions options = get_texture_options();
+ return (options & (COGL_TEXTURE_ALLOW_RECTANGLE | COGL_TEXTURE_FORCE_RECTANGLE)) != 0;
+ }
+
+ return FALSE;
}
/**
--
1.6.0.3
--=-1gOaMbTF0IoDctbcw5Ip
Content-Disposition: attachment; filename*0=0002-Use-ARB_texture_rectangle-for-pixmap-shape-rectangle.pat; filename*1=ch
Content-Type: text/x-patch; name="0002-Use-ARB_texture_rectangle-for-pixmap-shape-rectangle.patch"; charset="UTF-8"
Content-Transfer-Encoding: 7bit
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]