[mutter] Use a utility function to create GL_ARB_texture_rectangles



commit fccd6266048520ce3a5917c687c876a4ec645d6e
Author: Neil Roberts <neil linux intel com>
Date:   Wed Jul 13 15:47:10 2011 +0100

    Use a utility function to create GL_ARB_texture_rectangles
    
    meta-texture-rectangle and meta-shaped-texture both create textures
    with GL_TEXTURE_RECTANGLE_ARB as the target using direct GL
    calls. This patch moves that code into a shared utility function in a
    separate file instead. The function resolves the required GL symbols
    dynamically instead of linking to them directly so that if Clutter
    eventually stops linking to -lGL mutter will continue to build. The
    function also splits the texture creation into a separate texture
    creation and data upload stage so that it can use
    cogl_texture_set_region to upload the data. That way it can avoid
    clobbering the glPixelStore state and it can let Cogl do any necessary
    format conversion. The code preserves the old value of the rectangle
    texture binding instead of clobbering it because Cogl expects to be
    able to cache this value to avoid redundant glBindTexture
    calls. Finally, the function uses cogl_object_set_data to
    automatically destroy the GL texture when the Cogl texture is
    destroyed. This avoids having to have special code to destroy the cogl
    texture.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=654569

 src/Makefile.am                         |    2 +
 src/compositor/meta-shaped-texture.c    |   40 +++-------
 src/compositor/meta-texture-rectangle.c |  118 +++++++++++++++++++++++++++++++
 src/compositor/meta-texture-rectangle.h |   45 ++++++++++++
 src/compositor/meta-texture-tower.c     |   48 ++++---------
 5 files changed, 191 insertions(+), 62 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index c313e81..c6e2077 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -55,6 +55,8 @@ libmutter_la_SOURCES =				\
 	compositor/meta-shadow-factory-private.h	\
 	compositor/meta-shaped-texture.c	\
 	compositor/meta-shaped-texture.h	\
+	compositor/meta-texture-rectangle.c	\
+	compositor/meta-texture-rectangle.h	\
 	compositor/meta-texture-tower.c		\
 	compositor/meta-texture-tower.h		\
 	compositor/meta-window-actor.c		\
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 273dfd3..feeedda 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -27,6 +27,7 @@
 
 #include "meta-shaped-texture.h"
 #include "meta-texture-tower.h"
+#include "meta-texture-rectangle.h"
 
 #include <clutter/clutter.h>
 #include <cogl/cogl.h>
@@ -181,17 +182,6 @@ meta_shaped_texture_dirty_mask (MetaShapedTexture *stex)
 
   if (priv->mask_texture != COGL_INVALID_HANDLE)
     {
-      GLuint mask_gl_tex;
-      GLenum mask_gl_target;
-
-      cogl_texture_get_gl_texture (priv->mask_texture,
-                                   &mask_gl_tex, &mask_gl_target);
-
-#ifdef GL_TEXTURE_RECTANGLE_ARB
-      if (mask_gl_target == GL_TEXTURE_RECTANGLE_ARB)
-        glDeleteTextures (1, &mask_gl_tex);
-#endif
-
       cogl_handle_unref (priv->mask_texture);
       priv->mask_texture = COGL_INVALID_HANDLE;
 
@@ -258,24 +248,18 @@ meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
 #ifdef GL_TEXTURE_RECTANGLE_ARB
       if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
         {
-          GLuint tex;
-
-          glGenTextures (1, &tex);
-          glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
-          glPixelStorei (GL_UNPACK_ROW_LENGTH, tex_width);
-          glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
-          glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
-          glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
-          glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
-                        GL_ALPHA, tex_width, tex_height,
-                        0, GL_ALPHA, GL_UNSIGNED_BYTE, mask_data);
-
           priv->mask_texture
-            = cogl_texture_new_from_foreign (tex,
-                                             GL_TEXTURE_RECTANGLE_ARB,
-                                             tex_width, tex_height,
-                                             0, 0,
-                                             COGL_PIXEL_FORMAT_A_8);
+            = meta_texture_rectangle_new (tex_width, tex_height,
+                                          0, /* flags */
+                                          /* data format */
+                                          COGL_PIXEL_FORMAT_A_8,
+                                          /* internal GL format */
+                                          GL_ALPHA,
+                                          /* internal cogl format */
+                                          COGL_PIXEL_FORMAT_A_8,
+                                          /* rowstride */
+                                          tex_width,
+                                          mask_data);
         }
       else
 #endif /* GL_TEXTURE_RECTANGLE_ARB */
diff --git a/src/compositor/meta-texture-rectangle.c b/src/compositor/meta-texture-rectangle.c
new file mode 100644
index 0000000..d699729
--- /dev/null
+++ b/src/compositor/meta-texture-rectangle.c
@@ -0,0 +1,118 @@
+/*
+ * texture rectangle
+ *
+ * A small utility function to help create a rectangle texture
+ *
+ * Authored By Neil Roberts  <neil linux intel com>
+ *
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include "meta-texture-rectangle.h"
+
+#ifdef GL_TEXTURE_RECTANGLE_ARB
+
+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,
+                            unsigned int height,
+                            CoglTextureFlags flags,
+                            CoglPixelFormat format,
+                            GLenum internal_gl_format,
+                            GLenum internal_format,
+                            unsigned int rowstride,
+                            const guint8 *data)
+{
+  CoglHandle cogl_tex = COGL_INVALID_HANDLE;
+
+#ifdef GL_TEXTURE_RECTANGLE_ARB
+
+  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)
+    cogl_texture_set_region (cogl_tex,
+                             0, 0, /* src x/y */
+                             0, 0, /* dst x/y */
+                             width, height, /* dst width/height */
+                             width, height, /* src width/height */
+                             format,
+                             rowstride,
+                             data);
+
+#endif /* GL_TEXTURE_RECTANGLE_ARB */
+
+  return cogl_tex;
+}
diff --git a/src/compositor/meta-texture-rectangle.h b/src/compositor/meta-texture-rectangle.h
new file mode 100644
index 0000000..b777316
--- /dev/null
+++ b/src/compositor/meta-texture-rectangle.h
@@ -0,0 +1,45 @@
+/*
+ * texture rectangle
+ *
+ * A small utility function to help create a rectangle texture
+ *
+ * Authored By Neil Roberts  <neil linux intel com>
+ *
+ * Copyright (C) 2011 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __META_TEXTURE_RECTANGLE_H__
+#define __META_TEXTURE_RECTANGLE_H__
+
+#include <cogl/cogl.h>
+
+G_BEGIN_DECLS
+
+CoglHandle
+meta_texture_rectangle_new (unsigned int width,
+                            unsigned int height,
+                            CoglTextureFlags flags,
+                            CoglPixelFormat format,
+                            GLenum internal_gl_format,
+                            GLenum internal_format,
+                            unsigned int rowstride,
+                            const guint8 *data);
+
+G_END_DECLS
+
+#endif /* __META_TEXTURE_RECTANGLE_H__ */
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
index 73e1227..551450c 100644
--- a/src/compositor/meta-texture-tower.c
+++ b/src/compositor/meta-texture-tower.c
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "meta-texture-tower.h"
+#include "meta-texture-rectangle.h"
 
 #ifndef M_LOG2E
 #define M_LOG2E 1.4426950408889634074
@@ -109,22 +110,6 @@ texture_is_rectangle (CoglHandle texture)
 }
 #endif /* GL_TEXTURE_RECTANGLE_ARB */
 
-static void
-free_texture (CoglHandle texture)
-{
-#ifdef GL_TEXTURE_RECTANGLE_ARB
-  GLuint gl_tex;
-  GLenum gl_target;
-
-  cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
-
-  if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
-    glDeleteTextures (1, &gl_tex);
-#endif /* GL_TEXTURE_RECTANGLE_ARB */
-
-  cogl_handle_unref (texture);
-}
-
 /**
  * meta_texture_tower_update_area:
  * @tower: a MetaTextureTower
@@ -152,7 +137,7 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
         {
           if (tower->textures[i] != COGL_INVALID_HANDLE)
             {
-              free_texture (tower->textures[i]);
+              cogl_handle_unref (tower->textures[i]);
               tower->textures[i] = COGL_INVALID_HANDLE;
             }
 
@@ -384,23 +369,18 @@ texture_tower_create_texture (MetaTextureTower *tower,
   if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
       texture_is_rectangle (tower->textures[level - 1]))
     {
-      GLuint tex = 0;
-
-      glGenTextures (1, &tex);
-      glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
-      glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
-                    GL_RGBA, width,height,
-#if TEXTURE_FORMAT == COGL_PIXEL_FORMAT_BGRA_8888_PRE
-                    0, GL_BGRA, GL_UNSIGNED_BYTE,
-#else /* assume big endian */
-                    0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
-#endif
-                    NULL);
-
-      tower->textures[level] = cogl_texture_new_from_foreign (tex, GL_TEXTURE_RECTANGLE_ARB,
-                                                              width, height,
-                                                              0, 0,
-                                                              TEXTURE_FORMAT);
+      tower->textures[level] =
+        meta_texture_rectangle_new (width, height,
+                                    0, /* flags */
+                                    /* data format */
+                                    TEXTURE_FORMAT,
+                                    /* internal GL format */
+                                    GL_RGBA,
+                                    /* internal cogl format */
+                                    TEXTURE_FORMAT,
+                                    /* rowstride */
+                                    width * 4,
+                                    NULL);
     }
   else
 #endif /* GL_TEXTURE_RECTANGLE_ARB */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]