[cairo-commit] glitz/src Makefile.am, 1.8, 1.9 glitz.c, 1.30, 1.31 glitz.h, 1.25, 1.26 glitz_buffer.c, 1.6, 1.7 glitz_compose.c, 1.11, 1.12 glitz_drawable.c, 1.1, 1.2 glitz_filter.c, 1.7, 1.8 glitz_format.c, 1.9, 1.10 glitz_geometry.c, 1.4, 1.5 glitz_gl.h, 1.13, 1.14 glitz_operator.c, 1.6, 1.7 glitz_pixel.c, 1.14, 1.15 glitz_program.c, 1.16, 1.17 glitz_rect.c, 1.15, 1.16 glitz_region.c, 1.1, 1.2 glitz_status.c, 1.3, 1.4 glitz_surface.c, 1.24, 1.25 glitz_texture.c, 1.16, 1.17 glitz_trap.c, 1.9, 1.10 glitz_trapimp.h, NONE, 1.1 glitz_util.c, 1.11, 1.12 glitzint.h, 1.30, 1.31

David Reveman commit at pdx.freedesktop.org
Tue Jan 25 11:50:28 PST 2005


Committed by: davidr

Update of /cvs/cairo/glitz/src
In directory gabe:/tmp/cvs-serv2384/src

Modified Files:
	Makefile.am glitz.c glitz.h glitz_buffer.c glitz_compose.c 
	glitz_drawable.c glitz_filter.c glitz_format.c 
	glitz_geometry.c glitz_gl.h glitz_operator.c glitz_pixel.c 
	glitz_program.c glitz_rect.c glitz_region.c glitz_status.c 
	glitz_surface.c glitz_texture.c glitz_util.c glitzint.h 
Added Files:
	glitz_trap.c glitz_trapimp.h 
Log Message:
Add anti-aliased trapezoids, rectangular clipping, multiple geometry arrays, bitmap geometry, mask surface convolution filtering

Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/glitz/src/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Makefile.am	3 Nov 2004 22:50:58 -0000	1.8
+++ Makefile.am	25 Jan 2005 19:50:26 -0000	1.9
@@ -21,6 +21,8 @@
 	glitz_buffer.c	 \
 	glitz_geometry.c \
 	glitz_pixel.c	 \
+	glitz_trap.c	 \
+	glitz_trapimp.h	 \
 	glitz_gl.h	 \
 	glitzint.h
 
@@ -32,4 +34,4 @@
 
 EXTRA_DIST =	     \
 	glitz.pc.in  \
-	glitz.man
\ No newline at end of file
+	glitz.man

Index: glitz.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- glitz.c	3 Nov 2004 22:50:58 -0000	1.30
+++ glitz.c	25 Jan 2005 19:50:26 -0000	1.31
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
[...1001 lines suppressed...]
+                
+                glitz_texture_unbind (gl, texture);
+                
+                gl->enable (GLITZ_GL_SCISSOR_TEST);
         
-        status = GLITZ_STATUS_SUCCESS;
-      }
+                status = GLITZ_STATUS_SUCCESS;
+            }
+        }
+        glitz_surface_pop_current (src);
     }
-    glitz_surface_pop_current (src);
-  }
 
-  if (status)
-    glitz_surface_status_add (dst, glitz_status_to_status_mask (status));
+    if (status)
+        glitz_surface_status_add (dst, glitz_status_to_status_mask (status));
 }

Index: glitz.h
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- glitz.h	3 Nov 2004 22:50:58 -0000	1.25
+++ glitz.h	25 Jan 2005 19:50:26 -0000	1.26
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifndef GLITZ_H_INCLUDED
@@ -37,7 +37,7 @@
 #endif
 
 #define GLITZ_MAJOR    0
-#define GLITZ_MINOR    3
+#define GLITZ_MINOR    4
 #define GLITZ_REVISION 0
 
 #if defined(__cplusplus) || defined(c_plusplus)
@@ -56,6 +56,33 @@
   unsigned short width, height;
 } glitz_rectangle_t;
 
+typedef struct _glitz_box_t {
+  short x1, y1, x2, y2;
+} glitz_box_t;
+
+typedef struct _glitz_point_fixed_t {
+  glitz_fixed16_16_t x;
+  glitz_fixed16_16_t y;
+} glitz_point_fixed_t;
+
+typedef struct _glitz_line_fixed_t {
+  glitz_point_fixed_t p1;
+  glitz_point_fixed_t p2;
+} glitz_line_fixed_t;
+
+typedef struct _glitz_trapezoid_t {
+  glitz_fixed16_16_t top, bottom;
+  glitz_line_fixed_t left, right;
+} glitz_trapezoid_t;
+
+typedef struct _glitz_span_fixed_t {
+  glitz_fixed16_16_t left, right, y;
+} glitz_span_fixed_t;
+  
+typedef struct _glitz_trap_t {
+  glitz_span_fixed_t top, bottom;
+} glitz_trap_t;
+
 typedef struct _glitz_transform_t {
   glitz_fixed16_16_t matrix[3][3];
 } glitz_transform_t;
@@ -107,6 +134,7 @@
 #define GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK  (1L << 12)
 #define GLITZ_FEATURE_BLEND_COLOR_MASK              (1L << 13)
 #define GLITZ_FEATURE_PACKED_PIXELS_MASK            (1L << 14)
+#define GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK        (1L << 15)
 
 typedef enum {
   GLITZ_STANDARD_ARGB32,
@@ -176,14 +204,6 @@
   glitz_drawable_types_t types;
 } glitz_drawable_format_t;
 
-#define GLITZ_PBUFFER_WIDTH_MASK  (1L << 0)
-#define GLITZ_PBUFFER_HEIGHT_MASK (1L << 1)
-
-typedef struct _glitz_pbuffer_attributes_t {
-  unsigned int width;
-  unsigned int height;
-} glitz_pbuffer_attributes_t;
-    
 glitz_drawable_format_t *
 glitz_find_similar_drawable_format (glitz_drawable_t              *other,
                                     unsigned long                 mask,
@@ -191,10 +211,10 @@
                                     int                           count);
     
 glitz_drawable_t *
-glitz_create_pbuffer_drawable (glitz_drawable_t           *other,
-                               glitz_drawable_format_t    *format,
-                               glitz_pbuffer_attributes_t *attributes,
-                               unsigned long              mask);
+glitz_create_pbuffer_drawable (glitz_drawable_t        *other,
+                               glitz_drawable_format_t *format,
+                               unsigned int            width,
+                               unsigned int            height);
 
 void
 glitz_drawable_destroy (glitz_drawable_t *drawable);
@@ -257,12 +277,20 @@
 /* glitz_surface.c */
 
 typedef struct _glitz_surface glitz_surface_t;
+
+#define GLITZ_SURFACE_UNNORMALIZED_MASK (1L << 0)
+
+typedef struct _glitz_surface_attributes_t {
+  glitz_bool_t unnormalized;
+} glitz_surface_attributes_t;
   
 glitz_surface_t *
-glitz_surface_create (glitz_drawable_t *drawable,
-                      glitz_format_t   *format,
-                      unsigned int     width,
-                      unsigned int     height);
+glitz_surface_create (glitz_drawable_t           *drawable,
+                      glitz_format_t             *format,
+                      unsigned int               width,
+                      unsigned int               height,
+                      unsigned long              mask,
+                      glitz_surface_attributes_t *attributes);
 
 void
 glitz_surface_destroy (glitz_surface_t *surface);
@@ -330,6 +358,18 @@
 glitz_format_t *
 glitz_surface_get_format (glitz_surface_t *surface);
 
+void
+glitz_surface_translate_point (glitz_surface_t     *surface,
+                               glitz_point_fixed_t *src,
+                               glitz_point_fixed_t *dst);
+
+void
+glitz_surface_set_clip_region (glitz_surface_t *surface,
+                               int             x_origin,
+                               int             y_origin,
+                               glitz_box_t     *box,
+                               int             n_box);
+
   
 /* glitz_rect.c */
 
@@ -371,10 +411,10 @@
 } glitz_buffer_access_t;
 
 glitz_buffer_t *
-glitz_geometry_buffer_create (glitz_drawable_t    *drawable,
-                              void                *data,
-                              unsigned int        size,
-                              glitz_buffer_hint_t hint);
+glitz_vertex_buffer_create (glitz_drawable_t    *drawable,
+                            void                *data,
+                            unsigned int        size,
+                            glitz_buffer_hint_t hint);
 
 glitz_buffer_t *
 glitz_pixel_buffer_create (glitz_drawable_t    *drawable,
@@ -456,53 +496,130 @@
 /* glitz_geometry.c */
 
 typedef enum {
-  GLITZ_GEOMETRY_MODE_DIRECT,
-  GLITZ_GEOMETRY_MODE_INDIRECT
-} glitz_geometry_mode_t;
-
-typedef enum {
-  GLITZ_GEOMETRY_EDGE_HINT_SHARP,
-  GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH,
-  GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH,
-  GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH
-} glitz_geometry_edge_hint_t;
+  GLITZ_PRIMITIVE_POINTS,
+  GLITZ_PRIMITIVE_LINES,
+  GLITZ_PRIMITIVE_LINE_STRIP,
+  GLITZ_PRIMITIVE_LINE_LOOP,
+  GLITZ_PRIMITIVE_TRIANGLES,
+  GLITZ_PRIMITIVE_TRIANGLE_STRIP,
+  GLITZ_PRIMITIVE_TRIANGLE_FAN,
+  GLITZ_PRIMITIVE_QUADS,
+  GLITZ_PRIMITIVE_QUAD_STRIP,
+  GLITZ_PRIMITIVE_POLYGON
+} glitz_primitive_t;
 
 typedef enum {
-  GLITZ_GEOMETRY_PRIMITIVE_POINTS,
-  GLITZ_GEOMETRY_PRIMITIVE_LINES,
-  GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP,
-  GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP,
-  GLITZ_GEOMETRY_PRIMITIVE_TRIANGLES,
-  GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_STRIP,
-  GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_FAN,
-  GLITZ_GEOMETRY_PRIMITIVE_QUADS,
-  GLITZ_GEOMETRY_PRIMITIVE_QUAD_STRIP,
-  GLITZ_GEOMETRY_PRIMITIVE_POLYGON
-} glitz_geometry_primitive_t;
-  
-typedef enum {
   GLITZ_DATA_TYPE_SHORT,
   GLITZ_DATA_TYPE_INT,
   GLITZ_DATA_TYPE_FLOAT,
   GLITZ_DATA_TYPE_DOUBLE
 } glitz_data_type_t;
 
-typedef struct _glitz_geometry_format {
-  glitz_geometry_mode_t      mode;
-  glitz_geometry_edge_hint_t edge_hint;
-  glitz_geometry_primitive_t primitive;
-  glitz_data_type_t          type;
-  int                        first;
-  unsigned int               count;
+typedef enum {
+  GLITZ_COORDINATE_SIZE_X,
+  GLITZ_COORDINATE_SIZE_XY
+} glitz_coordinate_size_t;
+    
+typedef struct _glitz_coordinate_attribute {
+    glitz_data_type_t       type;
+    glitz_coordinate_size_t size;
+    int                     offset;
+} glitz_coordinate_attribute_t;
+
+#define GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK  (1L << 0)
+#define GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK (1L << 1)
+
+typedef struct _glitz_vertex_format {
+  glitz_primitive_t            primitive;
+  glitz_data_type_t            type;
+  unsigned int                 bytes_per_vertex;
+  unsigned long                attributes;
+  glitz_coordinate_attribute_t src;
+  glitz_coordinate_attribute_t mask;
+} glitz_vertex_format_t;
+
+typedef struct _glitz_bitmap_format {
+  glitz_pixel_scanline_order_t scanline_order;
+  unsigned int                 bytes_per_line;
+  int                          pad;
+} glitz_bitmap_format_t;
+
+typedef enum {
+  GLITZ_GEOMETRY_TYPE_NONE,
+  GLITZ_GEOMETRY_TYPE_VERTEX,
+  GLITZ_GEOMETRY_TYPE_BITMAP
+} glitz_geometry_type_t;
+
+typedef union _glitz_geometry_format {
+  glitz_vertex_format_t vertex;
+  glitz_bitmap_format_t bitmap;
 } glitz_geometry_format_t;
 
 void
 glitz_set_geometry (glitz_surface_t         *dst,
-                    glitz_fixed16_16_t      x_dst,
-                    glitz_fixed16_16_t      y_dst,
+                    glitz_geometry_type_t   type,
                     glitz_geometry_format_t *format,
                     glitz_buffer_t          *buffer);
-  
+
+void
+glitz_set_array (glitz_surface_t    *dst,
+                 int                first,
+                 int                size,
+                 unsigned int       count,
+                 glitz_fixed16_16_t x_off,
+                 glitz_fixed16_16_t y_off);
+
+typedef struct _glitz_multi_array glitz_multi_array_t;
+
+glitz_multi_array_t *
+glitz_multi_array_create (unsigned int size);
+
+void
+glitz_multi_array_destroy (glitz_multi_array_t *array);
+
+void
+glitz_multi_array_reference (glitz_multi_array_t *array);
+
+void
+glitz_multi_array_add (glitz_multi_array_t *array,
+                       int                 first,
+                       int                 size,
+                       unsigned int        count,
+                       glitz_fixed16_16_t  x_off,
+                       glitz_fixed16_16_t  y_off);
+
+void
+glitz_multi_array_reset (glitz_multi_array_t *array);
+
+void
+glitz_set_multi_array (glitz_surface_t     *dst,
+                       glitz_multi_array_t *array,
+                       glitz_fixed16_16_t  x_off,
+                       glitz_fixed16_16_t  y_off);
+
+
+/* glitz_trap.c */
+
+int
+glitz_add_trapezoids (glitz_buffer_t    *buffer,
+                      int               offset,
+                      unsigned int      size,
+                      glitz_data_type_t type,
+                      glitz_surface_t   *mask,
+                      glitz_trapezoid_t *traps,
+                      int               n_traps,
+                      int               *n_added);
+
+int
+glitz_add_traps (glitz_buffer_t    *buffer,
+                 int               offset,
+                 unsigned int      size,
+                 glitz_data_type_t type,
+                 glitz_surface_t   *mask,
+                 glitz_trap_t      *traps,
+                 int               n_traps,
+                 int               *n_added);
+
 
 /* glitz.c */
 

Index: glitz_buffer.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_buffer.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- glitz_buffer.c	8 Nov 2004 15:11:43 -0000	1.6
+++ glitz_buffer.c	25 Jan 2005 19:50:26 -0000	1.7
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -36,84 +36,92 @@
                     unsigned int        size,
                     glitz_buffer_hint_t hint)
 {
-  glitz_gl_enum_t usage;
-
-  buffer->ref_count = 1;
-  buffer->name = 0;
-
-  switch (hint) {
-  case GLITZ_BUFFER_HINT_STREAM_DRAW:
-    usage = GLITZ_GL_STREAM_DRAW;
-    break;
-  case GLITZ_BUFFER_HINT_STREAM_READ:
-    usage = GLITZ_GL_STREAM_READ;
-    break;
-  case GLITZ_BUFFER_HINT_STREAM_COPY:
-    usage = GLITZ_GL_STREAM_COPY;
-    break;
-  case GLITZ_BUFFER_HINT_STATIC_DRAW:
-    usage = GLITZ_GL_STATIC_DRAW;
-    break;
-  case GLITZ_BUFFER_HINT_STATIC_READ:
-    usage = GLITZ_GL_STATIC_READ;
-    break;
-  case GLITZ_BUFFER_HINT_STATIC_COPY:
-    usage = GLITZ_GL_STATIC_COPY;
-    break;
-  case GLITZ_BUFFER_HINT_DYNAMIC_DRAW:
-    usage = GLITZ_GL_DYNAMIC_DRAW;
-    break;
-  case GLITZ_BUFFER_HINT_DYNAMIC_READ:
-    usage = GLITZ_GL_DYNAMIC_READ;
-    break;
-  default:
-    usage = GLITZ_GL_DYNAMIC_COPY;
-    break;
-  }
-  
-  if (drawable) {
-
-    GLITZ_GL_DRAWABLE (drawable);
+    glitz_gl_enum_t usage;
     
-    buffer->drawable = drawable;
-    glitz_drawable_reference (drawable);
+    buffer->ref_count = 1;
+    buffer->name = 0;
 
-    drawable->backend->push_current (drawable, NULL,
-                                     GLITZ_ANY_CONTEXT_CURRENT);
+    if (drawable)
+    {
+        GLITZ_GL_DRAWABLE (drawable);
+      
+        switch (hint) {
+        case GLITZ_BUFFER_HINT_STREAM_DRAW:
+            usage = GLITZ_GL_STREAM_DRAW;
+            break;
+        case GLITZ_BUFFER_HINT_STREAM_READ:
+            usage = GLITZ_GL_STREAM_READ;
+            break;
+        case GLITZ_BUFFER_HINT_STREAM_COPY:
+            usage = GLITZ_GL_STREAM_COPY;
+            break;
+        case GLITZ_BUFFER_HINT_STATIC_DRAW:
+            usage = GLITZ_GL_STATIC_DRAW;
+            break;
+        case GLITZ_BUFFER_HINT_STATIC_READ:
+            usage = GLITZ_GL_STATIC_READ;
+            break;
+        case GLITZ_BUFFER_HINT_STATIC_COPY:
+            usage = GLITZ_GL_STATIC_COPY;
+            break;
+        case GLITZ_BUFFER_HINT_DYNAMIC_DRAW:
+            usage = GLITZ_GL_DYNAMIC_DRAW;
+            break;
+        case GLITZ_BUFFER_HINT_DYNAMIC_READ:
+            usage = GLITZ_GL_DYNAMIC_READ;
+            break;
+        default:
+            usage = GLITZ_GL_DYNAMIC_COPY;
+            break;
+        }
 
-    gl->gen_buffers (1, &buffer->name);
-    if (buffer->name) {
-      gl->bind_buffer (buffer->target, buffer->name);
-      gl->buffer_data (buffer->target, size, data, usage);
-      gl->bind_buffer (buffer->target, 0);
+        buffer->owns_data = 1;
+        buffer->drawable = drawable;
+        glitz_drawable_reference (drawable);
+        
+        drawable->backend->push_current (drawable, NULL,
+                                         GLITZ_ANY_CONTEXT_CURRENT);
+        
+        gl->gen_buffers (1, &buffer->name);
+        if (buffer->name) {
+            gl->bind_buffer (buffer->target, buffer->name);
+            gl->buffer_data (buffer->target, size, data, usage);
+            gl->bind_buffer (buffer->target, 0);
+        }
+        
+        drawable->backend->pop_current (drawable);
+    }
+    else
+    {
+        buffer->drawable = NULL;
+        usage = GLITZ_GL_DYNAMIC_COPY;
     }
     
-    drawable->backend->pop_current (drawable);
-  } else
-    buffer->drawable = NULL;
-  
-  if (size > 0 && buffer->name == 0) {
-    buffer->data = malloc (size);
-    if (buffer->data == NULL)
-      return GLITZ_STATUS_NO_MEMORY;
-    
-    if (data)
-      memcpy (buffer->data, data, size);
-    
-    buffer->owns_data = 1;
-  } else {
-    buffer->owns_data = 0;
-    buffer->data = data;
-  }
+    if (size > 0 && buffer->name == 0)
+    {
+        buffer->data = malloc (size);
+        if (buffer->data == NULL)
+            return GLITZ_STATUS_NO_MEMORY;
+        
+        if (data)
+            memcpy (buffer->data, data, size);
+        
+        buffer->owns_data = 1;
+    }
+    else
+    {
+        buffer->owns_data = 0;
+        buffer->data = data;
+    }
   
-  return GLITZ_STATUS_SUCCESS;
+    return GLITZ_STATUS_SUCCESS;
 }
 
 glitz_buffer_t *
-glitz_geometry_buffer_create (glitz_drawable_t    *drawable,
-                              void                *data,
-                              unsigned int        size,
-                              glitz_buffer_hint_t hint)
+glitz_vertex_buffer_create (glitz_drawable_t    *drawable,
+                            void                *data,
+                            unsigned int        size,
+                            glitz_buffer_hint_t hint)
 {
   glitz_buffer_t *buffer;
   glitz_status_t status;
@@ -186,9 +194,6 @@
 {
   glitz_buffer_t *buffer;
   
-  if (data == NULL)
-    return NULL;
-  
   buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
   if (buffer == NULL)
     return NULL;
@@ -226,7 +231,7 @@
 void
 glitz_buffer_reference (glitz_buffer_t *buffer)
 {
-  if (buffer == NULL)
+  if (!buffer)
     return;
 
   buffer->ref_count++;

Index: glitz_compose.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_compose.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- glitz_compose.c	3 Dec 2004 02:19:51 -0000	1.11
+++ glitz_compose.c	25 Jan 2005 19:50:26 -0000	1.12
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -53,7 +53,7 @@
                      GLITZ_GL_SRC_COLOR);
   op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_OPERAND1_RGB,
                      GLITZ_GL_SRC_ALPHA);
-  
+
   op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_COMBINE_ALPHA,
                      GLITZ_GL_MODULATE);
   op->gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_SOURCE0_ALPHA,
@@ -144,6 +144,18 @@
 }
 
 static void
+_glitz_combine_argb_argbf (glitz_composite_op_t *op)
+{
+  glitz_set_operator (op->gl, op->render_op);
+  glitz_filter_enable (op->mask, op);
+  
+  op->gl->color_4us (op->alpha_mask.red,
+                     op->alpha_mask.green,
+                     op->alpha_mask.blue,
+                     op->alpha_mask.alpha);
+}
+
+static void
 _glitz_combine_argb_solid (glitz_composite_op_t *op)
 {
   glitz_set_operator (op->gl, op->render_op);
@@ -314,6 +326,18 @@
                      solid.alpha);
 }
 
+static void
+_glitz_combine_solid_argbf (glitz_composite_op_t *op)
+{
+  glitz_set_operator (op->gl, op->render_op);
+  glitz_filter_enable (op->mask, op);
+
+  op->gl->color_4us (SHORT_MULT (op->solid->red, op->alpha_mask.alpha),
+                     SHORT_MULT (op->solid->green, op->alpha_mask.alpha),
+                     SHORT_MULT (op->solid->blue, op->alpha_mask.alpha),
+                     SHORT_MULT (op->solid->alpha, op->alpha_mask.alpha));
+}
+
 /* This only works with the OVER operator. */
 static void
 _glitz_combine_solid_solidc (glitz_composite_op_t *op)
@@ -350,14 +374,14 @@
     { GLITZ_COMBINE_TYPE_ARGB,        _glitz_combine_argb_solid,  1, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_ARGB,   _glitz_combine_argb_argb,   2, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_ARGBC,  _glitz_combine_argb_argbc,  3, 0 },
-    { GLITZ_COMBINE_TYPE_NA,          NULL,                       0, 0 },
+    { GLITZ_COMBINE_TYPE_ARGB_ARGBF,  _glitz_combine_argb_argbf,  2, 2 },
     { GLITZ_COMBINE_TYPE_ARGB_SOLID,  _glitz_combine_argb_solid,  1, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 }
   }, {
     { GLITZ_COMBINE_TYPE_ARGB,        _glitz_combine_argb_solid,  1, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_ARGB,   _glitz_combine_argb_argb,   2, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_ARGBC,  _glitz_combine_argb_argbc,  3, 0 },
-    { GLITZ_COMBINE_TYPE_NA,          NULL,                       0, 0 },
+    { GLITZ_COMBINE_TYPE_ARGB_ARGBF,  _glitz_combine_argb_argbf,  2, 2 },
     { GLITZ_COMBINE_TYPE_ARGB_SOLID,  _glitz_combine_argb_solid,  1, 0 },
     { GLITZ_COMBINE_TYPE_ARGB_SOLIDC, _glitz_combine_argb_solidc, 1, 0 }
   }, {
@@ -371,14 +395,14 @@
     { GLITZ_COMBINE_TYPE_SOLID,        _glitz_combine_solid_solid,  0, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_ARGB,   _glitz_combine_solid_argb,   1, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_ARGBC,  _glitz_combine_solid_argbc,  1, 0 },
-    { GLITZ_COMBINE_TYPE_NA,           NULL,                        0, 0 },
+    { GLITZ_COMBINE_TYPE_SOLID_ARGBF,  _glitz_combine_solid_argbf,  1, 2 },
     { GLITZ_COMBINE_TYPE_SOLID_SOLID,  _glitz_combine_solid_solid,  0, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 }
   }, {
     { GLITZ_COMBINE_TYPE_SOLID,        _glitz_combine_solid_solid,  0, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_ARGB,   _glitz_combine_solid_argb,   1, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_ARGBC,  _glitz_combine_solid_argbc,  1, 0 },
-    { GLITZ_COMBINE_TYPE_NA,           NULL,                        0, 0 },
+    { GLITZ_COMBINE_TYPE_SOLID_ARGBF,  _glitz_combine_solid_argbf,  1, 2 },
     { GLITZ_COMBINE_TYPE_SOLID_SOLID,  _glitz_combine_solid_solid,  0, 0 },
     { GLITZ_COMBINE_TYPE_SOLID_SOLIDC, _glitz_combine_solid_solidc, 1, 0 }
   }
@@ -466,9 +490,6 @@
 
   feature_mask = dst->attached->backend->feature_mask;
 
-  if (dst->indirect && (dst->attached->format->stencil_size < 1))
-    return;
-  
   src_type = _glitz_get_surface_type (src, feature_mask);
   if (src_type < 1)
     return;
@@ -494,6 +515,15 @@
   if (!combine->type)
     return;
   
+  if (dst->geometry.type == GLITZ_GEOMETRY_TYPE_BITMAP)
+  {
+      /* We can't do anything but solid colors with bitmaps yet. */
+      if (src_type != GLITZ_SURFACE_TYPE_SOLID ||
+          (mask_type != GLITZ_SURFACE_TYPE_NULL &&
+           mask_type != GLITZ_SURFACE_TYPE_SOLID))
+          return;
+  }
+  
   if (src_type == GLITZ_SURFACE_TYPE_SOLID) {
     if (SURFACE_SOLID_DAMAGE (src)) {
       glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
@@ -523,17 +553,20 @@
     op->mask = NULL;
     
     if (op->src) {
-      op->per_component = 4;
-      op->combine = combine;
+        op->per_component = 4;
+        op->combine = combine;
     } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
       op->combine = combine;
     
   } else if (mask_type != GLITZ_SURFACE_TYPE_NULL) {
     if (mask_type == GLITZ_SURFACE_TYPE_ARGBC) {
       if (op->src) {
-        op->per_component = 4;
-        if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
-          op->combine = combine;
+          /* we can't do component alpha with alpha only surfaces */
+        if (op->src->format->color.red_size) {
+          op->per_component = 4;
+          if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
+            op->combine = combine;
+        }
       } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
         op->combine = combine;
     } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
@@ -552,8 +585,11 @@
   
   if (op->combine == combine) {
     op->type = combine->type;
-    if (combine->fragment_processing) {
-      op->fp = glitz_filter_get_fragment_program (src, op);
+    if (combine->source_shader) {
+      if (combine->source_shader == 1)
+        op->fp = glitz_filter_get_fragment_program (src, op);
+      else
+        op->fp = glitz_filter_get_fragment_program (mask, op);
       if (op->fp == 0)
         op->type = GLITZ_COMBINE_TYPE_NA;
     }

Index: glitz_drawable.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_drawable.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- glitz_drawable.c	3 Nov 2004 22:50:58 -0000	1.1
+++ glitz_drawable.c	25 Jan 2005 19:50:26 -0000	1.2
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -42,15 +42,15 @@
 slim_hidden_def(glitz_find_similar_drawable_format);
     
 glitz_drawable_t *
-glitz_create_pbuffer_drawable (glitz_drawable_t           *other,
-                               glitz_drawable_format_t    *format,
-                               glitz_pbuffer_attributes_t *attributes,
-                               unsigned long              mask)
+glitz_create_pbuffer_drawable (glitz_drawable_t        *other,
+                               glitz_drawable_format_t *format,
+                               unsigned int            width,
+                               unsigned int            height)
 {
   if (!format->types.pbuffer)
     return NULL;
   
-  return other->backend->create_pbuffer (other, format, attributes, mask);
+  return other->backend->create_pbuffer (other, format, width, height);
 }
 slim_hidden_def(glitz_create_pbuffer_drawable);
 
@@ -70,7 +70,7 @@
 void
 glitz_drawable_reference (glitz_drawable_t *drawable)
 {
-  if (drawable == NULL)
+  if (!drawable)
     return;
 
   drawable->ref_count++; 

Index: glitz_filter.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_filter.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- glitz_filter.c	20 Sep 2004 16:06:48 -0000	1.7
+++ glitz_filter.c	25 Jan 2005 19:50:26 -0000	1.8
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -29,36 +29,39 @@
 
 #include "glitzint.h"
 
-#include <math.h>
-
 struct _glitz_filter_params_t {
-  int fp_type;
-  int id;  
+  int          fp_type;
+  int          id;  
   glitz_vec4_t *vectors;
-  int n_vectors;
+  int          n_vectors;
 };
 
-static int
-_glitz_filter_params_ensure (glitz_filter_params_t **params, int vectors)
+static glitz_status_t
+_glitz_filter_params_ensure (glitz_surface_t *surface,
+                             int             vectors)
 {
-  if (*params == NULL) {
-    *params = calloc (1, sizeof (glitz_filter_params_t));
-    if (*params == NULL)      
-      return 1;
-  }
+    int size;
+    
+    size = sizeof (glitz_filter_params_t) + vectors * sizeof (glitz_vec4_t);
+    
+    if (!surface->filter_params ||
+        surface->filter_params->n_vectors != vectors)
+    {
+        if (surface->filter_params)
+            free (surface->filter_params);
+        
+        surface->filter_params = malloc (size);
+        if (surface->filter_params == NULL)      
+            return GLITZ_STATUS_NO_MEMORY;
 
-  if ((*params)->n_vectors != vectors) {
-    (*params)->vectors =
-      realloc ((*params)->vectors, vectors * sizeof (glitz_vec4_t));
-    (*params)->n_vectors = vectors;
-  }
-  
-  if (vectors > 0 && (*params)->vectors == NULL) {
-    free (*params);
-    return 1;
-  }
+        surface->filter_params->fp_type   = 0;
+        surface->filter_params->id        = 0;
+        surface->filter_params->vectors   =
+            (glitz_vec4_t *) (surface->filter_params + 1);
+        surface->filter_params->n_vectors = vectors;
+    }
   
-  return 0;
+    return GLITZ_STATUS_SUCCESS;
 }
 
 static void
@@ -108,7 +111,7 @@
     n = dn;
 
     size = m * n;
-    if (_glitz_filter_params_ensure (&surface->filter_params, size))
+    if (_glitz_filter_params_ensure (surface, size))
       return GLITZ_STATUS_NO_MEMORY;
 
     vecs = surface->filter_params->vectors;
@@ -167,7 +170,7 @@
     size = half_size * 2 + 1;
     xy_scale = 2.0f * radius / size;
 
-    if (_glitz_filter_params_ensure (&surface->filter_params, size * size))
+    if (_glitz_filter_params_ensure (surface, size * size))
       return GLITZ_STATUS_NO_MEMORY;
 
     vecs = surface->filter_params->vectors;
@@ -208,42 +211,42 @@
   case GLITZ_FILTER_LINEAR_GRADIENT:
   case GLITZ_FILTER_RADIAL_GRADIENT:
     if (n_params <= 4) {
-      if (surface->width == 1)
-        size = surface->height;
-      else if (surface->height == 1)
-        size = surface->width;
+      if (surface->box.x2 == 1)
+        size = surface->box.y2;
+      else if (surface->box.y2 == 1)
+        size = surface->box.x2;
     } else
       size = (n_params - 2) / 3;
     
     if (size < 2)
       size = 2;
 
-    if (_glitz_filter_params_ensure (&surface->filter_params, size + 1))
+    if (_glitz_filter_params_ensure (surface, size + 1))
       return GLITZ_STATUS_NO_MEMORY;
 
     vecs = surface->filter_params->vectors;
     
     if (filter == GLITZ_FILTER_LINEAR_GRADIENT) {
       glitz_float_t length, angle, dh, dv;
-      glitz_point_t start, stop;
+      glitz_float_t start_x, start_y, stop_x, stop_y;
 
-      _glitz_filter_params_set (&start.x, 0.0f, &params, &n_params);
-      _glitz_filter_params_set (&start.y, 0.0f, &params, &n_params);
-      _glitz_filter_params_set (&stop.x, 1.0f, &params, &n_params);
-      _glitz_filter_params_set (&stop.y, 0.0f, &params, &n_params);
+      _glitz_filter_params_set (&start_x, 0.0f, &params, &n_params);
+      _glitz_filter_params_set (&start_y, 0.0f, &params, &n_params);
+      _glitz_filter_params_set (&stop_x, 1.0f, &params, &n_params);
+      _glitz_filter_params_set (&stop_y, 0.0f, &params, &n_params);
 
-      dh = stop.x - start.x;
-      dv = stop.y - start.y;
+      dh = stop_x - start_x;
+      dv = stop_y - start_y;
 
-      length = sqrt (dh * dh + dv * dv);
+      length = sqrtf (dh * dh + dv * dv);
 
-      angle = -atan2 (dv, dh);
+      angle = -atan2f (dv, dh);
 
-      vecs->v[2] = cos (angle);
-      vecs->v[3] = -sin (angle);
+      vecs->v[2] = cosf (angle);
+      vecs->v[3] = -sinf (angle);
       
-      vecs->v[0] = vecs->v[2] * start.x;
-      vecs->v[0] += vecs->v[3] * start.y;
+      vecs->v[0] = vecs->v[2] * start_x;
+      vecs->v[0] += vecs->v[3] * start_y;
 
       vecs->v[1] = (length)? 1.0f / length: 2147483647.0f;
     } else {
@@ -270,16 +273,16 @@
       glitz_float_t x_default, y_default, o_default;
       
       o_default = i / (glitz_float_t) (size - 1);
-      x_default = (surface->width * i) / (glitz_float_t) size;
-      y_default = (surface->height * i) / (glitz_float_t) size;
+      x_default = (surface->box.x2 * i) / (glitz_float_t) size;
+      y_default = (surface->box.y2 * i) / (glitz_float_t) size;
       
       _glitz_filter_params_set (&vecs[i].v[2], o_default, &params, &n_params);
       _glitz_filter_params_set (&vecs[i].v[0], x_default, &params, &n_params);
       _glitz_filter_params_set (&vecs[i].v[1], y_default, &params, &n_params);
 
       glitz_clamp_value (&vecs[i].v[2], 0.0f, 1.0f);
-      glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->width - 1.0f);
-      glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->height - 1.0f);
+      glitz_clamp_value (&vecs[i].v[0], 0.0f, surface->box.x2 - 1.0f);
+      glitz_clamp_value (&vecs[i].v[1], 0.0f, surface->box.y2 - 1.0f);
 
       vecs[i].v[0] += 0.5f;
       vecs[i].v[1] += 0.5f;
@@ -313,6 +316,10 @@
     break;
   case GLITZ_FILTER_BILINEAR:
   case GLITZ_FILTER_NEAREST:
+    if (surface->filter_params)
+      free (surface->filter_params);
+
+    surface->filter_params = NULL;
     break;
   }
 
@@ -321,15 +328,6 @@
   return GLITZ_STATUS_SUCCESS;
 }
 
-void
-glitz_filter_params_destroy (glitz_filter_params_t *params)
-{
-  if (params->vectors)
-    free (params->vectors);
-
-  free (params);
-}
-
 glitz_gl_uint_t
 glitz_filter_get_fragment_program (glitz_surface_t *surface,
                                    glitz_composite_op_t *op)

Index: glitz_format.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_format.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- glitz_format.c	3 Nov 2004 22:50:58 -0000	1.9
+++ glitz_format.c	25 Jan 2005 19:50:26 -0000	1.10
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H

Index: glitz_geometry.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_geometry.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- glitz_geometry.c	3 Nov 2004 22:50:58 -0000	1.4
+++ glitz_geometry.c	25 Jan 2005 19:50:26 -0000	1.5
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -29,209 +29,289 @@
 
 #include "glitzint.h"
 
-/* This is supposed to be 8x, 4x and 2x rotated grid multi-sample
-   patterns. I'm not sure they're actually correct. */
-static glitz_sample_offset_t _8x_multi_sample_offsets[] = {
-  { -0.375f, -0.375f },
-  { -0.125f, -0.125f },
-  {  0.375f, -0.375f },
-  {  0.125f, -0.125f },
-  {  0.375f,  0.375f },
-  {  0.125f,  0.125f },
-  { -0.375f,  0.375f },
-  { -0.125f,  0.125f }
-};
 
-static unsigned short _8x_multi_sample_weights[] = {
-  0x2000, 0x4000, 0x6000, 0x8000, 0xa000, 0xbfff, 0xdfff, 0xffff
-};
+static glitz_gl_enum_t
+_glitz_data_type (glitz_data_type_t type)
+{
+    switch (type) {
+    case GLITZ_DATA_TYPE_SHORT:
+        return GLITZ_GL_SHORT;
+    case GLITZ_DATA_TYPE_INT:
+        return GLITZ_GL_INT;
+    case GLITZ_DATA_TYPE_DOUBLE:
+        return GLITZ_GL_DOUBLE;
+    default:
+        return GLITZ_GL_FLOAT;
+    }
+}
 
-static glitz_sample_info_t _8x_multi_sample = {
-  _8x_multi_sample_offsets,
-  _8x_multi_sample_weights,
-  8
-};
+void
+glitz_set_geometry (glitz_surface_t         *dst,
+                    glitz_geometry_type_t   type,
+                    glitz_geometry_format_t *format,
+                    glitz_buffer_t          *buffer)
+{
+    switch (type) {
+    case GLITZ_GEOMETRY_TYPE_VERTEX:
+    {
+        glitz_buffer_reference (buffer);
+        if (dst->geometry.buffer)
+            glitz_buffer_destroy (dst->geometry.buffer);
+        dst->geometry.buffer = buffer;
+        
+        dst->geometry.type = GLITZ_GEOMETRY_TYPE_VERTEX;
+            
+        switch (format->vertex.primitive) {
+        case GLITZ_PRIMITIVE_POINTS:
+            dst->geometry.u.v.prim = GLITZ_GL_POINTS;
+            break;
+        case GLITZ_PRIMITIVE_LINES:
+            dst->geometry.u.v.prim = GLITZ_GL_LINES;
+            break;
+        case GLITZ_PRIMITIVE_LINE_STRIP:
+            dst->geometry.u.v.prim = GLITZ_GL_LINE_STRIP;
+            break;
+        case GLITZ_PRIMITIVE_LINE_LOOP:
+            dst->geometry.u.v.prim = GLITZ_GL_LINE_LOOP;
+            break;
+        case GLITZ_PRIMITIVE_TRIANGLES:
+            dst->geometry.u.v.prim = GLITZ_GL_TRIANGLES;
+            break;
+        case GLITZ_PRIMITIVE_TRIANGLE_STRIP:
+            dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_STRIP;
+            break;
+        case GLITZ_PRIMITIVE_TRIANGLE_FAN:
+            dst->geometry.u.v.prim = GLITZ_GL_TRIANGLE_FAN;
+            break;
+        case GLITZ_PRIMITIVE_QUADS:
+            dst->geometry.u.v.prim = GLITZ_GL_QUADS;
+            break;
+        case GLITZ_PRIMITIVE_QUAD_STRIP:
+            dst->geometry.u.v.prim = GLITZ_GL_QUAD_STRIP;
+            break;
+        default:
+            dst->geometry.u.v.prim = GLITZ_GL_POLYGON;
+                break;
+        }
+            
+        dst->geometry.u.v.type = _glitz_data_type (format->vertex.type);
+        dst->geometry.stride = format->vertex.bytes_per_vertex;    
+        dst->geometry.attributes = format->vertex.attributes;
 
-static glitz_sample_offset_t _4x_multi_sample_offsets[] = {
-  { -0.125f, -0.375f },
-  {  0.375f, -0.125f },
-  {  0.125f,  0.375f },
-  { -0.375f,  0.125f }
-};
+        if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK)
+        {
+            dst->geometry.u.v.src.type =
+                _glitz_data_type (format->vertex.src.type);
+            dst->geometry.u.v.src.offset = format->vertex.src.offset;
+                
+            if (format->vertex.src.size == GLITZ_COORDINATE_SIZE_XY)
+                dst->geometry.u.v.src.size = 2;
+            else
+                dst->geometry.u.v.src.size = 1;
+        }
+        
+        if (format->vertex.attributes & GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK)
+        {
+            dst->geometry.u.v.mask.type =
+                _glitz_data_type (format->vertex.mask.type);
+            dst->geometry.u.v.mask.offset = format->vertex.mask.offset;
+            
+            if (format->vertex.mask.size == GLITZ_COORDINATE_SIZE_XY)
+                dst->geometry.u.v.mask.size = 2;
+            else
+                dst->geometry.u.v.mask.size = 1;
+        }
+    } break;
+    case GLITZ_GEOMETRY_TYPE_BITMAP:
+        glitz_buffer_reference (buffer);
+        if (dst->geometry.buffer)
+            glitz_buffer_destroy (dst->geometry.buffer);
+        dst->geometry.buffer = buffer;
+        
+        dst->geometry.type = GLITZ_GEOMETRY_TYPE_BITMAP;
 
-static unsigned short _4x_multi_sample_weights[] = {
-  0x4000, 0x8000, 0xbfff, 0xffff
-};
+        if (format->bitmap.scanline_order ==
+            GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
+            dst->geometry.u.b.top_down = 1;
+        else
+            dst->geometry.u.b.top_down = 0;
 
-static glitz_sample_info_t _4x_multi_sample = {
-  _4x_multi_sample_offsets,
-  _4x_multi_sample_weights,
-  4
-};
+        switch (format->bitmap.pad) {
+        case 2:
+            dst->geometry.u.b.pad = 2;
+            break;
+        case 4:
+            dst->geometry.u.b.pad = 4;
+            break;
+        case 8:
+            dst->geometry.u.b.pad = 8;
+            break;
+        default:
+            dst->geometry.u.b.pad = 1;
+            break;
+        }
+    
+        dst->geometry.stride = format->bitmap.bytes_per_line;
+        dst->geometry.attributes = 0;
+        break;
+    default:
+        dst->geometry.type = GLITZ_GEOMETRY_TYPE_NONE;
+        if (dst->geometry.buffer)
+            glitz_buffer_destroy (dst->geometry.buffer);
 
-static glitz_sample_offset_t _2x_multi_sample_offsets[] = {
-  { -0.24f, -0.24f },
-  {  0.24f,  0.24f }
-};
+        dst->geometry.buffer = NULL;
+        dst->geometry.attributes = 0;
+        break;
+    }
+}
+slim_hidden_def(glitz_set_geometry);
 
-static unsigned short _2x_multi_sample_weights[] = {
-  0x8000, 0xffff
-};
+void
+glitz_set_array (glitz_surface_t    *dst,
+                 int                first,
+                 int                size,
+                 unsigned int       count,
+                 glitz_fixed16_16_t x_off,
+                 glitz_fixed16_16_t y_off)
+{
+    if (dst->geometry.array)
+    {
+        glitz_multi_array_destroy (dst->geometry.array);
+        dst->geometry.array = NULL;
+    }
+    
+    dst->geometry.first    = first;
+    dst->geometry.size     = size;
+    dst->geometry.count    = count;
+    dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off);
+    dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off);
+}
+slim_hidden_def(glitz_set_array);
 
-static glitz_sample_info_t _2x_multi_sample = {
-  _2x_multi_sample_offsets,
-  _2x_multi_sample_weights,
-  2
-};
+glitz_multi_array_t *
+glitz_multi_array_create (unsigned int size)
+{
+  glitz_multi_array_t *array;
+  int                 alloc_size;
 
-static glitz_sample_offset_t _1x_sample_offsets[] = {
-  {  0.0f,  0.0f }
-};
+  if (!size)
+      return NULL;
 
-static unsigned short _1x_sample_weights[] = {
-  0xffff
-};
+  alloc_size = sizeof (glitz_multi_array_t) + (sizeof (int) +
+                                               sizeof (int) +
+                                               sizeof (unsigned int) +
+                                               sizeof (glitz_vec2_t) +
+                                               sizeof (int)) * (size);
+  
+  array = (glitz_multi_array_t *) malloc (alloc_size);
+  if (array == NULL)
+      return NULL;
 
-static glitz_sample_info_t _1x_sample = {
-  _1x_sample_offsets,
-  _1x_sample_weights,
-  1
-};
+  array->ref_count = 1;
+  array->size      = size;
+  array->first     = (int *)          (array + 1);
+  array->sizes     = (int *)          (array->first + size);
+  array->count     = (int *)          (array->sizes + size);
+  array->off       = (glitz_vec2_t *) (array->count + size);
+  array->span      = (int *)          (array->off   + size);
+
+  array->n_arrays = 0;
+  
+  return array;
+}
+slim_hidden_def(glitz_multi_array_create);
 
 void
-glitz_set_geometry (glitz_surface_t         *dst,
-                    glitz_fixed16_16_t      x_dst,
-                    glitz_fixed16_16_t      y_dst,
-                    glitz_geometry_format_t *format,
-                    glitz_buffer_t          *buffer)
+glitz_multi_array_destroy (glitz_multi_array_t *array)
 {
-  glitz_drawable_t *drawable = (dst->attached)? dst->attached: dst->drawable;
-
-  if (buffer) {
-    glitz_buffer_reference (buffer);
+    if (!array)
+        return;
     
-    if (dst->geometry.buffer)
-      glitz_buffer_destroy (dst->geometry.buffer);
-
-    dst->geometry.buffer = buffer;
+    array->ref_count--;
+    if (array->ref_count)
+        return;
     
-    dst->geometry.x_offset = FIXED_TO_FLOAT (x_dst);
-    dst->geometry.y_offset = FIXED_TO_FLOAT (y_dst);
+    free (array);
+}
 
-    switch (format->primitive) {
-    case GLITZ_GEOMETRY_PRIMITIVE_POINTS:
-      dst->geometry.primitive = GLITZ_GL_POINTS;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_LINES:
-      dst->geometry.primitive = GLITZ_GL_LINES;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP:
-      dst->geometry.primitive = GLITZ_GL_LINE_STRIP;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP:
-      dst->geometry.primitive = GLITZ_GL_LINE_LOOP;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLES:
-      dst->geometry.primitive = GLITZ_GL_TRIANGLES;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_STRIP:
-      dst->geometry.primitive = GLITZ_GL_TRIANGLE_STRIP;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_TRIANGLE_FAN:
-      dst->geometry.primitive = GLITZ_GL_TRIANGLE_FAN;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_QUADS:
-      dst->geometry.primitive = GLITZ_GL_QUADS;
-      break;
-    case GLITZ_GEOMETRY_PRIMITIVE_QUAD_STRIP:
-      dst->geometry.primitive = GLITZ_GL_QUAD_STRIP;
-      break;
-    default:
-      dst->geometry.primitive = GLITZ_GL_POLYGON;
-      break;
-    }
+void
+glitz_multi_array_reference (glitz_multi_array_t *array)
+{
+    if (array == NULL)
+        return;
+    
+    array->ref_count++;
+}
 
-    switch (format->type) {
-    case GLITZ_DATA_TYPE_SHORT:
-      dst->geometry.type = GLITZ_GL_SHORT;
-      break;
-    case GLITZ_DATA_TYPE_INT:
-      dst->geometry.type = GLITZ_GL_INT;
-      break;
-    case GLITZ_DATA_TYPE_DOUBLE:
-      dst->geometry.type = GLITZ_GL_DOUBLE;
-      break;
-    default:
-      dst->geometry.type = GLITZ_GL_FLOAT;
-      break;
-    }
+void
+glitz_multi_array_add (glitz_multi_array_t *array,
+                       int                 first,
+                       int                 size,
+                       unsigned int        count,
+                       glitz_fixed16_16_t  x_off,
+                       glitz_fixed16_16_t  y_off)
+{
+    int i;
 
-    dst->geometry.first = format->first;
-    dst->geometry.count = format->count;
+    if (array->size == array->n_arrays)
+        return;
 
-    if (drawable->format->samples > 1) {
-      if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_SHARP) {
-        dst->flags |= GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
+    i = array->n_arrays++;
 
-        if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH)
-          dst->flags |= GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK;
-        else
-          dst->flags &= ~GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK;
-      } else
-        dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
-    } else {
-      if (format->mode == GLITZ_GEOMETRY_MODE_INDIRECT) {
-        switch (format->edge_hint) {
-        case GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH:
-          if (drawable->format->stencil_size >= 4) {
-            dst->indirect = &_8x_multi_sample;
-            break;
-          }
-          /* fall-through */
-        case GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH:
-          if (drawable->format->stencil_size >= 3) {
-            dst->indirect = &_4x_multi_sample;
-            break;
-          }
-          /* fall-through */
-        case GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH:
-          if (drawable->format->stencil_size >= 2) {
-            dst->indirect = &_2x_multi_sample;
-            break;
-          }
-          /* fall-through */
-        case GLITZ_GEOMETRY_EDGE_HINT_SHARP:
-        default:
-          dst->indirect = &_1x_sample;
-          break;
-        }
-      } else
-        dst->indirect = NULL;
+    array->first[i] = first;
+    array->sizes[i] = size;
+    array->count[i] = count;
+    array->span[i]  = 0;
+        
+    if (i == 0 || x_off || y_off)
+    {
+        array->off[i].v[0]  = FIXED_TO_FLOAT (x_off);
+        array->off[i].v[1]  = FIXED_TO_FLOAT (y_off);
+        array->current_span = &array->span[i];
     }
-  } else {
-    if (dst->geometry.buffer)
-      glitz_buffer_destroy (dst->geometry.buffer);
+    
+    (*array->current_span)++;
+}
+slim_hidden_def(glitz_multi_array_add);
 
-    dst->geometry.buffer = NULL;
-    dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
-    dst->indirect = NULL;
-  }
+void
+glitz_multi_array_reset (glitz_multi_array_t *array)
+{
+    array->n_arrays = 0;
 }
-slim_hidden_def(glitz_set_geometry);
+slim_hidden_def(glitz_multi_array_reset);
 
 void
-glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl,
-                               glitz_surface_t              *dst,
-                               glitz_box_t                  *box)
+glitz_set_multi_array (glitz_surface_t     *dst,
+                       glitz_multi_array_t *array,
+                       glitz_fixed16_16_t  x_off,
+                       glitz_fixed16_16_t  y_off)
 {
-  dst->geometry.data[0] = box->x1;
-  dst->geometry.data[1] = box->y1;
-  dst->geometry.data[2] = box->x2;
-  dst->geometry.data[3] = box->y1;
-  dst->geometry.data[4] = box->x2;
-  dst->geometry.data[5] = box->y2;
-  dst->geometry.data[6] = box->x1;
-  dst->geometry.data[7] = box->y2;
+    glitz_multi_array_reference (array);
+    
+    if (dst->geometry.array)
+        glitz_multi_array_destroy (dst->geometry.array);
+
+    dst->geometry.array = array;
+    dst->geometry.count = array->n_arrays;
+    dst->geometry.off.v[0] = FIXED_TO_FLOAT (x_off);
+    dst->geometry.off.v[1] = FIXED_TO_FLOAT (y_off);
+}
+slim_hidden_def(glitz_set_multi_array);
+
+void
+glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl,
+                            glitz_surface_t              *dst,
+                            glitz_box_t                  *box)
+{
+  dst->geometry.data[0] = (glitz_float_t) box->x1;
+  dst->geometry.data[1] = (glitz_float_t) box->y1;
+  dst->geometry.data[2] = (glitz_float_t) box->x2;
+  dst->geometry.data[3] = (glitz_float_t) box->y1;
+  dst->geometry.data[4] = (glitz_float_t) box->x2;
+  dst->geometry.data[5] = (glitz_float_t) box->y2;
+  dst->geometry.data[6] = (glitz_float_t) box->x1;
+  dst->geometry.data[7] = (glitz_float_t) box->y2;
   
   gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, dst->geometry.data);
 }
@@ -239,38 +319,362 @@
 void
 glitz_geometry_enable (glitz_gl_proc_address_list_t *gl,
                        glitz_surface_t              *dst,
-                       glitz_gl_enum_t              *primitive,
-                       glitz_gl_int_t               *first,
-                       glitz_gl_sizei_t             *count,
                        glitz_box_t                  *box)
 {
-  if (dst->geometry.buffer) {
-    void *ptr;
+    switch (dst->geometry.type) {
+    case GLITZ_GEOMETRY_TYPE_VERTEX:
+        gl->vertex_pointer (2, dst->geometry.u.v.type, dst->geometry.stride,
+                            glitz_buffer_bind (dst->geometry.buffer,
+                                               GLITZ_GL_ARRAY_BUFFER));
+        break;
+    case GLITZ_GEOMETRY_TYPE_BITMAP:
+        dst->geometry.u.b.base =
+            glitz_buffer_bind (dst->geometry.buffer,
+                               GLITZ_GL_PIXEL_UNPACK_BUFFER);
 
-    ptr = glitz_buffer_bind (dst->geometry.buffer, GLITZ_GL_ARRAY_BUFFER);
+        gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, 0);
+        gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_ROWS, 0);
 
-    gl->vertex_pointer (2, dst->geometry.type, 0, ptr);
+#if BITMAP_BIT_ORDER == MSBFirst
+        gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_FALSE);
+#else
+        gl->pixel_store_i (GLITZ_GL_UNPACK_LSB_FIRST, GLITZ_GL_TRUE);
+#endif
+        
+        break;
+    case GLITZ_GEOMETRY_TYPE_NONE:
+        glitz_geometry_enable_none (gl, dst, box);
+    }
+}
+
+void
+glitz_geometry_disable (glitz_surface_t *dst)
+{
+    if (dst->geometry.buffer)
+        glitz_buffer_unbind (dst->geometry.buffer);
+}
+
+static void
+_glitz_draw_rectangle (glitz_gl_proc_address_list_t *gl,
+                       glitz_surface_t              *dst,
+                       glitz_box_t                  *bounds,
+                       int                          damage)
+{
+    glitz_box_t         *clip = dst->clip;
+    int                 n_clip = dst->n_clip;
+    glitz_box_t         box;
     
-    if (dst->geometry.x_offset || dst->geometry.y_offset)
-      gl->translate_f (dst->geometry.x_offset, dst->geometry.y_offset, 0.0f);
+    while (n_clip--)
+    {
+        box.x1 = clip->x1 + dst->x_clip;
+        box.y1 = clip->y1 + dst->y_clip;
+        box.x2 = clip->x2 + dst->x_clip;
+        box.y2 = clip->y2 + dst->y_clip;
+        if (bounds->x1 > box.x1)
+            box.x1 = bounds->x1;
+        if (bounds->y1 > box.y1)
+            box.y1 = bounds->y1;
+        if (bounds->x2 < box.x2)
+            box.x2 = bounds->x2;
+        if (bounds->y2 < box.y2)
+            box.y2 = bounds->y2;
+        
+        if (box.x1 < box.x2 && box.y1 < box.y2)
+        {
+            gl->scissor (box.x1 + dst->x,
+                         dst->attached->height - dst->y - box.y2,
+                         box.x2 - box.x1, box.y2 - box.y1);
+
+            gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
+            
+            if (damage)
+                glitz_surface_damage (dst, &box, damage);
+        }
+        
+        clip++;
+    }
+}
+
+#define MULTI_DRAW_ARRAYS(surface)                \
+    ((surface)->drawable->backend->feature_mask & \
+     GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK)
+
+static void
+_glitz_draw_vertex_arrays (glitz_gl_proc_address_list_t *gl,
+                           glitz_surface_t              *dst,
+                           glitz_box_t                  *bounds,
+                           int                          damage)
+{
+    glitz_multi_array_t *array = dst->geometry.array;
+    glitz_box_t         *clip = dst->clip;
+    int                 i, n_clip = dst->n_clip;
+    glitz_box_t         box;
     
-    *primitive = dst->geometry.primitive;
-    *first = dst->geometry.first;
-    *count = dst->geometry.count;
-  } else {
-    glitz_geometry_enable_default (gl, dst, box);
-    *primitive = GLITZ_GL_QUADS;
-    *first = 0;
-    *count = 4;
-  }
+    while (n_clip--)
+    {
+        box.x1 = clip->x1 + dst->x_clip;
+        box.y1 = clip->y1 + dst->y_clip;
+        box.x2 = clip->x2 + dst->x_clip;
+        box.y2 = clip->y2 + dst->y_clip;
+        if (bounds->x1 > box.x1)
+            box.x1 = bounds->x1;
+        if (bounds->y1 > box.y1)
+            box.y1 = bounds->y1;
+        if (bounds->x2 < box.x2)
+            box.x2 = bounds->x2;
+        if (bounds->y2 < box.y2)
+            box.y2 = bounds->y2;
+        
+        if (box.x1 < box.x2 && box.y1 < box.y2)
+        {
+            gl->scissor (box.x1 + dst->x,
+                         dst->attached->height - dst->y - box.y2,
+                         box.x2 - box.x1, box.y2 - box.y1);
+
+            gl->push_matrix ();
+                    
+            if (dst->geometry.off.v[0] || dst->geometry.off.v[1])
+                gl->translate_f (dst->geometry.off.v[0],
+                                 dst->geometry.off.v[1], 0.0f);
+            
+            if (array)
+            {
+                for (i = 0; i < array->n_arrays;)
+                {
+                    gl->translate_f (array->off[i].v[0],
+                                     array->off[i].v[1], 0.0f);
+                    
+                    if (MULTI_DRAW_ARRAYS (dst))
+                    {
+                        gl->multi_draw_arrays (dst->geometry.u.v.prim,
+                                               &array->first[i],
+                                               &array->count[i],
+                                               array->span[i]);
+                        i += array->span[i];
+                    }
+                    else
+                    {
+                        do {
+                            if (array->count[i])
+                                gl->draw_arrays (dst->geometry.u.v.prim,
+                                                 array->first[i],
+                                                 array->count[i]);
+                                
+                        } while (array->span[++i] == 0);
+                    }
+                }
+            } else
+                gl->draw_arrays (dst->geometry.u.v.prim,
+                                 dst->geometry.first,
+                                 dst->geometry.count);
+                
+            gl->pop_matrix ();
+            
+            if (damage)
+                glitz_surface_damage (dst, &box, damage);
+        }
+        
+        clip++;
+    }
+}
+
+#define N_STACK_BITMAP 128
+
+#define BITMAP_PAD 4
+#define BITMAP_STRIDE(x, w, a)                                  \
+    (((((x) & 3) + (w) + (((a) << 3) - 1)) / ((a) << 3)) * (a))
+
+#define BITMAP_SETUP(dst, first, size, count, _w, _h, _b_off, _p_off) \
+    (_w)     = (size);                                                \
+    (_h)     = (count);                                               \
+    (_b_off) = (first) >> 3;                                          \
+    if ((_p_off) != ((first) & 3))                                    \
+    {                                                                 \
+        (_p_off) = (first) & 3;                                       \
+        gl->pixel_store_i (GLITZ_GL_UNPACK_SKIP_PIXELS, _p_off);      \
+    }                                                                 \
+    if ((dst)->geometry.u.b.top_down)                                 \
+    {                                                                 \
+        dst_stride = BITMAP_STRIDE ((first), _w, BITMAP_PAD);         \
+        if ((dst)->geometry.stride)                                   \
+            src_stride = (dst)->geometry.stride;                      \
+        else                                                          \
+            src_stride = BITMAP_STRIDE ((first), _w,                  \
+                                        (dst)->geometry.u.b.pad);     \
+        min_stride = MIN (src_stride, dst_stride);                    \
+        base = (dst)->geometry.u.b.base + (_b_off);                   \
+        y = (_h);                                                     \
+        while (y--)                                                   \
+            memcpy (bitmap + ((_h) - 1 - y) * dst_stride,             \
+                    base + y * src_stride,                            \
+                    min_stride);                                      \
+        (_b_off) = 0;                                                 \
+    }
+
+/* TODO: clipping could be done without glScissor, that might be
+   faster. Other then solid colors can be used if bitmap fits into a
+   stipple pattern. Maybe we should add a repeat parameter to
+   glitz_bitmap_format_t as 2, 4, 8, 16 and 32 sized bitmaps can be tiled.
+ */
+static void
+_glitz_draw_bitmap_arrays (glitz_gl_proc_address_list_t *gl,
+                           glitz_surface_t              *dst,
+                           glitz_box_t                  *bounds,
+                           int                          damage)
+{
+    glitz_multi_array_t *array = dst->geometry.array;
+    glitz_box_t         *clip = dst->clip;
+    int                 n, i, n_clip = dst->n_clip;
+    int                 x, y, w, h, min_stride, dst_stride, src_stride;
+    glitz_gl_ubyte_t    *heap_bitmap = NULL;
+    glitz_gl_ubyte_t    stack_bitmap[N_STACK_BITMAP];
+    glitz_gl_ubyte_t    *base, *bitmap = dst->geometry.u.b.base;
+    int                 byte_offset, pixel_offset = 0;
+    glitz_float_t       x_off, y_off;
+    glitz_box_t         box;
+    
+    if (dst->geometry.u.b.top_down)
+    {
+        int max_size = 0;
+    
+        if (array)
+        {
+            int size;
+            
+            for (i = 0, n = array->n_arrays; n--; i++)
+            {
+                x = array->first[i];
+                w = array->sizes[i];
+                size = BITMAP_STRIDE (x, w, BITMAP_PAD) * array->count[i];
+                if (size > max_size)
+                    max_size = size;
+            }
+        }
+        else
+        {
+            x = dst->geometry.first;
+            w = dst->geometry.size;
+            max_size = BITMAP_STRIDE (x, w, BITMAP_PAD) * dst->geometry.count;
+        }
+
+        if (max_size > N_STACK_BITMAP)
+        {
+            heap_bitmap = malloc (max_size);
+            if (!heap_bitmap)
+            {
+                glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
+                return;
+            }
+            bitmap = heap_bitmap;
+        } else
+            bitmap = stack_bitmap;
+
+        gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, BITMAP_PAD);
+        gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, 0);
+    }
+    else
+    {
+        gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, dst->geometry.u.b.pad);
+        gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH,
+                           dst->geometry.stride * 8);
+    }
+    
+    while (n_clip--)
+    {
+        box.x1 = clip->x1 + dst->x_clip;
+        box.y1 = clip->y1 + dst->y_clip;
+        box.x2 = clip->x2 + dst->x_clip;
+        box.y2 = clip->y2 + dst->y_clip;
+        if (bounds->x1 > box.x1)
+            box.x1 = bounds->x1;
+        if (bounds->y1 > box.y1)
+            box.y1 = bounds->y1;
+        if (bounds->x2 < box.x2)
+            box.x2 = bounds->x2;
+        if (bounds->y2 < box.y2)
+            box.y2 = bounds->y2;
+        
+        if (box.x1 < box.x2 && box.y1 < box.y2)
+        {
+            gl->scissor (box.x1 + dst->x,
+                         dst->attached->height - dst->y - box.y2,
+                         box.x2 - box.x1, box.y2 - box.y1);
+
+            x_off = dst->x + dst->geometry.off.v[0];
+            y_off = dst->y + dst->geometry.off.v[1];
+            
+            if (array)
+            {
+                x_off += array->off->v[0];
+                y_off += array->off->v[1];
+
+                glitz_set_raster_pos (gl, x_off,
+                                      dst->attached->height - y_off);
+
+                for (i = 0, n = array->n_arrays; n--; i++)
+                {    
+                    if (n)
+                    {
+                        x_off = array->off[i + 1].v[0];
+                        y_off = array->off[i + 1].v[1];
+                    }
+
+                    BITMAP_SETUP (dst,
+                                  array->first[i],
+                                  array->sizes[i],
+                                  array->count[i],
+                                  w, h, byte_offset, pixel_offset);
+                        
+                    gl->bitmap (w, h,
+                                0.0f, (glitz_gl_float_t) array->count[i],
+                                x_off, -y_off,
+                                bitmap + byte_offset);
+                }
+            }
+            else
+            {
+                glitz_set_raster_pos (gl, x_off,
+                                      dst->attached->height - y_off);
+                
+                BITMAP_SETUP (dst,
+                              dst->geometry.first,
+                              dst->geometry.size,
+                              dst->geometry.count,
+                              w, h, byte_offset, pixel_offset);
+                
+                gl->bitmap (w, h,
+                            0.0f, (glitz_gl_float_t) dst->geometry.count,
+                            0.0f, 0.0f,
+                            bitmap + byte_offset);
+            }
+
+            if (damage)
+                glitz_surface_damage (dst, &box, damage);
+        }
+        
+        clip++;
+    }
+
+    if (heap_bitmap)
+        free (heap_bitmap);
 }
 
 void
-glitz_geometry_disable (glitz_gl_proc_address_list_t *gl,
-                        glitz_surface_t              *dst)
+glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl,
+                            glitz_surface_t              *dst,
+                            glitz_geometry_type_t        type,
+                            glitz_box_t                  *bounds,
+                            int                          damage)
 {
-  if (dst->geometry.buffer &&
-      (dst->drawable->backend->feature_mask &
-       GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK))
-    gl->bind_buffer (GLITZ_GL_ARRAY_BUFFER, 0);
+    switch (type) {
+    case GLITZ_GEOMETRY_TYPE_VERTEX:
+        _glitz_draw_vertex_arrays (gl, dst, bounds, damage);
+        break;
+    case GLITZ_GEOMETRY_TYPE_BITMAP:
+        _glitz_draw_bitmap_arrays (gl, dst, bounds, damage);
+        break;
+    case GLITZ_GEOMETRY_TYPE_NONE:
+        _glitz_draw_rectangle (gl, dst, bounds, damage);
+        break;
+    }
 }

Index: glitz_gl.h
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_gl.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- glitz_gl.h	3 Nov 2004 22:50:58 -0000	1.13
+++ glitz_gl.h	25 Jan 2005 19:50:26 -0000	1.14
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
+ * Copyright © 2004 David Reveman, Peter Nilsson
  *
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
@@ -21,7 +21,7 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
+ * Authors: David Reveman <davidr at novell.com>
  *          Peter Nilsson <c99pnn at cs.umu.se>
  */
 
@@ -39,6 +39,7 @@
 typedef double glitz_gl_double_t;
 typedef float glitz_gl_float_t;
 typedef unsigned short glitz_gl_ushort_t;
+typedef short glitz_gl_short_t;
 typedef unsigned int glitz_gl_bitfield_t;
 typedef double glitz_gl_clampd_t;
 typedef float glitz_gl_clampf_t;
@@ -57,7 +58,6 @@
 #define GLITZ_GL_EXTENSIONS                  0x1F03
 
 #define GLITZ_GL_UNSIGNED_BYTE               0x1401
-#define GLITZ_GL_FLOAT                       0x1406
 #define GLITZ_GL_UNSIGNED_BYTE_3_3_2         0x8032
 #define GLITZ_GL_UNSIGNED_BYTE_2_3_3_REV     0x8362
 #define GLITZ_GL_UNSIGNED_SHORT_5_6_5        0x8363
@@ -89,7 +89,8 @@
 #define GLITZ_GL_QUAD_STRIP     0x0008
 #define GLITZ_GL_POLYGON        0x0009
 
-#define GLITZ_GL_VERTEX_ARRAY   0x8074
+#define GLITZ_GL_VERTEX_ARRAY        0x8074
+#define GLITZ_GL_TEXTURE_COORD_ARRAY 0x8078
 
 #define GLITZ_GL_FILL           0x1B02
 #define GLITZ_GL_FRONT          0x0404
@@ -225,10 +226,12 @@
 #define GLITZ_GL_CONSTANT_COLOR      0x8001
 
 #define GLITZ_GL_PACK_ALIGNMENT      0x0D05
+#define GLITZ_GL_PACK_LSB_FIRST      0x0D01
 #define GLITZ_GL_PACK_ROW_LENGTH     0x0D02
 #define GLITZ_GL_PACK_SKIP_PIXELS    0x0D04
 #define GLITZ_GL_PACK_SKIP_ROWS      0x0D03
 #define GLITZ_GL_UNPACK_ALIGNMENT    0x0CF5
+#define GLITZ_GL_UNPACK_LSB_FIRST    0x0CF1
 #define GLITZ_GL_UNPACK_ROW_LENGTH   0x0CF2
 #define GLITZ_GL_UNPACK_SKIP_PIXELS  0x0CF4
 #define GLITZ_GL_UNPACK_SKIP_ROWS    0x0CF3
@@ -282,9 +285,9 @@
 #define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS 0x880F
 #define GLITZ_GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS 0x8810
 
-#define GLITZ_GL_ARRAY_BUFFER        0x8892
-#define GLITZ_GL_PIXEL_PACK_BUFFER   0x88EB
-#define GLITZ_GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GLITZ_GL_ARRAY_BUFFER         0x8892
+#define GLITZ_GL_PIXEL_PACK_BUFFER    0x88EB
+#define GLITZ_GL_PIXEL_UNPACK_BUFFER  0x88EC
 
 #define GLITZ_GL_STREAM_DRAW  0x88E0
 #define GLITZ_GL_STREAM_READ  0x88E1
@@ -316,8 +319,14 @@
 typedef glitz_gl_void_t (* glitz_gl_vertex_pointer_t)
      (glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride,
       const glitz_gl_void_t *ptr);
+typedef glitz_gl_void_t (* glitz_gl_tex_coord_pointer_t)
+     (glitz_gl_int_t size, glitz_gl_enum_t type, glitz_gl_sizei_t stride,
+      const glitz_gl_void_t *ptr);
 typedef glitz_gl_void_t (* glitz_gl_draw_arrays_t)
      (glitz_gl_enum_t mode, glitz_gl_int_t first, glitz_gl_sizei_t count);
+typedef glitz_gl_void_t (* glitz_gl_multi_draw_arrays_t)
+     (glitz_gl_enum_t mode, glitz_gl_int_t *first, glitz_gl_sizei_t *count,
+      glitz_gl_sizei_t primcount);
 typedef glitz_gl_void_t (* glitz_gl_tex_env_f_t)
      (glitz_gl_enum_t target, glitz_gl_enum_t pname, glitz_gl_float_t param);
 typedef glitz_gl_void_t (* glitz_gl_tex_env_fv_t)
@@ -457,6 +466,8 @@
      (glitz_gl_enum_t pname, glitz_gl_void_t **params);
 typedef glitz_gl_void_t (* glitz_gl_active_texture_t)
      (glitz_gl_enum_t);
+typedef glitz_gl_void_t (* glitz_gl_client_active_texture_t)
+     (glitz_gl_enum_t);
 typedef glitz_gl_void_t (* glitz_gl_gen_programs_t)
      (glitz_gl_sizei_t, glitz_gl_uint_t *);
 typedef glitz_gl_void_t (* glitz_gl_delete_programs_t)

Index: glitz_operator.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_operator.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- glitz_operator.c	3 Nov 2004 22:50:58 -0000	1.6
+++ glitz_operator.c	25 Jan 2005 19:50:26 -0000	1.7
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
+ * Copyright © 2004 David Reveman, Peter Nilsson
  *
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
@@ -21,7 +21,7 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
+ * Authors: David Reveman <davidr at novell.com>
  *          Peter Nilsson <c99pnn at cs.umu.se>
  */
 

Index: glitz_pixel.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_pixel.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- glitz_pixel.c	3 Dec 2004 02:19:51 -0000	1.14
+++ glitz_pixel.c	25 Jan 2005 19:50:26 -0000	1.15
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -599,8 +599,8 @@
 
   GLITZ_GL_SURFACE (dst);
 
-  if (x_dst < 0 || x_dst > (dst->width - width) ||
-      y_dst < 0 || y_dst > (dst->height - height)) {
+  if (x_dst < 0 || x_dst > (dst->box.x2 - width) ||
+      y_dst < 0 || y_dst > (dst->box.y2 - height)) {
     glitz_surface_status_add (dst, GLITZ_STATUS_BAD_COORDINATE_MASK);
     return;
   }
@@ -612,6 +612,7 @@
 
   if (SURFACE_SOLID (dst)) {
     glitz_image_t src_image, dst_image;
+    glitz_color_t old = dst->solid;
 
     dst_image.width = dst_image.height = 1;
 
@@ -620,7 +621,7 @@
     src_image.format = format;
     src_image.width = src_image.height = 1;
 
-    if (format->masks.alpha_mask) {
+    if (format->masks.alpha_mask && dst->format->color.alpha_size) {
       dst_image.data = (void *) &dst->solid.alpha;
       dst_image.format = &_solid_format[SOLID_ALPHA];
 
@@ -630,7 +631,7 @@
     } else
       dst->solid.alpha = 0xffff;
 
-    if (format->masks.red_mask) {
+    if (format->masks.red_mask && dst->format->color.red_size) {
       dst_image.data = (void *) &dst->solid.red;
       dst_image.format = &_solid_format[SOLID_RED];
 
@@ -640,7 +641,7 @@
     } else
       dst->solid.red = 0;
 
-    if (format->masks.green_mask) {
+    if (format->masks.green_mask && dst->format->color.green_size) {
       dst_image.data = (void *) &dst->solid.green;
       dst_image.format = &_solid_format[SOLID_GREEN];
 
@@ -650,7 +651,7 @@
     } else
       dst->solid.green = 0;
 
-    if (format->masks.blue_mask) {
+    if (format->masks.blue_mask && dst->format->color.blue_size) {
       dst_image.data = (void *) &dst->solid.blue;
       dst_image.format = &_solid_format[SOLID_BLUE];
 
@@ -662,10 +663,23 @@
 
     glitz_buffer_unmap (buffer);
 
-    dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
-    glitz_surface_damage (dst, &box,
-                          GLITZ_DAMAGE_TEXTURE_MASK |
-                          GLITZ_DAMAGE_DRAWABLE_MASK);
+    if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
+    {
+        dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
+        glitz_surface_damage (dst, &box,
+                              GLITZ_DAMAGE_TEXTURE_MASK |
+                              GLITZ_DAMAGE_DRAWABLE_MASK);
+    }
+    else
+    {
+        if (dst->solid.red   != old.red   ||
+            dst->solid.green != old.green ||
+            dst->solid.blue  != old.blue  ||
+            dst->solid.alpha != old.alpha)
+            glitz_surface_damage (dst, &box,
+                                  GLITZ_DAMAGE_TEXTURE_MASK |
+                                  GLITZ_DAMAGE_DRAWABLE_MASK);
+    }
     return;
   }
 
@@ -750,12 +764,10 @@
   if (bytes_per_line) {
     if ((bytes_per_line % 4) == 0)
       gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 4);
-    else if ((bytes_per_line % 3) == 0)
-      gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 3);
     else if ((bytes_per_line % 2) == 0)
       gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2);
     else
-      gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 2);
+      gl->pixel_store_i (GLITZ_GL_UNPACK_ALIGNMENT, 1);
 
     gl->pixel_store_i (GLITZ_GL_UNPACK_ROW_LENGTH, bytes_per_line / (bpp / 8));
   } else {
@@ -808,8 +820,8 @@
 
   GLITZ_GL_SURFACE (src);
   
-  if (x_src < 0 || x_src > (src->width - width) ||
-      y_src < 0 || y_src > (src->height - height)) {
+  if (x_src < 0 || x_src > (src->box.x2 - width) ||
+      y_src < 0 || y_src > (src->box.y2 - height)) {
     glitz_surface_status_add (src, GLITZ_STATUS_BAD_COORDINATE_MASK);
     return;
   }
@@ -969,12 +981,10 @@
   if (bytes_per_line) {
     if ((bytes_per_line % 4) == 0)
       gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 4);
-    else if ((bytes_per_line % 3) == 0)
-      gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 3);
     else if ((bytes_per_line % 2) == 0)
       gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2);
     else
-      gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 2);
+      gl->pixel_store_i (GLITZ_GL_PACK_ALIGNMENT, 1);
     
     gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, bytes_per_line / (bpp / 8));
   } else {
@@ -982,7 +992,7 @@
     gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0);
   }
 
-  if (from_drawable) {    
+  if (from_drawable) {
     gl->read_buffer (src->buffer);
     
     gl->disable (GLITZ_GL_SCISSOR_TEST);

Index: glitz_program.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_program.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- glitz_program.c	3 Nov 2004 22:50:58 -0000	1.16
+++ glitz_program.c	25 Jan 2005 19:50:26 -0000	1.17
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -32,69 +32,110 @@
 #include <stdio.h>
 
 #define EXPAND_NONE ""
-#define EXPAND_2D "2D"
+#define EXPAND_2D   "2D"
 #define EXPAND_RECT "RECT"
+#define EXPAND_NA   "NA"
 
-#define EXPAND_NO_IN_OP \
-  "MUL result.color, color, fragment.color.a;"
+#define EXPAND_X_IN_SOLID_OP \
+  { "", "", "MUL result.color, color, fragment.color.a;" }
 
+#define EXPAND_SOLID_IN_X_OP \
+  { "", "", "MUL result.color, fragment.color, color.a;" }
+      
 #define EXPAND_SRC_DECL "TEMP src;"
 #define EXPAND_SRC_2D_IN_OP \
-  "TXP src, fragment.texcoord[1], texture[1], 2D;" \
-  "DP4 color.a, color, fragment.color;" \
-  "MUL result.color, src, color.a;"
+  { "TXP src, fragment.texcoord[1], texture[1], 2D;", \
+    "DP4 color.a, color, fragment.color;", \
+    "MUL result.color, src, color.a;" }
+      
 #define EXPAND_SRC_RECT_IN_OP \
-  "TXP src, fragment.texcoord[1], texture[1], RECT;" \
-  "DP4 color.a, color, fragment.color;" \
-  "MUL result.color, src, color.a;"
+  { "TXP src, fragment.texcoord[1], texture[1], RECT;", \
+    "DP4 color.a, color, fragment.color;", \
+    "MUL result.color, src, color.a;" }
 
 #define EXPAND_MASK_DECL "TEMP mask;"
 #define EXPAND_MASK_2D_IN_OP \
-  "TXP mask, fragment.texcoord[0], texture[0], 2D;" \
-  "DP4 mask.a, mask, fragment.color;" \
-  "MUL result.color, color, mask.a;"
+  { "TXP mask, fragment.texcoord[0], texture[0], 2D;", \
+    "DP4 mask.a, mask, fragment.color;", \
+    "MUL result.color, color, mask.a;" }
 
 #define EXPAND_MASK_RECT_IN_OP \
-  "TXP mask, fragment.texcoord[0], texture[0], RECT;" \
-  "DP4 mask.a, mask, fragment.color;" \
-  "MUL result.color, color, mask.a;"
+  { "TXP mask, fragment.texcoord[0], texture[0], RECT;", \
+    "DP4 mask.a, mask, fragment.color;", \
+    "MUL result.color, color, mask.a;" }
+
+#define EXPAND_IN_NA \
+  { "NA", "NA", "NA" }
 
 typedef struct _glitz_program_expand_t glitz_program_expand_t;
 
+typedef struct _glitz_inop {
+    char *fetch;
+    char *dot_product;
+    char *mult;
+} glitz_in_op_t;
+
 static const struct _glitz_program_expand_t {
-  char *texture;
-  char *declarations;
-  char *in;
-} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST] = {
+  char          *texture;
+  char          *declarations;
+  glitz_in_op_t in;
+} _program_expand_map[GLITZ_TEXTURE_LAST][GLITZ_TEXTURE_LAST][2] = {
   {
     /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_NONE] */
-    { EXPAND_NONE, EXPAND_NONE, EXPAND_NO_IN_OP },
+    {
+      { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA },
+      { EXPAND_NA, EXPAND_NA, EXPAND_IN_NA }
+    },
     
     /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_2D] */
-    { EXPAND_NONE, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
+    {
+      { EXPAND_NA,   EXPAND_NA,   EXPAND_IN_NA         },
+      { EXPAND_2D,   EXPAND_NONE, EXPAND_SOLID_IN_X_OP }
+    },
     
     /* [GLITZ_TEXTURE_NONE][GLITZ_TEXTURE_RECT] */
-    { EXPAND_NONE, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }
+    {
+      { EXPAND_NA,   EXPAND_NA,   EXPAND_IN_NA         },
+      { EXPAND_RECT, EXPAND_NONE, EXPAND_SOLID_IN_X_OP }
+    }
   }, {
     
     /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_NONE] */
-    { EXPAND_2D, EXPAND_NONE, EXPAND_NO_IN_OP },
+    {
+      { EXPAND_2D, EXPAND_NONE, EXPAND_X_IN_SOLID_OP },
+      { EXPAND_NA, EXPAND_NA,   EXPAND_IN_NA         }
+    },
     
     /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_2D] */
-    { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
+    {
+      { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
+      { EXPAND_2D, EXPAND_SRC_DECL,  EXPAND_SRC_2D_IN_OP  }
+    },
     
     /* [GLITZ_TEXTURE_2D][GLITZ_TEXTURE_RECT] */
-    { EXPAND_2D, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }
+    {
+      { EXPAND_2D,   EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP },
+      { EXPAND_RECT, EXPAND_SRC_DECL,  EXPAND_SRC_2D_IN_OP    }
+    }
   }, {
-    
+      
     /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_NONE] */
-    { EXPAND_RECT, EXPAND_NONE, EXPAND_NO_IN_OP },
+    {
+      { EXPAND_RECT, EXPAND_NONE, EXPAND_X_IN_SOLID_OP },
+      { EXPAND_NA,   EXPAND_NA,   EXPAND_IN_NA         }
+    },
     
     /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_2D] */
-    { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
+    {
+      { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_2D_IN_OP },
+      { EXPAND_2D,   EXPAND_SRC_DECL,  EXPAND_SRC_2D_IN_OP  }
+    },
     
     /* [GLITZ_TEXTURE_RECT][GLITZ_TEXTURE_RECT] */
-    { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP }
+    {
+      { EXPAND_RECT, EXPAND_MASK_DECL, EXPAND_MASK_RECT_IN_OP },
+      { EXPAND_RECT, EXPAND_SRC_DECL,  EXPAND_SRC_RECT_IN_OP  }
+    }   
   }
 };
 
@@ -106,7 +147,7 @@
   "ATTRIB pos = fragment.texcoord[%s];",
   "TEMP color, in, coord, position;",
 
-  /* extra declerations */
+  /* extra declarations */
   "%s"
   
   /* perspective divide */
@@ -139,7 +180,7 @@
   "ATTRIB pos = fragment.texcoord[%s];",
   "TEMP color, second_color, stop0, stop1, position;",
 
-  /* extra declerations */
+  /* extra declarations */
   "%s",
 
   /* perspective divide */
@@ -352,23 +393,36 @@
                                 const glitz_program_expand_t *expand)
 {
   char buffer[1024], *program = NULL, *tex, *p = NULL;
+  char *texture_type, *extra_declarations;
+  const glitz_in_op_t *in;
   glitz_gl_uint_t fp;
   int i;
-  
+
   switch (op->type) {
   case GLITZ_COMBINE_TYPE_ARGBF:
   case GLITZ_COMBINE_TYPE_ARGBF_SOLID:
   case GLITZ_COMBINE_TYPE_ARGBF_SOLIDC:
+    i = 0;
+    tex = "0";
+    break;
+  case GLITZ_COMBINE_TYPE_ARGB_ARGBF:
+  case GLITZ_COMBINE_TYPE_SOLID_ARGBF:
+    i = 1;
     tex = "0";
     break;
   case GLITZ_COMBINE_TYPE_ARGBF_ARGB:
   case GLITZ_COMBINE_TYPE_ARGBF_ARGBC:
+    i = 0;
     tex = "1";
     break;
   default:
     return 0;
   }
 
+  texture_type       = expand[i].texture;
+  extra_declarations = expand[i].declarations;
+  in                 = &expand[i].in;
+
   switch (fp_type) {
   case GLITZ_FP_CONVOLUTION:
     program = malloc (CONVOLUTION_BASE_SIZE + CONVOLUTION_SAMPLE_SIZE * id);
@@ -380,14 +434,14 @@
     p += sprintf (p, "!!ARBfp1.0");
     
     _string_array_to_char_array (buffer, _convolution_header);
-    p += sprintf (p, buffer, id, id - 1, tex, expand->declarations);
+    p += sprintf (p, buffer, id, id - 1, tex, extra_declarations);
     
     _string_array_to_char_array (buffer, _convolution_sample_first);
-    p += sprintf (p, buffer, tex, expand->texture);
+    p += sprintf (p, buffer, tex, texture_type);
     
     _string_array_to_char_array (buffer, _convolution_sample);
     for (i = 1; i < id; i++)
-      p += sprintf (p, buffer, i, i, tex, expand->texture, i);
+      p += sprintf (p, buffer, i, i, tex, texture_type, i);
     
     break;
   case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
@@ -409,7 +463,7 @@
     p += sprintf (p, "!!ARBfp1.0");
     
     _string_array_to_char_array (buffer, _gradient_header);
-    p += sprintf (p, buffer, id, id, tex, expand->declarations);
+    p += sprintf (p, buffer, id, id, tex, extra_declarations);
     
     switch (fp_type) {
     case GLITZ_FP_LINEAR_GRADIENT_TRANSPARENT:
@@ -452,7 +506,7 @@
       p += sprintf (p, buffer, id - i - 1, id - i - 1);
     
     _string_array_to_char_array (buffer, _gradient_fetch_and_interpolate);
-    p += sprintf (p, buffer, tex, expand->texture, tex, expand->texture);
+    p += sprintf (p, buffer, tex, texture_type, tex, texture_type);
     
     id++;
     break;
@@ -463,7 +517,10 @@
   if (program == NULL)
     return 0;
   
-  p += sprintf (p, "%s", expand->in);
+  p += sprintf (p, "%s", in->fetch);
+  if (op->per_component)
+      p += sprintf (p, "%s", in->dot_product);
+  p += sprintf (p, "%s", in->mult);
   sprintf (p, "END");
 
   fp = _glitz_compile_arb_fragment_program (op->gl, program, id);
@@ -549,7 +606,7 @@
     
     program->name[id - 1] =
       _glitz_create_fragment_program (op, fp_type, id,
-                                      &_program_expand_map[t0][t1]);
+                                      _program_expand_map[t0][t1]);
     
     glitz_surface_pop_current (op->dst);
   }

Index: glitz_rect.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_rect.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- glitz_rect.c	12 Nov 2004 13:19:13 -0000	1.15
+++ glitz_rect.c	25 Jan 2005 19:50:26 -0000	1.16
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -35,26 +35,39 @@
           ((1L << (size)) - 1L)) : \
          dst)
 
-static void
-glitz_rectangle_bounds (const glitz_rectangle_t *rects,
-                        int                     n_rects,
-                        glitz_box_t             *box)
+static glitz_buffer_t *
+_glitz_minimum_buffer (glitz_surface_t         *surface,
+                       const glitz_rectangle_t *rects,
+                       int                     n_rects,
+                       unsigned int            pixel)
 {
-  box->x1 = MAXSHORT;
-  box->x2 = MINSHORT;
-  box->y1 = MAXSHORT;
-  box->y2 = MINSHORT;
+    glitz_buffer_t *buffer;
+    int            i, size = 0;
+    unsigned int   *data;
   
-  for (; n_rects; n_rects--, rects++) {
-    if (rects->x < box->x1)
-      box->x1 = rects->x;
-    if ((rects->x + rects->width) > box->x2)
-      box->x2 = rects->x + rects->width;
-    if (rects->y < box->y1)
-      box->y1 = rects->y;
-    if ((rects->y + rects->height) > box->y2)
-      box->y2 = rects->y + rects->height;
-  }
+    while (n_rects--)
+    {
+        i = rects->width * rects->height;
+        if (i > size)
+            size = i;
+        
+        rects++;
+    }
+    
+    buffer = glitz_pixel_buffer_create (surface->drawable, NULL,
+                                        size * sizeof (unsigned int),
+                                        GLITZ_BUFFER_HINT_STATIC_DRAW);
+    if (!buffer)
+        return NULL;
+    
+    data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
+    
+    while (size--)
+        *data++ = pixel;
+
+    glitz_buffer_unmap (buffer);
+    
+    return buffer;
 }
 
 void
@@ -63,99 +76,171 @@
                       const glitz_rectangle_t *rects,
                       int                     n_rects)
 {
-  glitz_box_t bounds;
+    GLITZ_GL_SURFACE (dst);
 
-  GLITZ_GL_SURFACE (dst);
+    if (n_rects < 1)
+        return;
 
-  glitz_rectangle_bounds (rects, n_rects, &bounds);
-  if (bounds.x1 > dst->width || bounds.y1 > dst->height ||
-      bounds.x2 < 0 || bounds.y2 < 0)
-    return;
+    if (SURFACE_SOLID (dst))
+    {
+        glitz_color_t old = dst->solid;
+        glitz_box_t   *clip  = dst->clip;
+        int           n_clip = dst->n_clip;
 
-  if (SURFACE_SOLID (dst) &&
-      (bounds.x2 - bounds.x1) > 0 && (bounds.y2 - bounds.y1) > 0) {
-    STORE_16 (dst->solid.red, dst->format->color.red_size, color->red);
-    STORE_16 (dst->solid.green, dst->format->color.green_size, color->green);
-    STORE_16 (dst->solid.blue, dst->format->color.blue_size, color->blue);
-    STORE_16 (dst->solid.alpha, dst->format->color.alpha_size, color->alpha);
+        for (; n_clip; clip++, n_clip--)
+        {
+            if (clip->x1 > 0 ||
+                clip->y1 > 0 ||
+                clip->x2 < 1 ||
+                clip->y2 < 1)
+                continue;
+            
+            for (; n_rects; rects++, n_rects--)
+            {
+                if (rects->x > 0 ||
+                    rects->y > 0 ||
+                    (rects->x + rects->width) < 1 ||
+                    (rects->y + rects->height) < 1)
+                    continue;
+            
+                STORE_16 (dst->solid.red,
+                          dst->format->color.red_size,
+                          color->red);
+                STORE_16 (dst->solid.green,
+                          dst->format->color.green_size,
+                          color->green);
+                STORE_16 (dst->solid.blue,
+                          dst->format->color.blue_size,
+                          color->blue);
+                STORE_16 (dst->solid.alpha,
+                          dst->format->color.alpha_size,
+                          color->alpha);
+    
+                if (dst->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
+                {
+                    dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
+                    glitz_surface_damage (dst, &dst->box,
+                                          GLITZ_DAMAGE_TEXTURE_MASK |
+                                          GLITZ_DAMAGE_DRAWABLE_MASK);
+                }
+                else
+                {
+                    if (dst->solid.red   != old.red   ||
+                        dst->solid.green != old.green ||
+                        dst->solid.blue  != old.blue  ||
+                        dst->solid.alpha != old.alpha)
+                        glitz_surface_damage (dst, &dst->box,
+                                              GLITZ_DAMAGE_TEXTURE_MASK |
+                                              GLITZ_DAMAGE_DRAWABLE_MASK);
+                }
+                break;
+            }
+            break;
+        }
+    }
+    else
+    {
+        static glitz_pixel_format_t pf = {
+            {
+                32,
+                0xff000000,
+                0x00ff0000,
+                0x0000ff00,
+                0x000000ff
+            },
+            0, 0, 0,
+            GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
+        };
+        glitz_buffer_t *buffer = NULL;
+        glitz_box_t    box;
+        glitz_bool_t   drawable;
+        
+        drawable = glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT);
+        if (drawable)
+        {
+            gl->clear_color (color->red   / (glitz_gl_clampf_t) 0xffff,
+                             color->green / (glitz_gl_clampf_t) 0xffff,
+                             color->blue  / (glitz_gl_clampf_t) 0xffff,
+                             color->alpha / (glitz_gl_clampf_t) 0xffff);
+        }
+        else
+        {
+            unsigned int pixel =
+                ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) |
+                ((((unsigned int) color->red   * 0xff) / 0xffff) << 16) |
+                ((((unsigned int) color->green * 0xff) / 0xffff) << 8) |
+                ((((unsigned int) color->blue  * 0xff) / 0xffff));
 
-    dst->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
-    glitz_surface_damage (dst, &bounds,
-                          GLITZ_DAMAGE_TEXTURE_MASK |
-                          GLITZ_DAMAGE_DRAWABLE_MASK);
-    return;
-  }
+            buffer = _glitz_minimum_buffer (dst, rects, n_rects, pixel);
+            if (!buffer)
+            {
+                glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
+                return;
+            }
+        }
+      
+        while (n_rects--)
+        {
+            glitz_box_t *clip  = dst->clip;
+            int         n_clip = dst->n_clip;
 
-  if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) {
-    gl->clear_color (color->red / (glitz_gl_clampf_t) 0xffff,
-                     color->green / (glitz_gl_clampf_t) 0xffff,
-                     color->blue / (glitz_gl_clampf_t) 0xffff,
-                     color->alpha / (glitz_gl_clampf_t) 0xffff);
+            while (n_clip--)
+            {
+                box.x1 = clip->x1 + dst->x_clip;
+                box.y1 = clip->y1 + dst->y_clip;
+                box.x2 = clip->x2 + dst->x_clip;
+                box.y2 = clip->y2 + dst->y_clip;
 
-    for (; n_rects; n_rects--, rects++) {
-      gl->scissor (rects->x,
-                   dst->attached->height - dst->y - rects->y - rects->height,
-                   rects->width,
-                   rects->height);
-      gl->clear (GLITZ_GL_COLOR_BUFFER_BIT);
-    }
-    glitz_surface_damage (dst, &bounds,
-                          GLITZ_DAMAGE_TEXTURE_MASK |
-                          GLITZ_DAMAGE_SOLID_MASK);
-  } else {
-    static glitz_pixel_format_t pf = {
-      {
-        32,
-        0xff000000,
-        0x00ff0000,
-        0x0000ff00,
-        0x000000ff
-      },
-      0, 0, 0,
-      GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
-    };
-    glitz_buffer_t *buffer;
-    unsigned int i, width, height, pixel, *data;
+                if (dst->box.x1 > box.x1)
+                    box.x1 = dst->box.x1;
+                if (dst->box.y1 > box.y1)
+                    box.y1 = dst->box.y1;
+                if (dst->box.x2 < box.x2)
+                    box.x2 = dst->box.x2;
+                if (dst->box.y2 < box.y2)
+                    box.y2 = dst->box.y2;
+                
+                if (rects->x > box.x1)
+                    box.x1 = rects->x;
+                if (rects->y > box.y1)
+                    box.y1 = rects->y;
+                if (rects->x + rects->width < box.x2)
+                    box.x2 = rects->x + rects->width;
+                if (rects->y + rects->height < box.y2)
+                    box.y2 = rects->y + rects->height;
 
-    width = bounds.x2 - bounds.x1;
-    height = bounds.y2 - bounds.y1;
+                if (box.x1 < box.x2 && box.y1 < box.y2)
+                {
+                    if (drawable)
+                    {
+                        gl->scissor (box.x1,
+                                     dst->attached->height - dst->y - box.y2,
+                                     box.x2 - box.x1,
+                                     box.y2 - box.y1);
+                        gl->clear (GLITZ_GL_COLOR_BUFFER_BIT);
+                        
+                        glitz_surface_damage (dst, &box,
+                                              GLITZ_DAMAGE_TEXTURE_MASK |
+                                              GLITZ_DAMAGE_SOLID_MASK);
+                    }
+                    else
+                    {
+                        glitz_set_pixels (dst,
+                                          box.x1, box.y1,
+                                          box.x2 - box.x1, box.y2 - box.y1,
+                                          &pf, buffer);
+                    }
+                }
+                clip++;
+            }
+            rects++;
+        }
+        
+        if (buffer)
+            glitz_buffer_destroy (buffer);
 
-    data = malloc (width * height * 4);
-    if (data == NULL) {
-      glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
-      return;
+        glitz_surface_pop_current (dst);
     }
-    
-    buffer = glitz_buffer_create_for_data (data);
-    if (buffer == NULL) {
-      free (data);
-      glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
-      return;
-    }        
-    
-    pixel =
-      ((((unsigned int) color->alpha * 0xff) / 0xffff) << 24) |
-      ((((unsigned int) color->red * 0xff) / 0xffff) << 16) |
-      ((((unsigned int) color->green * 0xff) / 0xffff) << 8) |
-      ((((unsigned int) color->blue * 0xff) / 0xffff));
-    
-    for (i = 0; i < width; i++)
-      data[i] = pixel;
-    
-    for (i = 1; i < height; i++)
-      memcpy (&data[i * width], data, width * sizeof (unsigned int));
-
-    for (; n_rects; n_rects--, rects++)
-      glitz_set_pixels (dst,
-                        rects->x, rects->y,
-                        rects->width, rects->height,
-                        &pf, buffer);
-
-    glitz_buffer_destroy (buffer);
-    free (data);
-  }
-  
-  glitz_surface_pop_current (dst);
 }
 slim_hidden_def(glitz_set_rectangles);
 
@@ -167,13 +252,13 @@
                      unsigned int        width,
                      unsigned int        height)
 {
-  glitz_rectangle_t rect;
+    glitz_rectangle_t rect;
 
-  rect.x = x;
-  rect.y = y;
-  rect.width = width;
-  rect.height = height;
+    rect.x = x;
+    rect.y = y;
+    rect.width = width;
+    rect.height = height;
 
-  glitz_set_rectangles (dst, color, &rect, 1);
+    glitz_set_rectangles (dst, color, &rect, 1);
 }
 slim_hidden_def(glitz_set_rectangle);

Index: glitz_region.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_region.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- glitz_region.c	3 Nov 2004 22:50:58 -0000	1.1
+++ glitz_region.c	25 Jan 2005 19:50:26 -0000	1.2
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H

Index: glitz_status.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_status.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- glitz_status.c	3 Sep 2004 14:27:58 -0000	1.3
+++ glitz_status.c	25 Jan 2005 19:50:26 -0000	1.4
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
+ * Copyright © 2004 David Reveman, Peter Nilsson
  *
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
@@ -21,7 +21,7 @@
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
+ * Authors: David Reveman <davidr at novell.com>
  *          Peter Nilsson <c99pnn at cs.umu.se>
  */
 

Index: glitz_surface.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_surface.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- glitz_surface.c	3 Nov 2004 22:50:58 -0000	1.24
+++ glitz_surface.c	25 Jan 2005 19:50:26 -0000	1.25
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -33,55 +33,81 @@
 #include <string.h>
 
 glitz_surface_t *
-glitz_surface_create (glitz_drawable_t *drawable,
-                      glitz_format_t   *format,
-                      unsigned int     width,
-                      unsigned int     height)
+glitz_surface_create (glitz_drawable_t           *drawable,
+                      glitz_format_t             *format,
+                      unsigned int               width,
+                      unsigned int               height,
+                      unsigned long              mask,
+                      glitz_surface_attributes_t *attributes)
 {
-  glitz_surface_t *surface;
-  
-  if (width == 0 || height == 0)
-    return NULL;
+    glitz_surface_t *surface;
+    glitz_bool_t    unnormalized = 0;
+    unsigned long   feature_mask = drawable->backend->feature_mask;
 
-  surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t));
-  if (surface == NULL)
-    return NULL;
+    if (!width || !height)
+        return NULL;
 
-  surface->drawable = drawable;
-  glitz_drawable_reference (drawable);
-  
-  surface->ref_count = 1;
-  surface->filter = GLITZ_FILTER_NEAREST;  
-  surface->format = format;
-  surface->width = (int) width;
-  surface->height = (int) height;
-  surface->buffer = GLITZ_GL_FRONT;
+    if (mask & GLITZ_SURFACE_UNNORMALIZED_MASK)
+    {
+        if (attributes->unnormalized)
+        {
+            if (!(feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK))
+                return NULL;
 
-  REGION_INIT (&surface->texture_damage, NULL_BOX);
-  REGION_INIT (&surface->drawable_damage, NULL_BOX);
+            unnormalized = 1;
+        }
+    }
 
-  if (width == 1 && height == 1) {
-    surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK;
-    surface->solid.alpha = 0xffff;
-  }
+    surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t));
+    if (surface == NULL)
+        return NULL;
+
+    surface->drawable = drawable;
+    glitz_drawable_reference (drawable);
   
-  glitz_texture_init (&surface->texture, width, height,
-                      drawable->backend->texture_formats[format->id],
-                      drawable->backend->feature_mask);
+    surface->ref_count = 1;
+    surface->filter    = GLITZ_FILTER_NEAREST;  
+    surface->format    = format;
+    surface->box.x2    = (short) width;
+    surface->box.y2    = (short) height;
+    surface->clip      = &surface->box;
+    surface->n_clip    = 1;
+    surface->buffer    = GLITZ_GL_FRONT;
+
+    if (width == 1 && height == 1)
+    {
+        surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK;
+        surface->solid.alpha = 0xffff;
+        
+        REGION_INIT (&surface->texture_damage, &surface->box);
+        REGION_INIT (&surface->drawable_damage, &surface->box);
+    }
+    else
+    {
+        REGION_INIT (&surface->texture_damage, NULL_BOX);
+        REGION_INIT (&surface->drawable_damage, NULL_BOX);
+    }
   
-  if (width > 64 || height > 64) {
-    glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT);
-    glitz_texture_size_check (&drawable->backend->gl, &surface->texture,
-                              drawable->backend->max_texture_2d_size,
-                              drawable->backend->max_texture_rect_size);
-    glitz_surface_pop_current (surface);
-    if (TEXTURE_INVALID_SIZE (&surface->texture)) {
-      glitz_surface_destroy (surface);
-      return NULL;
+    glitz_texture_init (&surface->texture, width, height,
+                        drawable->backend->texture_formats[format->id],
+                        feature_mask, unnormalized);
+  
+    if (width > 64 || height > 64)
+    {
+        glitz_surface_push_current (surface, GLITZ_CONTEXT_CURRENT);
+        glitz_texture_size_check (&drawable->backend->gl, &surface->texture,
+                                  drawable->backend->max_texture_2d_size,
+                                  drawable->backend->max_texture_rect_size);
+        glitz_surface_pop_current (surface);
+      
+        if (TEXTURE_INVALID_SIZE (&surface->texture))
+        {
+            glitz_surface_destroy (surface);
+            return NULL;
+        }
     }
-  }
   
-  return surface;
+    return surface;
 }
 
 void
@@ -106,11 +132,14 @@
   if (surface->geometry.buffer)
     glitz_buffer_destroy (surface->geometry.buffer);
   
+  if (surface->geometry.array)
+    glitz_multi_array_destroy (surface->geometry.array);
+  
   if (surface->transform)
     free (surface->transform);
   
   if (surface->filter_params)
-    glitz_filter_params_destroy (surface->filter_params);
+    free (surface->filter_params);
 
   if (surface->attached)
     glitz_drawable_destroy (surface->attached);
@@ -132,195 +161,217 @@
 static void
 _glitz_surface_sync_texture (glitz_surface_t *surface)
 {
-  if (REGION_NOTEMPTY (&surface->texture_damage)) {
-    glitz_box_t *box;
-    int         n_box;
-
-    GLITZ_GL_SURFACE (surface);
-
-    if (!(TEXTURE_ALLOCATED (&surface->texture)))
-      glitz_texture_allocate (gl, &surface->texture);
+    if (REGION_NOTEMPTY (&surface->texture_damage))
+    {
+        glitz_box_t *box;
+        int         n_box;
+        
+        GLITZ_GL_SURFACE (surface);
+        
+        if (!(TEXTURE_ALLOCATED (&surface->texture)))
+            glitz_texture_allocate (gl, &surface->texture);
 
-    if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface))) {
-      glitz_gl_float_t color[4];
+        if (SURFACE_SOLID (surface) && (!SURFACE_SOLID_DAMAGE (surface)))
+        {
+            glitz_gl_float_t color[4];
+            
+            if (TEXTURE_ALLOCATED (&surface->texture))
+            {
+                color[0] = surface->solid.red / 65535.0f;
+                color[1] = surface->solid.green / 65535.0f;
+                color[2] = surface->solid.blue / 65535.0f;
+                color[3] = surface->solid.alpha / 65535.0f;
+                
+                glitz_texture_bind (gl, &surface->texture);
+                gl->tex_sub_image_2d (surface->texture.target, 0,
+                                      surface->texture.box.x1,
+                                      surface->texture.box.y1,
+                                      1, 1, GLITZ_GL_RGBA,
+                                      GLITZ_GL_FLOAT, color);
+                glitz_texture_unbind (gl, &surface->texture);
+            }
+            REGION_EMPTY (&surface->texture_damage);
+            return;
+        }
 
-      if (TEXTURE_ALLOCATED (&surface->texture)) {
-        color[0] = surface->solid.red / 65535.0f;
-        color[1] = surface->solid.green / 65535.0f;
-        color[2] = surface->solid.blue / 65535.0f;
-        color[3] = surface->solid.alpha / 65535.0f;
-    
+        glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
+        
+        gl->read_buffer (surface->buffer);
+        
+        gl->disable (GLITZ_GL_SCISSOR_TEST);
+        
         glitz_texture_bind (gl, &surface->texture);
-        gl->tex_sub_image_2d (surface->texture.target, 0,
-                              surface->texture.box.x1, surface->texture.box.y1,
-                              1, 1, GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color);
-        glitz_texture_unbind (gl, &surface->texture);
-      }
-      REGION_EMPTY (&surface->texture_damage);
-      return;
-    }
-
-    glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
-
-    gl->read_buffer (surface->buffer);
-
-    gl->disable (GLITZ_GL_SCISSOR_TEST);
-
-    glitz_texture_bind (gl, &surface->texture);
+        
+        box = REGION_RECTS (&surface->texture_damage);
+        n_box = REGION_NUM_RECTS (&surface->texture_damage);
+        
+        while (n_box--)
+        {
+            glitz_texture_copy_drawable (gl,
+                                         &surface->texture,
+                                         surface->attached,
+                                         box->x1 + surface->x,
+                                         box->y1 + surface->y,
+                                         box->x2 - box->x1,
+                                         box->y2 - box->y1,
+                                         box->x1,
+                                         box->y1);
+            
+            box++;
+        }
 
-    box = REGION_RECTS (&surface->texture_damage);
-    n_box = REGION_NUM_RECTS (&surface->texture_damage);
-  
-    while (n_box--) {
-      glitz_texture_copy_drawable (gl,
-                                   &surface->texture,
-                                   surface->attached,
-                                   box->x1 + surface->x,
-                                   box->y1 + surface->y,
-                                   box->x2 - box->x1,
-                                   box->y2 - box->y1,
-                                   box->x1,
-                                   box->y1);
-      
-      box++;
+        REGION_EMPTY (&surface->texture_damage);
+        
+        glitz_texture_unbind (gl, &surface->texture);
+        
+        gl->enable (GLITZ_GL_SCISSOR_TEST);
+        
+        glitz_surface_pop_current (surface);
     }
-
-    REGION_EMPTY (&surface->texture_damage);
-
-    glitz_texture_unbind (gl, &surface->texture);
-
-    gl->enable (GLITZ_GL_SCISSOR_TEST);
-
-    glitz_surface_pop_current (surface);
-  }
 }
 
 static void
 _glitz_surface_sync_drawable (glitz_surface_t *surface)
 {   
-  if (REGION_NOTEMPTY (&surface->drawable_damage)) {
-    glitz_texture_t *texture;
-    glitz_box_t     *box, *ext;
-    int             n_box;
-  
-    GLITZ_GL_SURFACE (surface);
-
-    texture = glitz_surface_get_texture (surface, 0);
-    if (!texture)
-      return;
-    
-    box = REGION_RECTS (&surface->drawable_damage);
-    ext = REGION_EXTENTS (&surface->drawable_damage);
-    n_box = REGION_NUM_RECTS (&surface->drawable_damage);
-
-    glitz_texture_bind (gl, texture);
+    if (REGION_NOTEMPTY (&surface->drawable_damage))
+    {
+        glitz_texture_t *texture;
+        glitz_box_t     *box, *ext;
+        int             n_box;
+        
+        GLITZ_GL_SURFACE (surface);
+        
+        texture = glitz_surface_get_texture (surface, 0);
+        if (!texture)
+            return;
+        
+        box = REGION_RECTS (&surface->drawable_damage);
+        ext = REGION_EXTENTS (&surface->drawable_damage);
+        n_box = REGION_NUM_RECTS (&surface->drawable_damage);
+        
+        glitz_texture_bind (gl, texture);
   
-    glitz_texture_set_tex_gen (gl, texture, 0, 0, 0); 
+        glitz_texture_set_tex_gen (gl, texture, NULL,
+                                   0, 0,
+                                   GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK,
+                                   NULL); 
     
-    gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
-                   GLITZ_GL_REPLACE);
-    gl->color_4us (0x0, 0x0, 0x0, 0xffff);
+        gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+                       GLITZ_GL_REPLACE);
+        gl->color_4us (0x0, 0x0, 0x0, 0xffff);
     
-    glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE);
-    glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST);
+        glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE);
+        glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST);
     
-    glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
+        glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
     
-    gl->scissor (surface->x + ext->x1,
-                 surface->attached->height - surface->y - ext->y2,
-                 ext->x2 - ext->x1,
-                 ext->y2 - ext->y1);
+        gl->scissor (surface->x + ext->x1,
+                     surface->attached->height - surface->y - ext->y2,
+                     ext->x2 - ext->x1,
+                     ext->y2 - ext->y1);
 
-    if (n_box > 1) {
-      glitz_float_t *data;
-      void          *ptr;
-      int           vertices;
-      
-      ptr = malloc (n_box * 8 * sizeof (glitz_float_t));
-      if (!ptr) {
-        glitz_surface_status_add (surface, GLITZ_STATUS_NO_MEMORY_MASK);
-        return;
-      }
+        if (n_box > 1)
+        {
+            glitz_float_t *data;
+            void          *ptr;
+            int           vertices;
+            
+            ptr = malloc (n_box * 8 * sizeof (glitz_float_t));
+            if (!ptr) {
+                glitz_surface_status_add (surface,
+                                          GLITZ_STATUS_NO_MEMORY_MASK);
+                return;
+            }
+            
+            data = (glitz_float_t *) ptr;
+            vertices = n_box << 2;
+            
+            while (n_box--)
+            {
+                *data++ = (glitz_float_t) box->x1;
+                *data++ = (glitz_float_t) box->y1;
+                *data++ = (glitz_float_t) box->x2;
+                *data++ = (glitz_float_t) box->y1;
+                *data++ = (glitz_float_t) box->x2;
+                *data++ = (glitz_float_t) box->y2;
+                *data++ = (glitz_float_t) box->x1;
+                *data++ = (glitz_float_t) box->y2;
+                
+                box++;
+            }
 
-      data = (glitz_float_t *) ptr;
-      vertices = n_box << 2;
+            gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr);
+            gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices);
+      
+            free (ptr);
+        }
+        else
+        {
+            glitz_geometry_enable_none (gl, surface, ext);
+            gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
+        }
 
-      while (n_box--) {
-        *data++ = (glitz_float_t) box->x1;
-        *data++ = (glitz_float_t) box->y1;
-        *data++ = (glitz_float_t) box->x2;
-        *data++ = (glitz_float_t) box->y1;
-        *data++ = (glitz_float_t) box->x2;
-        *data++ = (glitz_float_t) box->y2;
-        *data++ = (glitz_float_t) box->x1;
-        *data++ = (glitz_float_t) box->y2;
+        glitz_texture_unbind (gl, texture);
         
-        box++;
-      }
-
-      gl->vertex_pointer (2, GLITZ_GL_FLOAT, 0, ptr);
-      gl->draw_arrays (GLITZ_GL_QUADS, 0, vertices);
-      
-      free (ptr);
-    } else {
-      glitz_geometry_enable_default (gl, surface, ext);
-      gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
+        REGION_EMPTY (&surface->drawable_damage);
     }
-
-    glitz_texture_unbind (gl, texture);
-    
-    REGION_EMPTY (&surface->drawable_damage);
-  }
 }
 
 void
 glitz_surface_sync_solid (glitz_surface_t *surface)
 {
-  if (SURFACE_SOLID_DAMAGE (surface)) {
-    glitz_gl_float_t *c, color[64];
-    glitz_texture_t *texture;
-
-    GLITZ_GL_SURFACE (surface);
+    if (SURFACE_SOLID_DAMAGE (surface))
+    {
+        glitz_gl_float_t *c, color[64];
+        glitz_texture_t *texture;
+        
+        GLITZ_GL_SURFACE (surface);
+        
+        texture = glitz_surface_get_texture (surface, 0);
+        
+        c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4];
+        if (texture)
+        {
+            glitz_texture_bind (gl, texture);
+            gl->get_tex_image (texture->target, 0,
+                               GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color);
+            glitz_texture_unbind (gl, texture);
+        }
+        else
+        {
+            c[0] = c[1] = c[2] = 0.0f;
+            c[3] = 1.0f;
+        }
+        
+        surface->solid.red = c[0] * 65535.0f;
+        surface->solid.green = c[1] * 65535.0f;
+        surface->solid.blue = c[2] * 65535.0f;
+        surface->solid.alpha = c[3] * 65535.0f;
 
-    texture = glitz_surface_get_texture (surface, 0);
-    
-    c = &color[(texture->box.y1 * texture->width + texture->box.x1) * 4];
-    if (texture) {
-      glitz_texture_bind (gl, texture);
-      gl->get_tex_image (texture->target, 0,
-                         GLITZ_GL_RGBA, GLITZ_GL_FLOAT, color);
-      glitz_texture_unbind (gl, texture);
-    } else {
-      c[0] = c[1] = c[2] = 0.0f;
-      c[3] = 1.0f;
+        surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
     }
-    
-    surface->solid.red = c[0] * 65535.0f;
-    surface->solid.green = c[1] * 65535.0f;
-    surface->solid.blue = c[2] * 65535.0f;
-    surface->solid.alpha = c[3] * 65535.0f;
-
-    surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
-  }
 }
 
 glitz_texture_t *
 glitz_surface_get_texture (glitz_surface_t *surface,
                            glitz_bool_t    allocate)
 {
-  GLITZ_GL_SURFACE (surface);
+    GLITZ_GL_SURFACE (surface);
 
-  if (REGION_NOTEMPTY (&surface->texture_damage)) {
-    _glitz_surface_sync_texture (surface);
-  } else if (allocate) {
-    if (!(TEXTURE_ALLOCATED (&surface->texture)))
-      glitz_texture_allocate (gl, &surface->texture);
-  }
-  
-  if (TEXTURE_ALLOCATED (&surface->texture))
-    return &surface->texture;
+    if (REGION_NOTEMPTY (&surface->texture_damage))
+    {
+        _glitz_surface_sync_texture (surface);
+    }
+    else if (allocate)
+    {
+        if (!(TEXTURE_ALLOCATED (&surface->texture)))
+            glitz_texture_allocate (gl, &surface->texture);
+    }
+    
+    if (TEXTURE_ALLOCATED (&surface->texture))
+        return &surface->texture;
   
-  return NULL;
+    return NULL;
 }
 
 void
@@ -328,107 +379,93 @@
                       glitz_box_t     *box,
                       int             what)
 {
-  glitz_box_t b;
-
-  if (box) {
-    b.x1 = MAX (0, box->x1);
-    b.y1 = MAX (0, box->y1);
-    b.x2 = MIN (surface->width, box->x2);
-    b.y2 = MIN (surface->height, box->y2);
-
-    if (b.x1 >= b.x2 || b.y1 >= b.y2)
-      return;
-    
-    if (what & GLITZ_DAMAGE_DRAWABLE_MASK)
-      REGION_UNION (&surface->drawable_damage, &b);
-
-    if (what & GLITZ_DAMAGE_TEXTURE_MASK)
-      REGION_UNION (&surface->texture_damage, &b);
-  } else {
-    b.x1 = b.y1 = 0;
-    b.x2 = surface->width;
-    b.y2 = surface->height;
+    if (box)
+    {
+        if (what & GLITZ_DAMAGE_DRAWABLE_MASK)
+            REGION_UNION (&surface->drawable_damage, box);
 
-    if (what & GLITZ_DAMAGE_DRAWABLE_MASK) {
-      REGION_EMPTY (&surface->drawable_damage);
-      REGION_INIT (&surface->drawable_damage, &b);
+        if (what & GLITZ_DAMAGE_TEXTURE_MASK)
+            REGION_UNION (&surface->texture_damage, box);
     }
-
-    if (what & GLITZ_DAMAGE_TEXTURE_MASK) {
-      REGION_EMPTY (&surface->texture_damage);
-      REGION_INIT (&surface->texture_damage, &b);
+    else
+    {
+        if (what & GLITZ_DAMAGE_DRAWABLE_MASK)
+        {
+            REGION_EMPTY (&surface->drawable_damage);
+            REGION_INIT (&surface->drawable_damage, &surface->box);
+        }
+        
+        if (what & GLITZ_DAMAGE_TEXTURE_MASK)
+        {
+            REGION_EMPTY (&surface->texture_damage);
+            REGION_INIT (&surface->texture_damage, &surface->box);
+        }
     }
-  }
-
-  if (what & GLITZ_DAMAGE_SOLID_MASK)
-    surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
+    
+    if (what & GLITZ_DAMAGE_SOLID_MASK)
+        surface->flags |= GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
 }
 
 void
-glitz_surface_status_add (glitz_surface_t *surface, int flags)
+glitz_surface_status_add (glitz_surface_t *surface,
+                          int             flags)
 {
-  surface->status_mask |= flags;
+    surface->status_mask |= flags;
 }
 
 static void
 _glitz_surface_update_state (glitz_surface_t *surface)
 {
-  glitz_rectangle_t *viewport;
-  
-  GLITZ_GL_SURFACE (surface);
-
-  viewport = &surface->attached->viewport;
-  
-  if (surface->attached->update_all ||
-      viewport->x != surface->x ||
-      viewport->y != surface->y ||
-      viewport->width != surface->width ||
-      viewport->height != surface->height) {
-    gl->viewport (surface->x,
-                  surface->attached->height - surface->y - surface->height,
-                  surface->width,
-                  surface->height);
-    gl->matrix_mode (GLITZ_GL_PROJECTION);
-    gl->load_identity ();
-    gl->ortho (0.0,
-               surface->width,
-               surface->attached->height - surface->height,
-               surface->attached->height,
-               -1.0, 1.0);
-    gl->matrix_mode (GLITZ_GL_MODELVIEW);
-    gl->load_identity ();
-    gl->scale_f (1.0f, -1.0f, 1.0f);
-    gl->translate_f (0.0f, -surface->attached->height, 0.0f);
+    glitz_rectangle_t *viewport;
     
-    viewport->x = surface->x;
-    viewport->y = surface->y;
-    viewport->width = surface->width;
-    viewport->height = surface->height;
+    GLITZ_GL_SURFACE (surface);
     
-    surface->attached->update_all = 0;
-  }
-
-  gl->draw_buffer (surface->buffer);
+    viewport = &surface->attached->viewport;
+    
+    if (surface->attached->update_all ||
+        viewport->x != surface->x ||
+        viewport->y != surface->y ||
+        viewport->width != surface->box.x2 ||
+        viewport->height != surface->box.y2)
+    {
+        gl->viewport (surface->x,
+                      surface->attached->height - surface->y - surface->box.y2,
+                      surface->box.x2,
+                      surface->box.y2);
+        gl->matrix_mode (GLITZ_GL_PROJECTION);
+        gl->load_identity ();
+        gl->ortho (0.0,
+                   surface->box.x2,
+                   surface->attached->height - surface->box.y2,
+                   surface->attached->height,
+                   -1.0, 1.0);
+        gl->matrix_mode (GLITZ_GL_MODELVIEW);
+        gl->load_identity ();
+        gl->scale_f (1.0f, -1.0f, 1.0f);
+        gl->translate_f (0.0f, -surface->attached->height, 0.0f);
+    
+        viewport->x = surface->x;
+        viewport->y = surface->y;
+        viewport->width = surface->box.x2;
+        viewport->height = surface->box.y2;
+    
+        surface->attached->update_all = 0;
+    }
+    
+    gl->draw_buffer (surface->buffer);
 
-  if (SURFACE_DITHER (surface))
-    gl->enable (GLITZ_GL_DITHER);
-  else
-    gl->disable (GLITZ_GL_DITHER);
+    if (SURFACE_DITHER (surface))
+        gl->enable (GLITZ_GL_DITHER);
+    else
+        gl->disable (GLITZ_GL_DITHER);
 
-  if (surface->attached->format->samples > 1) {
-    if (SURFACE_MULTISAMPLE (surface)) {
-      gl->enable (GLITZ_GL_MULTISAMPLE);
-      
-      if (surface->attached->backend->feature_mask &
-          GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK) {
-        if (SURFACE_NICEST_MULTISAMPLE (surface))
-          gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST);
-        else
-          gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_FASTEST);
-      }
-    } else
-      gl->disable (GLITZ_GL_MULTISAMPLE);
-  }
+    if (surface->attached->format->samples > 1)
+    {
+        gl->enable (GLITZ_GL_MULTISAMPLE);
+        if (surface->attached->backend->feature_mask &
+            GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK)
+            gl->hint (GLITZ_GL_MULTISAMPLE_FILTER_HINT, GLITZ_GL_NICEST);
+    }
 }
 
 void
@@ -438,64 +475,59 @@
                       int                     x,
                       int                     y)
 {
-  glitz_drawable_reference (drawable);
+    glitz_drawable_reference (drawable);
 
-  if (surface->attached)
-    glitz_drawable_destroy (surface->attached);
+    if (surface->attached)
+        glitz_drawable_destroy (surface->attached);
   
-  surface->attached = drawable;
-  surface->x = x;
-  surface->y = y;
+    surface->attached = drawable;
+    surface->x = x;
+    surface->y = y;
 
-  switch (buffer) {
-  case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR:
-    surface->buffer = GLITZ_GL_FRONT;
-    break;
-  case GLITZ_DRAWABLE_BUFFER_BACK_COLOR:
-    surface->buffer = GLITZ_GL_BACK;
-    break;
-  }
+    switch (buffer) {
+    case GLITZ_DRAWABLE_BUFFER_FRONT_COLOR:
+        surface->buffer = GLITZ_GL_FRONT;
+        break;
+    case GLITZ_DRAWABLE_BUFFER_BACK_COLOR:
+        surface->buffer = GLITZ_GL_BACK;
+        break;
+    }
 
-  if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface))
-    REGION_EMPTY (&surface->texture_damage);
+    if ((!SURFACE_SOLID (surface)) || SURFACE_SOLID_DAMAGE (surface))
+        REGION_EMPTY (&surface->texture_damage);
 }
 
 void
 glitz_surface_detach (glitz_surface_t *surface)
 {
-  glitz_box_t box;
-
-  if (!surface->attached)
-    return;
+    if (!surface->attached)
+        return;
 
-  if (REGION_NOTEMPTY (&surface->texture_damage)) {
-    glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
-    _glitz_surface_sync_texture (surface);
-    glitz_surface_pop_current (surface);
-  }
+    if (REGION_NOTEMPTY (&surface->texture_damage))
+    {
+        glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
+        _glitz_surface_sync_texture (surface);
+        glitz_surface_pop_current (surface);
+    }
   
-  glitz_drawable_destroy (surface->attached); 
-  surface->attached = NULL;
-
-  box.x1 = box.y1 = 0;
-  box.x2 = surface->width;
-  box.y2 = surface->height;
+    glitz_drawable_destroy (surface->attached); 
+    surface->attached = NULL;
     
-  REGION_EMPTY (&surface->drawable_damage);
-  REGION_INIT (&surface->drawable_damage, &box);
+    REGION_EMPTY (&surface->drawable_damage);
+    REGION_INIT (&surface->drawable_damage, &surface->box);
 }
 
 glitz_drawable_t *
 glitz_surface_get_drawable (glitz_surface_t *surface)
 {
-  return surface->drawable;
+    return surface->drawable;
 }
 slim_hidden_def(glitz_surface_get_drawable);
 
 glitz_drawable_t *
 glitz_surface_get_attached_drawable (glitz_surface_t *surface)
 {
-  return surface->attached;
+    return surface->attached;
 }
 slim_hidden_def(glitz_surface_get_attached_drawable);
 
@@ -775,14 +807,14 @@
 unsigned int
 glitz_surface_get_width (glitz_surface_t *surface)
 {
-  return (unsigned int) surface->width;
+  return (unsigned int) surface->box.x2;
 }
 slim_hidden_def(glitz_surface_get_width);
 
 unsigned int
 glitz_surface_get_height (glitz_surface_t *surface)
 {
-  return (unsigned int) surface->height;
+  return (unsigned int) surface->box.y2;
 }
 slim_hidden_def(glitz_surface_get_height);
 
@@ -799,3 +831,47 @@
   return surface->format;
 }
 slim_hidden_def(glitz_surface_get_format);
+
+void
+glitz_surface_translate_point (glitz_surface_t     *surface,
+                               glitz_point_fixed_t *src,
+                               glitz_point_fixed_t *dst)
+{
+
+    if (surface->texture.target == GLITZ_GL_TEXTURE_2D)
+    {
+        dst->x = (INT_TO_FIXED (surface->texture.box.x1) + src->x) /
+            surface->texture.width;
+        dst->y = (INT_TO_FIXED (surface->texture.box.y2) - src->y) /
+            surface->texture.height;
+    }
+    else
+    {
+        dst->x = INT_TO_FIXED (surface->texture.box.x1) + src->x;
+        dst->y = INT_TO_FIXED (surface->texture.box.y2) - src->y;
+    }
+}
+slim_hidden_def(glitz_surface_translate_point);
+
+void
+glitz_surface_set_clip_region (glitz_surface_t *surface,
+                               int             x_origin,
+                               int             y_origin,
+                               glitz_box_t     *box,
+                               int             n_box)
+{
+    if (n_box)
+    {
+        surface->clip   = box;
+        surface->n_clip = n_box;
+        surface->x_clip = x_origin;
+        surface->y_clip = y_origin;
+    }
+    else
+    {
+        surface->clip   = &surface->box;
+        surface->n_clip = 1;
+        surface->x_clip = surface->y_clip = 0;
+    }
+}
+slim_hidden_def(glitz_surface_set_clip_region);

Index: glitz_texture.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_texture.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- glitz_texture.c	3 Nov 2004 22:50:58 -0000	1.16
+++ glitz_texture.c	25 Jan 2005 19:50:26 -0000	1.17
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -34,55 +34,69 @@
                     int             width,
                     int             height,
                     glitz_gl_int_t  texture_format,
-                    unsigned long   feature_mask)
+                    unsigned long   feature_mask,
+                    glitz_bool_t    unnormalized)
 {
-  texture->filter = 0;
-  texture->wrap = 0;
-  texture->format = texture_format;
-  texture->name = 0;
+    texture->filter = 0;
+    texture->wrap = 0;
+    texture->format = texture_format;
+    texture->name = 0;
 
-  if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK) {
-    texture->box.x1 = texture->box.y1 = 0;
-    texture->box.x2 = texture->width = width;
-    texture->box.y2 = texture->height = height;
-    texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
-      GLITZ_TEXTURE_FLAG_PADABLE_MASK;
-  } else {
-    texture->box.x1 = texture->box.y1 = 1;
-    texture->box.x2 = width + 1;
-    texture->box.y2 = height + 1;
-    texture->width = width + 2;
-    texture->height = height + 2;
-    texture->flags = 0;
-  }
+    if (feature_mask & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)
+    {
+        texture->box.x1 = texture->box.y1 = 0;
+        texture->box.x2 = texture->width = width;
+        texture->box.y2 = texture->height = height;
+        texture->flags = GLITZ_TEXTURE_FLAG_REPEATABLE_MASK |
+            GLITZ_TEXTURE_FLAG_PADABLE_MASK;
+    }
+    else
+    {
+        texture->box.x1 = texture->box.y1 = 1;
+        texture->box.x2 = width + 1;
+        texture->box.y2 = height + 1;
+        texture->width = width + 2;
+        texture->height = height + 2;
+        texture->flags = 0;
+    }
   
-  if ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) ||
-      (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height))) {
-    texture->target = GLITZ_GL_TEXTURE_2D;
-  } else {
-    texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK;
-
-    if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK) {
-      texture->target = GLITZ_GL_TEXTURE_RECTANGLE;
-    } else {
-      texture->target = GLITZ_GL_TEXTURE_2D;
-      texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK;
-        
-      if (!POWER_OF_TWO (texture->width))
-        texture->width = glitz_uint_to_power_of_two (texture->width);
+    if (!unnormalized &&
+        ((feature_mask & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) ||
+         (POWER_OF_TWO (texture->width) && POWER_OF_TWO (texture->height))))
+    {
+        texture->target = GLITZ_GL_TEXTURE_2D;
+    }
+    else
+    {
+        texture->flags &= ~GLITZ_TEXTURE_FLAG_REPEATABLE_MASK;
       
-      if (!POWER_OF_TWO (texture->height))
-        texture->height = glitz_uint_to_power_of_two (texture->height);
+        if (feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)
+        {
+            texture->target = GLITZ_GL_TEXTURE_RECTANGLE;
+        }
+        else
+        {
+            texture->target = GLITZ_GL_TEXTURE_2D;
+            texture->flags &= ~GLITZ_TEXTURE_FLAG_PADABLE_MASK;
+          
+            if (!POWER_OF_TWO (texture->width))
+                texture->width = glitz_uint_to_power_of_two (texture->width);
+          
+            if (!POWER_OF_TWO (texture->height))
+                texture->height = glitz_uint_to_power_of_two (texture->height);
+        }
     }
-  }
 
-  if (texture->target == GLITZ_GL_TEXTURE_2D) {
-    texture->texcoord_width_unit = 1.0f / texture->width;
-    texture->texcoord_height_unit = 1.0f / texture->height;   
-  } else {
-    texture->texcoord_width_unit = 1.0f;
-    texture->texcoord_height_unit = 1.0f;
-  }
+    if (texture->target == GLITZ_GL_TEXTURE_2D)
+    {
+        texture->texcoord_width_unit = 1.0f / texture->width;
+        texture->texcoord_height_unit = 1.0f / texture->height;   
+    }
+    else
+    {
+        texture->texcoord_width_unit = 1.0f;
+        texture->texcoord_height_unit = 1.0f;
+    }
 }
 
 void
@@ -240,47 +254,85 @@
 void
 glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
                            glitz_texture_t              *texture,
+                           glitz_geometry_t             *geometry,
                            int                          x_src,
                            int                          y_src,
-                           unsigned long                flags)
+                           unsigned long                flags,
+                           glitz_int_coordinate_t       *coord)
 {
-  glitz_vec4_t plane;
+    glitz_vec4_t plane;
 
-  plane.v[1] = plane.v[2] = 0.0f;
-  
-  if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) {
-    plane.v[0] = 1.0f;
-    plane.v[3] = -x_src;
-  } else {
-    plane.v[0] = texture->texcoord_width_unit;
-    
-    if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
-      plane.v[3] = -(x_src) * texture->texcoord_width_unit;
-    else
-      plane.v[3] = -(x_src - texture->box.x1) * texture->texcoord_width_unit;
-  }  
-  
-  gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE,
-                 GLITZ_GL_EYE_LINEAR);
-  gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v);
-  gl->enable (GLITZ_GL_TEXTURE_GEN_S);
+    if (flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK)
+    {
+        plane.v[1] = plane.v[2] = 0.0f;
+        
+        if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
+        {
+            plane.v[0] = 1.0f;
+            plane.v[3] = -x_src;
+        }
+        else
+        {
+            plane.v[0] = texture->texcoord_width_unit;
+            
+            if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
+                plane.v[3] = -(x_src) * texture->texcoord_width_unit;
+            else
+                plane.v[3] = -(x_src - texture->box.x1) *
+                    texture->texcoord_width_unit;
+        }
+        
+        gl->tex_gen_i (GLITZ_GL_S, GLITZ_GL_TEXTURE_GEN_MODE,
+                       GLITZ_GL_EYE_LINEAR);
+        gl->tex_gen_fv (GLITZ_GL_S, GLITZ_GL_EYE_PLANE, plane.v);
 
-  plane.v[0] = 0.0f;
-  if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK) {
-    plane.v[1] = 1.0f;
-    plane.v[3] = -y_src;
-  } else {
-    plane.v[1] = -texture->texcoord_height_unit;
-    
-    if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
-      plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) *
-        texture->texcoord_height_unit;
+        gl->enable (GLITZ_GL_TEXTURE_GEN_S);
+    }
     else
-      plane.v[3] = (y_src + texture->box.y2) * texture->texcoord_height_unit;
-  }
+        gl->disable (GLITZ_GL_TEXTURE_GEN_S);
+
+    if (flags & GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK)
+    {
+        plane.v[0] = 0.0f;
+        if (flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
+        {
+            plane.v[1] = 1.0f;
+            plane.v[3] = -y_src;
+        }
+        else
+        {
+            plane.v[1] = -texture->texcoord_height_unit;
+            
+            if (flags & GLITZ_SURFACE_FLAG_TRANSFORM_MASK)
+                plane.v[3] = (y_src + texture->box.y2 - texture->box.y1) *
+                    texture->texcoord_height_unit;
+            else
+                plane.v[3] = (y_src + texture->box.y2) *
+                    texture->texcoord_height_unit;
+        }
   
-  gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE,
-                 GLITZ_GL_EYE_LINEAR);
-  gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v);
-  gl->enable (GLITZ_GL_TEXTURE_GEN_T);
+        gl->tex_gen_i (GLITZ_GL_T, GLITZ_GL_TEXTURE_GEN_MODE,
+                       GLITZ_GL_EYE_LINEAR);
+        gl->tex_gen_fv (GLITZ_GL_T, GLITZ_GL_EYE_PLANE, plane.v);
+        
+        gl->enable (GLITZ_GL_TEXTURE_GEN_T);
+    }
+    else
+        gl->disable (GLITZ_GL_TEXTURE_GEN_T);
+
+    if (!(flags & GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK))
+    {
+        unsigned char *ptr;
+
+        gl->enable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY);
+        
+        ptr = glitz_buffer_bind (geometry->buffer, GLITZ_GL_ARRAY_BUFFER);
+        ptr += coord->offset;
+
+        gl->tex_coord_pointer (coord->size,
+                               coord->type,
+                               geometry->stride,
+                               (void *) ptr);
+    } else
+        gl->disable_client_state (GLITZ_GL_TEXTURE_COORD_ARRAY);
 }


--- NEW FILE: glitz_trapimp.h ---
(This appears to be a binary file; contents omitted.)

Index: glitz_util.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_util.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- glitz_util.c	3 Nov 2004 22:50:58 -0000	1.11
+++ glitz_util.c	25 Jan 2005 19:50:26 -0000	1.12
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -51,9 +51,12 @@
   { 0.0, "GL_NV_multisample_filter_hint",
     GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK },
   { 0.0, "GL_ARB_multitexture", GLITZ_FEATURE_MULTITEXTURE_MASK },
+  { 0.0, "GL_EXT_multi_draw_arrays", GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK },
   { 0.0, "GL_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK },
   { 0.0, "GL_ARB_vertex_buffer_object",
     GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK },
+  { 0.0, "GL_ARB_pixel_buffer_object",
+    GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
   { 0.0, "GL_EXT_pixel_buffer_object",
     GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK },
   { 0.0, "GL_EXT_blend_color", GLITZ_FEATURE_BLEND_COLOR_MASK },
@@ -154,17 +157,30 @@
     if (backend->gl_version >= 1.3f) {
       backend->gl.active_texture = (glitz_gl_active_texture_t)
         get_proc_address ("glActiveTexture", closure);
+      backend->gl.client_active_texture = (glitz_gl_client_active_texture_t)
+        get_proc_address ("glClientActiveTexture", closure);
     } else {
       backend->gl.active_texture = (glitz_gl_active_texture_t)
         get_proc_address ("glActiveTextureARB", closure);
+      backend->gl.client_active_texture = (glitz_gl_client_active_texture_t)
+        get_proc_address ("glClientActiveTextureARB", closure);
     }
 
-    if (!backend->gl.active_texture) {
+    if ((!backend->gl.active_texture) ||
+        (!backend->gl.client_active_texture)) {
       backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK;
       backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK;
     }
   }
 
+  if (backend->feature_mask & GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK) {
+    backend->gl.multi_draw_arrays = (glitz_gl_multi_draw_arrays_t)
+      get_proc_address ("glMultiDrawArraysEXT", closure);
+
+    if (!backend->gl.multi_draw_arrays)
+      backend->feature_mask &= ~GLITZ_FEATURE_MULTI_DRAW_ARRAYS_MASK;
+  }
+
   if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) {
     backend->gl.gen_programs = (glitz_gl_gen_programs_t)
       get_proc_address ("glGenProgramsARB", closure);
@@ -278,8 +294,8 @@
 
 void
 glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl,
-                      int                          x,
-                      int                          y)
+                      glitz_float_t                x,
+                      glitz_float_t                y)
 {
   gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT);
   gl->matrix_mode (GLITZ_GL_PROJECTION);

Index: glitzint.h
===================================================================
RCS file: /cvs/cairo/glitz/src/glitzint.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- glitzint.h	3 Nov 2004 22:50:58 -0000	1.30
+++ glitzint.h	25 Jan 2005 19:50:26 -0000	1.31
@@ -1,11 +1,11 @@
 /*
- * Copyright © 2004 David Reveman
+ * Copyright © 2004 David Reveman
  * 
  * Permission to use, copy, modify, distribute, and sell this software
  * and its documentation for any purpose is hereby granted without
  * fee, provided that the above copyright notice appear in all copies
  * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
  * David Reveman not be used in advertising or publicity pertaining to
  * distribution of the software without specific, written prior permission.
  * David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Author: David Reveman <c99drn at cs.umu.se>
+ * Author: David Reveman <davidr at novell.com>
  */
 
 #ifndef GLITZINT_H_INCLUDED
@@ -29,9 +29,23 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+#include <math.h>
 
 #include "glitz.h"
 
+#if defined(__APPLE__) || defined(__sun__)
+# define floorf(a)    floor (a)
+# define ceilf(a)     ceil (a)
+# define sinf(a)      sin (a)
+# define cosf(a)      cos (a)
+# define tanf(a)      tan (a)
+# define asinf(a)     asin (a)
+# define acosf(a)     acos (a)
+# define atanf(a)     atan (a)
+# define atan2f(a, b) atan2 (a, b)
+# define sqrtf(a)     sqrt (a)
+#endif
+
 #if __GNUC__ >= 3 && defined(__ELF__)
 # define slim_hidden_proto(name)	slim_hidden_proto1(name, INT_##name)
 # define slim_hidden_def(name)		slim_hidden_def1(name, INT_##name)
@@ -71,9 +85,6 @@
 
 #include "glitz_gl.h"
 
-#define GLITZ_DEFAULT_PBUFFER_WIDTH  512
-#define GLITZ_DEFAULT_PBUFFER_HEIGHT 512
-
 #define GLITZ_CONTEXT_STACK_SIZE 16
 
 typedef void (*glitz_function_pointer_t) (void);
@@ -88,6 +99,7 @@
   glitz_gl_enable_client_state_t        enable_client_state;
   glitz_gl_disable_client_state_t       disable_client_state;
   glitz_gl_vertex_pointer_t             vertex_pointer;
+  glitz_gl_tex_coord_pointer_t          tex_coord_pointer;
   glitz_gl_draw_arrays_t                draw_arrays;
   glitz_gl_tex_env_f_t                  tex_env_f;
   glitz_gl_tex_env_fv_t                 tex_env_fv;
@@ -142,6 +154,8 @@
   /* extensions */
   glitz_gl_blend_color_t                blend_color;
   glitz_gl_active_texture_t             active_texture;
+  glitz_gl_client_active_texture_t      client_active_texture;
+  glitz_gl_multi_draw_arrays_t          multi_draw_arrays;
   glitz_gl_gen_programs_t               gen_programs;
   glitz_gl_delete_programs_t            delete_programs;
   glitz_gl_program_string_t             program_string;
@@ -175,19 +189,22 @@
 #define GLITZ_COMBINE_TYPE_ARGB           1
 #define GLITZ_COMBINE_TYPE_ARGB_ARGB      2
 #define GLITZ_COMBINE_TYPE_ARGB_ARGBC     3
-#define GLITZ_COMBINE_TYPE_ARGB_SOLID     4
-#define GLITZ_COMBINE_TYPE_ARGB_SOLIDC    5
-#define GLITZ_COMBINE_TYPE_ARGBF          6
-#define GLITZ_COMBINE_TYPE_ARGBF_ARGB     7
-#define GLITZ_COMBINE_TYPE_ARGBF_ARGBC    8
-#define GLITZ_COMBINE_TYPE_ARGBF_SOLID    9
-#define GLITZ_COMBINE_TYPE_ARGBF_SOLIDC  10
-#define GLITZ_COMBINE_TYPE_SOLID         11
-#define GLITZ_COMBINE_TYPE_SOLID_ARGB    12
-#define GLITZ_COMBINE_TYPE_SOLID_ARGBC   13
-#define GLITZ_COMBINE_TYPE_SOLID_SOLID   14
-#define GLITZ_COMBINE_TYPE_SOLID_SOLIDC  15
-#define GLITZ_COMBINE_TYPES              16
+#define GLITZ_COMBINE_TYPE_ARGB_ARGBF     4
+#define GLITZ_COMBINE_TYPE_ARGB_SOLID     5
+#define GLITZ_COMBINE_TYPE_ARGB_SOLIDC    6
+#define GLITZ_COMBINE_TYPE_ARGBF          7
+#define GLITZ_COMBINE_TYPE_ARGBF_ARGB     8
+#define GLITZ_COMBINE_TYPE_ARGBF_ARGBC    9
+#define GLITZ_COMBINE_TYPE_ARGBF_ARGBF   10
+#define GLITZ_COMBINE_TYPE_ARGBF_SOLID   11
+#define GLITZ_COMBINE_TYPE_ARGBF_SOLIDC  12
+#define GLITZ_COMBINE_TYPE_SOLID         13
+#define GLITZ_COMBINE_TYPE_SOLID_ARGB    14
+#define GLITZ_COMBINE_TYPE_SOLID_ARGBC   15
+#define GLITZ_COMBINE_TYPE_SOLID_ARGBF   16
+#define GLITZ_COMBINE_TYPE_SOLID_SOLID   17
+#define GLITZ_COMBINE_TYPE_SOLID_SOLIDC  18
+#define GLITZ_COMBINE_TYPES              19
 
 #define GLITZ_TEXTURE_NONE 0
 #define GLITZ_TEXTURE_2D   1
@@ -225,10 +242,6 @@
   GLITZ_DRAWABLE_CURRENT
 } glitz_constraint_t;
 
-typedef struct _glitz_box_t {
-  short x1, y1, x2, y2;
-} glitz_box_t;
-
 typedef struct _glitz_region_t {
   glitz_box_t extents;
   glitz_box_t *box;
@@ -295,10 +308,10 @@
 
 typedef struct glitz_backend {
   glitz_drawable_t *
-  (*create_pbuffer)            (void                       *drawable,
-                                glitz_drawable_format_t    *format,
-                                glitz_pbuffer_attributes_t *attributes,
-                                unsigned long              mask);
+  (*create_pbuffer)            (void                    *drawable,
+                                glitz_drawable_format_t *format,
+                                unsigned int            width,
+                                unsigned int            height);
   
   void
   (*destroy)                   (void *drawable);
@@ -347,11 +360,11 @@
 #define GLITZ_GL_DRAWABLE(drawable) \
   glitz_gl_proc_address_list_t *gl = &(drawable)->backend->gl;
 
-typedef struct _glitz_point_t {
-  glitz_float_t x, y;
-} glitz_point_t;
+typedef struct _glitz_vec2_t {
+  glitz_float_t v[2];
+} glitz_vec2_t;
 
-typedef struct _glitz_vec_t {
+typedef struct _glitz_vec4_t {
   glitz_float_t v[4];
 } glitz_vec4_t;
 
@@ -399,15 +412,50 @@
   glitz_drawable_t *drawable;
 };
 
+struct _glitz_multi_array {
+  int ref_count;
+  int size;
+  int n_arrays;
+  int *first;
+  int *sizes;
+  int *count;
+  int *span, *current_span;
+  glitz_vec2_t *off;
+};
+
+typedef struct _glitz_int_coordinate {
+  glitz_gl_enum_t type;
+  int             size, offset;
+} glitz_int_coordinate_t;
+
+typedef struct _glitz_vertex_info {
+  glitz_gl_enum_t        prim;
+  glitz_gl_enum_t        type;
+  glitz_int_coordinate_t src;
+  glitz_int_coordinate_t mask;
+} glitz_vertex_info_t;
+
+typedef struct _glitz_bitmap_info {
+  glitz_bool_t     top_down;
+  glitz_gl_int_t   pad;
+  glitz_gl_ubyte_t *base;
+} glitz_bitmap_info_t;
+
 typedef struct _glitz_geometry {
-  glitz_gl_enum_t  primitive;
-  glitz_gl_enum_t  type;
-  glitz_gl_int_t   first;
-  glitz_gl_sizei_t count;
-  glitz_buffer_t   *buffer;
-  glitz_float_t    x_offset;
-  glitz_float_t    y_offset;
-  glitz_gl_float_t data[8];
+  glitz_geometry_type_t type;
+  glitz_buffer_t        *buffer;
+  glitz_gl_sizei_t      stride;
+  glitz_gl_float_t      data[8];
+  glitz_gl_int_t        first;
+  glitz_gl_int_t        size;
+  glitz_gl_sizei_t      count;
+  glitz_vec2_t          off;
+  glitz_multi_array_t   *array;
+  unsigned long         attributes;
+  union {
+    glitz_vertex_info_t v;
+    glitz_bitmap_info_t b;
+  } u;
 } glitz_geometry_t;
 
 #define GLITZ_SURFACE_FLAG_SOLID_MASK                   (1L <<  0)
@@ -425,6 +473,12 @@
 #define GLITZ_SURFACE_FLAG_EYE_COORDS_MASK              (1L << 12)
 #define GLITZ_SURFACE_FLAG_TRANSFORM_MASK               (1L << 13)
 #define GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK    (1L << 14)
+#define GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK            (1L << 15)
+#define GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK            (1L << 16)
+
+#define GLITZ_SURFACE_FLAGS_GEN_COORDS_MASK  \
+    (GLITZ_SURFACE_FLAG_GEN_S_COORDS_MASK | \
+     GLITZ_SURFACE_FLAG_GEN_T_COORDS_MASK)
 
 #define SURFACE_SOLID(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_MASK)
@@ -446,12 +500,6 @@
 #define SURFACE_DITHER(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_DITHER_MASK)
 
-#define SURFACE_MULTISAMPLE(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK)
-
-#define SURFACE_NICEST_MULTISAMPLE(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK)
-
 #define SURFACE_SOLID_DAMAGE(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
 
@@ -470,17 +518,6 @@
 #define SURFACE_PROJECTIVE_TRANSFORM(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK)
 
-typedef struct _glitz_sample_offset {
-  glitz_float_t x;
-  glitz_float_t y;
-} glitz_sample_offset_t;
-
-typedef struct _glitz_multi_sample_info {
-  glitz_sample_offset_t *offsets;
-  unsigned short        *weights;
-  int                   n_samples;
-} glitz_sample_info_t;
-
 typedef struct _glitz_filter_params_t glitz_filter_params_t;
 
 typedef struct _glitz_matrix {
@@ -503,12 +540,23 @@
   glitz_filter_params_t *filter_params;
   glitz_matrix_t        *transform;
   int                   x, y;
-  int                   width, height;
+  glitz_box_t           box;
+  short                 x_clip, y_clip;
+  glitz_box_t           *clip;
+  int                   n_clip;
   glitz_gl_enum_t       buffer;
   unsigned long         flags;
-  glitz_sample_info_t   *indirect;
   glitz_color_t         solid;
   glitz_geometry_t      geometry;
+  void                  *arrays;
+  int                   n_arrays;
+  int                   *first;
+  unsigned int          *count;
+  glitz_vec2_t          *off;
+  int                   default_first;
+  unsigned int          default_count;
+  glitz_vec2_t          default_off;
+  int                   *primcount;
   glitz_region_t        texture_damage;
   glitz_region_t        drawable_damage;
 };
@@ -524,7 +572,7 @@
   glitz_combine_type_t     type;
   glitz_combine_function_t enable;
   int                      texture_units;
-  int                      fragment_processing;
+  int                      source_shader;
 } glitz_combine_t;
 
 struct _glitz_composite_op_t {
@@ -570,8 +618,8 @@
 
 extern void __internal_linkage
 glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl,
-                      int                          x,
-                      int                          y);
+                      glitz_float_t                x,
+                      glitz_float_t                y);
 
 extern void __internal_linkage
 glitz_clamp_value (glitz_float_t *value,
@@ -599,7 +647,8 @@
                     int             width,
                     int             height,
                     glitz_gl_int_t  texture_format,
-                    unsigned long   feature_mask);
+                    unsigned long   feature_mask,
+                    glitz_bool_t    unnormalized);
 
 void
 glitz_texture_fini (glitz_gl_proc_address_list_t *gl,
@@ -618,7 +667,7 @@
 extern void __internal_linkage
 glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl,
                              glitz_texture_t              *texture,
-                             glitz_filter_t               filter);
+                             glitz_gl_enum_t              filter);
 
 extern void __internal_linkage
 glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl,
@@ -647,11 +696,13 @@
 void
 glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
                            glitz_texture_t              *texture,
+                           glitz_geometry_t             *geometry,
                            int                          x_src,
                            int                          y_src,
-                           unsigned long                flags);
+                           unsigned long                flags,
+                           glitz_int_coordinate_t       *coord);
 
-extern glitz_texture_t *__internal_linkage
+extern glitz_texture_t __internal_linkage *
 glitz_surface_get_texture (glitz_surface_t *surface,
                            glitz_bool_t    allocate);
 
@@ -708,7 +759,7 @@
 extern void __internal_linkage
 glitz_composite_disable (glitz_composite_op_t *op);
 
-extern void *__internal_linkage
+extern void __internal_linkage *
 glitz_buffer_bind (glitz_buffer_t  *buffer,
                    glitz_gl_enum_t target);
 
@@ -725,9 +776,6 @@
 glitz_filter_set_type (glitz_surface_t *surface,
                        glitz_filter_t  filter);
 
-extern void __internal_linkage
-glitz_filter_params_destroy (glitz_filter_params_t *params);
-
 extern glitz_gl_uint_t __internal_linkage
 glitz_filter_get_vertex_program (glitz_surface_t      *surface,
                                  glitz_composite_op_t *op);
@@ -741,22 +789,24 @@
                      glitz_composite_op_t *op);
 
 extern void __internal_linkage
-glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl,
-                               glitz_surface_t              *dst,
-                               glitz_box_t                  *box);
+glitz_geometry_enable_none (glitz_gl_proc_address_list_t *gl,
+                            glitz_surface_t              *dst,
+                            glitz_box_t                  *box);
 
 extern void __internal_linkage
 glitz_geometry_enable (glitz_gl_proc_address_list_t *gl,
                        glitz_surface_t              *dst,
-                       glitz_gl_enum_t              *primitive,
-                       glitz_gl_int_t               *first,
-                       glitz_gl_sizei_t             *count,
                        glitz_box_t                  *box);
 
 extern void __internal_linkage
-glitz_geometry_disable (glitz_gl_proc_address_list_t *gl,
-                        glitz_surface_t              *dst);
+glitz_geometry_disable (glitz_surface_t *dst);
 
+extern void __internal_linkage
+glitz_geometry_draw_arrays (glitz_gl_proc_address_list_t *gl,
+                            glitz_surface_t              *dst,
+                            glitz_geometry_type_t        type,
+                            glitz_box_t                  *bounds,
+                            int                          damage);
 
 #define MAXSHORT SHRT_MAX
 #define MINSHORT SHRT_MIN
@@ -856,9 +906,16 @@
 slim_hidden_proto(glitz_surface_get_format)
 slim_hidden_proto(glitz_surface_get_drawable)
 slim_hidden_proto(glitz_surface_get_attached_drawable)
+slim_hidden_proto(glitz_surface_translate_point)
+slim_hidden_proto(glitz_surface_set_clip_region)
 slim_hidden_proto(glitz_set_rectangle)
 slim_hidden_proto(glitz_set_rectangles)
 slim_hidden_proto(glitz_set_geometry)
+slim_hidden_proto(glitz_set_array)
+slim_hidden_proto(glitz_multi_array_create)
+slim_hidden_proto(glitz_multi_array_add)
+slim_hidden_proto(glitz_multi_array_reset)
+slim_hidden_proto(glitz_set_multi_array)
 slim_hidden_proto(glitz_buffer_set_data)
 slim_hidden_proto(glitz_buffer_get_data)
 




More information about the cairo-commit mailing list