meta-texture-rectangle: Use Cogl's API to create a rectangle texture
Cogl now has public experimental API to create a rectangle texture which we can use instead of creating a foreign texture with GL. This avoids Mutter depending on Cogl including a GL header from its public headers which it might not do in future. https://bugzilla.gnome.org/show_bug.cgi?id=672711
This commit is contained in:
parent
a22859a64a
commit
ed358c8f4b
@ -250,7 +250,6 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
|
|||||||
int i;
|
int i;
|
||||||
int n_rects;
|
int n_rects;
|
||||||
int stride;
|
int stride;
|
||||||
GLenum paint_gl_target;
|
|
||||||
|
|
||||||
/* If we have no shape region and no (or an empty) overlay region, we
|
/* If we have no shape region and no (or an empty) overlay region, we
|
||||||
* don't need to create a full mask texture, so quit early. */
|
* don't need to create a full mask texture, so quit early. */
|
||||||
@ -293,26 +292,14 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
|
|||||||
|
|
||||||
install_overlay_path (stex, mask_data, tex_width, tex_height, stride);
|
install_overlay_path (stex, mask_data, tex_width, tex_height, stride);
|
||||||
|
|
||||||
cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
|
if (meta_texture_rectangle_check (paint_tex))
|
||||||
|
priv->mask_texture = meta_texture_rectangle_new (tex_width, tex_height,
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
COGL_PIXEL_FORMAT_A_8,
|
||||||
if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
COGL_PIXEL_FORMAT_A_8,
|
||||||
{
|
stride,
|
||||||
priv->mask_texture
|
mask_data,
|
||||||
= meta_texture_rectangle_new (tex_width, tex_height,
|
NULL /* error */);
|
||||||
0, /* flags */
|
|
||||||
/* data format */
|
|
||||||
COGL_PIXEL_FORMAT_A_8,
|
|
||||||
/* internal GL format */
|
|
||||||
GL_ALPHA,
|
|
||||||
/* internal cogl format */
|
|
||||||
COGL_PIXEL_FORMAT_A_8,
|
|
||||||
/* rowstride */
|
|
||||||
stride,
|
|
||||||
mask_data);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
|
||||||
{
|
{
|
||||||
/* Note: we don't allow slicing for this texture because we
|
/* Note: we don't allow slicing for this texture because we
|
||||||
* need to use it with multi-texturing which doesn't support
|
* need to use it with multi-texturing which doesn't support
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Authored By Neil Roberts <neil@linux.intel.com>
|
* Authored By Neil Roberts <neil@linux.intel.com>
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Intel Corporation
|
* Copyright (C) 2011, 2012 Intel Corporation
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
@ -25,94 +25,77 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||||
|
#define COGL_ENABLE_EXPERIMENTAL_API
|
||||||
|
|
||||||
|
#include <clutter/clutter.h>
|
||||||
#include "meta-texture-rectangle.h"
|
#include "meta-texture-rectangle.h"
|
||||||
|
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
CoglTexture *
|
||||||
|
|
||||||
static void (* pf_glGetIntegerv) (GLenum pname, GLint *params);
|
|
||||||
static void (* pf_glTexImage2D) (GLenum target, GLint level,
|
|
||||||
GLint internalFormat,
|
|
||||||
GLsizei width, GLsizei height,
|
|
||||||
GLint border, GLenum format, GLenum type,
|
|
||||||
const GLvoid *pixels);
|
|
||||||
static void (* pf_glGenTextures) (GLsizei n, GLuint *textures);
|
|
||||||
static void (* pf_glDeleteTextures) (GLsizei n, const GLuint *texture);
|
|
||||||
static void (* pf_glBindTexture) (GLenum target, GLuint texture);
|
|
||||||
|
|
||||||
static void
|
|
||||||
rectangle_texture_destroy_cb (void *user_data)
|
|
||||||
{
|
|
||||||
GLuint tex = GPOINTER_TO_UINT (user_data);
|
|
||||||
|
|
||||||
pf_glDeleteTextures (1, &tex);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
|
||||||
|
|
||||||
CoglHandle
|
|
||||||
meta_texture_rectangle_new (unsigned int width,
|
meta_texture_rectangle_new (unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
CoglTextureFlags flags,
|
|
||||||
CoglPixelFormat format,
|
CoglPixelFormat format,
|
||||||
GLenum internal_gl_format,
|
CoglPixelFormat internal_format,
|
||||||
GLenum internal_format,
|
|
||||||
unsigned int rowstride,
|
unsigned int rowstride,
|
||||||
const guint8 *data)
|
const guint8 *data,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
CoglHandle cogl_tex = COGL_INVALID_HANDLE;
|
ClutterBackend *backend =
|
||||||
|
clutter_get_default_backend ();
|
||||||
|
CoglContext *context =
|
||||||
|
clutter_backend_get_cogl_context (backend);
|
||||||
|
CoglTextureRectangle *tex_rect;
|
||||||
|
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
tex_rect = cogl_texture_rectangle_new_with_size (context,
|
||||||
|
width, height,
|
||||||
|
internal_format,
|
||||||
|
error);
|
||||||
|
if (tex_rect == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
static CoglUserDataKey user_data_key;
|
|
||||||
GLint old_binding;
|
|
||||||
GLuint tex;
|
|
||||||
|
|
||||||
if (pf_glGenTextures == NULL)
|
|
||||||
{
|
|
||||||
pf_glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv");
|
|
||||||
pf_glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D");
|
|
||||||
pf_glGenTextures = (void *) cogl_get_proc_address ("glGenTextures");
|
|
||||||
pf_glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures");
|
|
||||||
pf_glBindTexture = (void *) cogl_get_proc_address ("glBindTexture");
|
|
||||||
}
|
|
||||||
|
|
||||||
pf_glGenTextures (1, &tex);
|
|
||||||
pf_glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
|
|
||||||
pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
|
|
||||||
pf_glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
|
|
||||||
internal_gl_format, width, height,
|
|
||||||
0, internal_gl_format,
|
|
||||||
GL_UNSIGNED_BYTE, NULL);
|
|
||||||
pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, old_binding);
|
|
||||||
|
|
||||||
cogl_tex = cogl_texture_new_from_foreign (tex,
|
|
||||||
GL_TEXTURE_RECTANGLE_ARB,
|
|
||||||
width, height,
|
|
||||||
0, 0, /* no waste */
|
|
||||||
internal_format);
|
|
||||||
|
|
||||||
/* Cogl won't destroy the GL texture when a foreign texture is used
|
|
||||||
so we need to destroy it manually. We can set a destroy
|
|
||||||
notification callback to do this transparently */
|
|
||||||
cogl_object_set_user_data (cogl_tex,
|
|
||||||
&user_data_key,
|
|
||||||
GUINT_TO_POINTER (tex),
|
|
||||||
rectangle_texture_destroy_cb);
|
|
||||||
|
|
||||||
/* Use cogl_texture_set_region instead of uploading the data
|
|
||||||
directly with GL calls so that we can let Cogl deal with setting
|
|
||||||
the pixel store parameters and handling format conversion */
|
|
||||||
if (data)
|
if (data)
|
||||||
cogl_texture_set_region (cogl_tex,
|
cogl_texture_set_region (COGL_TEXTURE (tex_rect),
|
||||||
0, 0, /* src x/y */
|
0, 0, /* src_x/y */
|
||||||
0, 0, /* dst x/y */
|
0, 0, /* dst_x/y */
|
||||||
width, height, /* dst width/height */
|
width, height, /* dst_width/height */
|
||||||
width, height, /* src width/height */
|
width, height, /* width/height */
|
||||||
format,
|
format,
|
||||||
rowstride,
|
rowstride,
|
||||||
data);
|
data);
|
||||||
|
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
return COGL_TEXTURE (tex_rect);
|
||||||
|
}
|
||||||
return cogl_tex;
|
|
||||||
|
static void
|
||||||
|
texture_rectangle_check_cb (CoglTexture *sub_texture,
|
||||||
|
const float *sub_texture_coords,
|
||||||
|
const float *meta_coords,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
gboolean *result = user_data;
|
||||||
|
|
||||||
|
if (cogl_is_texture_rectangle (sub_texture))
|
||||||
|
*result = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determines if the given texture is using a rectangle texture as its
|
||||||
|
* primitive texture type. Eventually this function could be replaced
|
||||||
|
* with cogl_texture_get_type if Cogl makes that public.
|
||||||
|
*
|
||||||
|
* http://git.gnome.org/browse/cogl/commit/?h=8012eee31
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
meta_texture_rectangle_check (CoglTexture *texture)
|
||||||
|
{
|
||||||
|
gboolean result = FALSE;
|
||||||
|
|
||||||
|
cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
|
||||||
|
0.0f, 0.0f, /* tx_1 / ty_1 */
|
||||||
|
1.0f, 1.0f, /* tx_2 / ty_2 */
|
||||||
|
COGL_PIPELINE_WRAP_MODE_REPEAT,
|
||||||
|
COGL_PIPELINE_WRAP_MODE_REPEAT,
|
||||||
|
texture_rectangle_check_cb,
|
||||||
|
&result);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -30,15 +30,17 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
CoglHandle
|
CoglTexture *
|
||||||
meta_texture_rectangle_new (unsigned int width,
|
meta_texture_rectangle_new (unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
CoglTextureFlags flags,
|
|
||||||
CoglPixelFormat format,
|
CoglPixelFormat format,
|
||||||
GLenum internal_gl_format,
|
CoglPixelFormat internal_format,
|
||||||
GLenum internal_format,
|
|
||||||
unsigned int rowstride,
|
unsigned int rowstride,
|
||||||
const guint8 *data);
|
const guint8 *data,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_texture_rectangle_check (CoglTexture *texture);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -98,18 +98,6 @@ meta_texture_tower_free (MetaTextureTower *tower)
|
|||||||
g_slice_free (MetaTextureTower, tower);
|
g_slice_free (MetaTextureTower, tower);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
|
||||||
static gboolean
|
|
||||||
texture_is_rectangle (CoglHandle texture)
|
|
||||||
{
|
|
||||||
GLuint gl_tex;
|
|
||||||
GLenum gl_target;
|
|
||||||
|
|
||||||
cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
|
|
||||||
return gl_target == GL_TEXTURE_RECTANGLE_ARB;
|
|
||||||
}
|
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* meta_texture_tower_set_base_texture:
|
* meta_texture_tower_set_base_texture:
|
||||||
* @tower: a #MetaTextureTower
|
* @tower: a #MetaTextureTower
|
||||||
@ -354,13 +342,11 @@ get_paint_level (int width, int height)
|
|||||||
return (int)(0.5 + lambda);
|
return (int)(0.5 + lambda);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_power_of_two (int x)
|
is_power_of_two (int x)
|
||||||
{
|
{
|
||||||
return (x & (x - 1)) == 0;
|
return (x & (x - 1)) == 0;
|
||||||
}
|
}
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
texture_tower_create_texture (MetaTextureTower *tower,
|
texture_tower_create_texture (MetaTextureTower *tower,
|
||||||
@ -368,25 +354,23 @@ texture_tower_create_texture (MetaTextureTower *tower,
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
|
||||||
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
|
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
|
||||||
texture_is_rectangle (tower->textures[level - 1]))
|
meta_texture_rectangle_check (tower->textures[level - 1]))
|
||||||
{
|
{
|
||||||
tower->textures[level] =
|
tower->textures[level] =
|
||||||
meta_texture_rectangle_new (width, height,
|
meta_texture_rectangle_new (width, height,
|
||||||
0, /* flags */
|
|
||||||
/* data format */
|
/* data format */
|
||||||
TEXTURE_FORMAT,
|
TEXTURE_FORMAT,
|
||||||
/* internal GL format */
|
|
||||||
GL_RGBA,
|
|
||||||
/* internal cogl format */
|
/* internal cogl format */
|
||||||
TEXTURE_FORMAT,
|
TEXTURE_FORMAT,
|
||||||
/* rowstride */
|
/* rowstride */
|
||||||
width * 4,
|
width * 4,
|
||||||
|
/* data */
|
||||||
|
NULL,
|
||||||
|
/* error */
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
|
|
||||||
{
|
{
|
||||||
tower->textures[level] = cogl_texture_new_with_size (width, height,
|
tower->textures[level] = cogl_texture_new_with_size (width, height,
|
||||||
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
||||||
|
Loading…
Reference in New Issue
Block a user