[cairo-commit] glitz/src Makefile.am, 1.7, 1.8 glitz-agl.h, 1.5, NONE glitz-glx.h, 1.5, NONE glitz.c, 1.29, 1.30 glitz.h, 1.24, 1.25 glitz.pc.in, NONE, 1.1 glitz_agl_context.c, 1.10, NONE glitz_agl_extension.c, 1.14, NONE glitz_agl_format.c, 1.7, NONE glitz_agl_info.c, 1.15, NONE glitz_agl_pbuffer.c, 1.6, NONE glitz_agl_surface.c, 1.21, NONE glitz_aglint.h, 1.14, NONE glitz_buffer.c, 1.4, 1.5 glitz_compose.c, 1.9, 1.10 glitz_drawable.c, NONE, 1.1 glitz_format.c, 1.8, 1.9 glitz_geometry.c, 1.3, 1.4 glitz_gl.h, 1.12, 1.13 glitz_glx_context.c, 1.17, NONE glitz_glx_extension.c, 1.16, NONE glitz_glx_format.c, 1.11, NONE glitz_glx_info.c, 1.22, NONE glitz_glx_pbuffer.c, 1.5, NONE glitz_glx_surface.c, 1.22, NONE glitz_glxext.h, 1.7, NONE glitz_glxint.h, 1.18, NONE glitz_operator.c, 1.5, 1.6 glitz_pixel.c, 1.12, 1.13 glitz_program.c, 1.15, 1.16 glitz_rect.c, 1.13, 1.14 glitz_region.c, NONE, 1.1 glitz_surface.c, 1.23, 1.24 glitz_texture.c, 1.15, 1.16 glitz_util.c, 1.10, 1.11 glitzint.h, 1.29, 1.30

David Reveman commit at pdx.freedesktop.org
Wed Nov 3 14:51:01 PST 2004


Committed by: davidr

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

Modified Files:
	Makefile.am glitz.c glitz.h glitz_buffer.c glitz_compose.c 
	glitz_format.c glitz_geometry.c glitz_gl.h glitz_operator.c 
	glitz_pixel.c glitz_program.c glitz_rect.c glitz_surface.c 
	glitz_texture.c glitz_util.c glitzint.h 
Added Files:
	glitz.pc.in glitz_drawable.c glitz_region.c 
Removed Files:
	glitz-agl.h glitz-glx.h glitz_agl_context.c 
	glitz_agl_extension.c glitz_agl_format.c glitz_agl_info.c 
	glitz_agl_pbuffer.c glitz_agl_surface.c glitz_aglint.h 
	glitz_glx_context.c glitz_glx_extension.c glitz_glx_format.c 
	glitz_glx_info.c glitz_glx_pbuffer.c glitz_glx_surface.c 
	glitz_glxext.h glitz_glxint.h 
Log Message:
Source tree restructuring and switch to new drawable interface

Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/glitz/src/Makefile.am,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- Makefile.am	3 Sep 2004 14:27:58 -0000	1.7
+++ Makefile.am	3 Nov 2004 22:50:58 -0000	1.8
@@ -1,85 +1,35 @@
-if GLITZ_BUILD_GLX_BACKEND
-libglitz_glx_library = libglitz-glx.la
-libglitz_glx_header = glitz-glx.h
-else
-libglitz_glx_library =
-libglitz_glx_header =
-endif
-
-if GLITZ_BUILD_AGL_BACKEND
-libglitz_agl_library = libglitz-agl.la
-libglitz_agl_header = glitz-agl.h
-else
-libglitz_agl_library =
-libglitz_agl_header =
-endif
-
-lib_LTLIBRARIES = \
-	libglitz.la \
-	$(libglitz_glx_library) \
-	$(libglitz_agl_library)
+SUBDIRS = . glx agl
 
-include_HEADERS = \
-	glitz.h \
-	$(libglitz_glx_header) \
-	$(libglitz_agl_header)
+lib_LTLIBRARIES = libglitz.la
+include_HEADERS = glitz.h
 
-libglitz_la_SOURCES = \
-	glitz.c \
-	glitz.h \
+libglitz_la_SOURCES =	 \
+	glitz.h		 \
+	glitz.c		 \
 	glitz_operator.c \
-	glitz_surface.c \
-	glitz_texture.c \
-	glitz_rect.c \
-	glitz_status.c \
-	glitz_util.c \
-	glitz_format.c \
-	glitz_program.c \
-	glitz_compose.c \
-	glitz_filter.c \
-	glitz_buffer.c \
+	glitz_drawable.c \
+	glitz_surface.c	 \
+	glitz_texture.c	 \
+	glitz_rect.c	 \
+	glitz_status.c	 \
+	glitz_util.c	 \
+	glitz_region.c	 \
+	glitz_format.c	 \
+	glitz_program.c	 \
+	glitz_compose.c	 \
+	glitz_filter.c	 \
+	glitz_buffer.c	 \
 	glitz_geometry.c \
-	glitz_pixel.c \
-	glitz_gl.h \
+	glitz_pixel.c	 \
+	glitz_gl.h	 \
 	glitzint.h
 
 libglitz_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined
-libglitz_la_CFLAGS =
 libglitz_la_LIBADD = -lm
 
-if GLITZ_BUILD_GLX_BACKEND
-libglitz_glx_la_SOURCES = \
-	glitz.h \
-	glitz_gl.h \
-	glitzint.h \
-	glitz-glx.h \
-	glitz_glx_surface.c \
-	glitz_glx_format.c \
-	glitz_glx_info.c \
-	glitz_glx_extension.c \
-	glitz_glx_context.c \
-	glitz_glx_pbuffer.c \
-	glitz_glxext.h \
-	glitz_glxint.h
-libglitz_glx_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined
-libglitz_glx_la_CFLAGS = $(GLX_CFLAGS)
-libglitz_glx_la_LIBADD = -lglitz $(GLX_LIBS)
-endif
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = glitz.pc
 
-if GLITZ_BUILD_AGL_BACKEND
-libglitz_agl_la_SOURCES = \
-	glitz.h \
-	glitz_gl.h \
-	glitzint.h \
-	glitz-agl.h \
-	glitz_agl_surface.c \
-	glitz_agl_format.c \
-	glitz_agl_info.c \
-	glitz_agl_extension.c \
-	glitz_agl_context.c \
-	glitz_agl_pbuffer.c \
-	glitz_aglint.h
-libglitz_agl_la_LDFLAGS = -version-info @VERSION_INFO@
-libglitz_agl_la_CFLAGS = $(AGL_CFLAGS)
-libglitz_agl_la_LIBADD = -lglitz $(AGL_LIBS)
-endif
+EXTRA_DIST =	     \
+	glitz.pc.in  \
+	glitz.man
\ No newline at end of file

--- glitz-agl.h DELETED ---

--- glitz-glx.h DELETED ---

Index: glitz.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- glitz.c	20 Oct 2004 23:03:36 -0000	1.29
+++ glitz.c	3 Nov 2004 22:50:58 -0000	1.30
@@ -61,9 +61,6 @@
                  int width,
                  int height)
 {
-  glitz_gl_proc_address_list_t *gl = &dst->backend->gl;
-  glitz_surface_t *intermediate = NULL;
-  glitz_bounding_box_t rect;
   glitz_composite_op_t comp_op;
   int i, passes, texture_nr = -1;
   glitz_texture_t *stexture, *mtexture;
@@ -72,6 +69,9 @@
   glitz_gl_enum_t primitive;
   glitz_gl_int_t first;
   glitz_gl_sizei_t count;
+  glitz_box_t rect;
+
+  GLITZ_GL_SURFACE (dst);
 
   if (width <= 0 || height <= 0)
     return;
@@ -84,64 +84,6 @@
 
   src = comp_op.src;
   mask = comp_op.mask;
-  
-  if (comp_op.type == GLITZ_COMBINE_TYPE_INTERMEDIATE) {
-    glitz_format_t templ;
-    glitz_format_t *format;
-    unsigned long templ_mask;
-    
-    templ.red_size = src->format->red_size;
-    templ.green_size = src->format->green_size;
-    templ.blue_size = src->format->blue_size;
-    templ.alpha_size = MAX (src->format->alpha_size, mask->format->alpha_size);
-    templ.draw.offscreen = 1;
-    
-    templ_mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK |
-      GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK |
-      GLITZ_FORMAT_DRAW_OFFSCREEN_MASK;
-    
-    format = glitz_surface_find_similar_format (dst, templ_mask, &templ, 0);
-    if (!format) {
-      glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
-      return;
-    }
-    
-    intermediate = glitz_surface_create_similar (dst, format, width, height);  
-    if (!intermediate) {
-      glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
-      return;
-    }
-    
-    glitz_composite (GLITZ_OPERATOR_SRC,
-                     mask, NULL, intermediate,
-                     x_mask, y_mask,
-                     0, 0,
-                     0, 0,
-                     width,
-                     height);
-
-    glitz_composite (GLITZ_OPERATOR_IN,
-                     src, NULL, intermediate,
-                     x_src, y_src,
-                     0, 0,
-                     0, 0,
-                     width,
-                     height);
-    
-    src = intermediate;
-    mask = NULL;
-    x_src = y_src = 0;
-
-    glitz_composite_op_init (&comp_op, op, src, mask, dst);
-    if (comp_op.type == GLITZ_COMBINE_TYPE_NA) {
-      glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
-      glitz_surface_destroy (intermediate);
-      return;
-    }
-
-    src = comp_op.src;
-    mask = comp_op.mask;
-  }
 
   if (src) {
     stexture = glitz_surface_get_texture (src, 0);
@@ -157,7 +99,7 @@
   } else
     mtexture = NULL;
 
-  if (!glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
+  if (!glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) {
     glitz_surface_status_add (dst, GLITZ_STATUS_NOT_SUPPORTED_MASK);
     glitz_surface_pop_current (dst);
     return;
@@ -202,7 +144,7 @@
       else
         glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_REPEAT);
     } else {
-      if ((!(dst->backend->feature_mask &
+      if ((!(dst->drawable->backend->feature_mask &
              GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)) ||
           SURFACE_PAD (mask))
         glitz_texture_ensure_wrap (gl, mtexture, GLITZ_GL_CLAMP_TO_EDGE);
@@ -235,7 +177,7 @@
       gl->load_matrix_f (SURFACE_EYE_COORDS (src)?
                          src->transform->m: src->transform->t);
       gl->matrix_mode (GLITZ_GL_MODELVIEW);
-      
+
       if (SURFACE_LINEAR_TRANSFORM_FILTER (src))
         glitz_texture_ensure_filter (gl, stexture, GLITZ_GL_LINEAR);
       else
@@ -249,7 +191,7 @@
       else
         glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_REPEAT);
     } else {
-      if ((!(dst->backend->feature_mask &
+      if ((!(dst->drawable->backend->feature_mask &
              GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)) ||
           SURFACE_PAD (src))
         glitz_texture_ensure_wrap (gl, stexture, GLITZ_GL_CLAMP_TO_EDGE);
@@ -258,8 +200,8 @@
     }
   }
 
-  gl->scissor (rect.x1,
-               dst->height - rect.y2,
+  gl->scissor (rect.x1 + dst->x,
+               dst->attached->height - dst->y - rect.y2,
                width, height);
 
   gl->push_matrix ();
@@ -388,13 +330,12 @@
     if (i > 0)
       gl->active_texture (textures[i - 1].unit);
   }
-  
-  glitz_surface_dirty (dst, &rect);
+
+  glitz_surface_damage (dst, &rect,
+                        GLITZ_DAMAGE_TEXTURE_MASK |
+                        GLITZ_DAMAGE_SOLID_MASK);
   
   glitz_surface_pop_current (dst);
-  
-  if (intermediate)
-    glitz_surface_destroy (intermediate);
 }
 
 void
@@ -407,8 +348,9 @@
                  int x_dst,
                  int y_dst)
 {
-  glitz_gl_proc_address_list_t *gl;
-  int status;
+  glitz_status_t status;
+
+  GLITZ_GL_SURFACE (dst);
   
   if (x_src < 0) {
     x_dst -= x_src;
@@ -443,35 +385,44 @@
   if (width <= 0 || height <= 0)
     return;
 
-  gl = &dst->backend->gl;
-
-  status = 0;
-  if (glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
-    glitz_bounding_box_t box;
+  status = GLITZ_STATUS_NOT_SUPPORTED;
+  if (glitz_surface_push_current (dst, GLITZ_DRAWABLE_CURRENT)) {
+    glitz_box_t box;
     
-    if (src != dst)
+    if (src->attached == dst->attached) {
+      if (REGION_NOTEMPTY (&src->drawable_damage)) {
+        glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT);
+        glitz_surface_pop_current (src);
+      }
+      status = GLITZ_STATUS_SUCCESS;
+    } else
       status = glitz_surface_make_current_read (src);
-    else
-      status = 1;
 
     box.x1 = x_dst;
     box.y1 = y_dst;
     box.x2 = box.x1 + width;
     box.y2 = box.y1 + height;
 
-    if (status) {
-      if (src->format->doublebuffer)
-        gl->read_buffer (src->read_buffer);
+    if (!status) {
+      gl->read_buffer (src->buffer);
+      gl->draw_buffer (dst->buffer);
       
       glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
       
-      gl->scissor (0, 0, dst->width, dst->height);
+      gl->disable (GLITZ_GL_SCISSOR_TEST);
       
-      glitz_set_raster_pos (gl, x_dst, dst->height - (y_dst + height));
-      gl->copy_pixels (x_src, src->height - (y_src + height),
+      glitz_set_raster_pos (gl,
+                            x_dst + dst->x,
+                            dst->attached->height - (y_dst + dst->y + height));
+      gl->copy_pixels (x_src + src->x,
+                       src->attached->height - (y_src + src->y + height),
                        width, height, GLITZ_GL_COLOR);
+
+      gl->enable (GLITZ_GL_SCISSOR_TEST);
     } else {
-      glitz_texture_t *texture = glitz_surface_get_texture (src, 0);
+      glitz_texture_t *texture;
+
+      texture = glitz_surface_get_texture (src, 0);
       if (texture) {
         glitz_texture_bind (gl, texture);
 
@@ -489,8 +440,8 @@
 
         glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
 
-        gl->scissor (box.x1,
-                     dst->height - box.y2,
+        gl->scissor (box.x1 + dst->x,
+                     dst->attached->height - dst->y - box.y2,
                      width, height);
         
         glitz_geometry_enable_default (gl, dst, &box);
@@ -501,57 +452,56 @@
       }
     }
     
-    glitz_surface_dirty (dst, &box);
+    glitz_surface_damage (dst, &box,
+                          GLITZ_DAMAGE_TEXTURE_MASK |
+                          GLITZ_DAMAGE_SOLID_MASK);
 
-    status = 1;
+    status = GLITZ_STATUS_SUCCESS;
   }
 
   glitz_surface_pop_current (dst);
 
-  if (!status) {
-    if (glitz_surface_push_current (src, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
+  if (status) {
+    if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) {
       glitz_texture_t *texture;
 
-      if (src->format->doublebuffer)
-        gl->read_buffer (src->read_buffer);
-
-      gl->scissor (0, 0, src->width, src->height);
+      gl->read_buffer (src->buffer);
 
       texture = glitz_surface_get_texture (dst, 1);
       if (texture) {
-        glitz_texture_copy_surface (texture, src,
-                                    x_src, y_src, width, height, x_dst, y_dst);
-        status = 1;
+        glitz_box_t box;
+
+        gl->disable (GLITZ_GL_SCISSOR_TEST);
+
+        glitz_texture_bind (gl, texture);
+
+        glitz_texture_copy_drawable (gl,
+                                     texture,
+                                     src->attached,
+                                     x_src + src->x,
+                                     y_src + src->y,
+                                     width, height,
+                                     x_dst, y_dst);
+
+        glitz_texture_unbind (gl, texture);
+
+        gl->enable (GLITZ_GL_SCISSOR_TEST);
+
+        box.x1 = x_dst;
+        box.y1 = y_dst;
+        box.x2 = box.x1 + width;
+        box.y2 = box.y1 + height;
+
+        glitz_surface_damage (dst, &box,
+                              GLITZ_DAMAGE_DRAWABLE_MASK |
+                              GLITZ_DAMAGE_SOLID_MASK);
+        
+        status = GLITZ_STATUS_SUCCESS;
       }
     }
     glitz_surface_pop_current (src);
   }
 
-  if (!status) {
-    static glitz_pixel_format_t pf = {
-      {
-        32,
-        0xff000000,
-        0x00ff0000,
-        0x0000ff00,
-        0x000000ff
-      },
-      0, 0, 0,
-      GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
-    };
-    glitz_buffer_t *buffer =
-      glitz_pixel_buffer_create (src,
-                                 NULL,
-                                 width * height * 4,
-                                 GLITZ_BUFFER_HINT_STATIC_COPY);
-    if (!buffer) {
-      glitz_surface_status_add (dst, GLITZ_STATUS_NO_MEMORY_MASK);
-      return;
-    }
-
-    glitz_get_pixels (src, x_src, y_src, width, height, &pf, buffer);
-    glitz_set_pixels (dst, x_dst, y_dst, width, height, &pf, buffer);
-    
-    glitz_buffer_destroy (buffer);
-  }
+  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.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- glitz.h	4 Oct 2004 11:46:10 -0000	1.24
+++ glitz.h	3 Nov 2004 22:50:58 -0000	1.25
@@ -36,10 +36,9 @@
 #  endif
 #endif
 
-/* NOTE: Must be manually synchronized with GLITZ_VERSION in configure.in */
-#define GLITZ_MAJOR 0
-#define GLITZ_MINOR 2
-#define GLITZ_REVISION 3
+#define GLITZ_MAJOR    0
+#define GLITZ_MINOR    3
+#define GLITZ_REVISION 0
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
@@ -53,7 +52,7 @@
 typedef int glitz_fixed16_16_t;
 
 typedef struct _glitz_rectangle_t {
-  short x, y;
+  short          x, y;
   unsigned short width, height;
 } glitz_rectangle_t;
 
@@ -90,8 +89,7 @@
   GLITZ_OPERATOR_ATOP,
   GLITZ_OPERATOR_ATOP_REVERSE,
   GLITZ_OPERATOR_XOR,
-  GLITZ_OPERATOR_ADD,
-  GLITZ_OPERATOR_SATURATE
+  GLITZ_OPERATOR_ADD
 } glitz_operator_t;
 
 #define GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK        (1L <<  0)
@@ -99,16 +97,16 @@
 #define GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK  (1L <<  2)
 #define GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK     (1L <<  3)
 #define GLITZ_FEATURE_MULTISAMPLE_MASK              (1L <<  4)
-#define GLITZ_FEATURE_OFFSCREEN_MULTISAMPLE_MASK    (1L <<  5)
-#define GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK  (1L <<  6)
-#define GLITZ_FEATURE_MULTITEXTURE_MASK             (1L <<  7)
-#define GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK      (1L <<  8)
-#define GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK         (1L <<  9)
-#define GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK         (1L << 10)
-#define GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK     (1L << 11)
-#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK      (1L << 12)
-#define GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK  (1L << 13)
-#define GLITZ_FEATURE_BLEND_COLOR_MASK              (1L << 14)
+#define GLITZ_FEATURE_MULTISAMPLE_FILTER_HINT_MASK  (1L <<  5)
+#define GLITZ_FEATURE_MULTITEXTURE_MASK             (1L <<  6)
+#define GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK      (1L <<  7)
+#define GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK         (1L <<  8)
+#define GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK         (1L <<  9)
+#define GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK     (1L << 10)
+#define GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK      (1L << 11)
+#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)
 
 typedef enum {
   GLITZ_STANDARD_ARGB32,
@@ -117,69 +115,155 @@
   GLITZ_STANDARD_A1
 } glitz_format_name_t;
   
-#define GLITZ_FORMAT_ID_MASK                  (1L <<  0)
-#define GLITZ_FORMAT_RED_SIZE_MASK            (1L <<  6)
-#define GLITZ_FORMAT_GREEN_SIZE_MASK          (1L <<  7)
-#define GLITZ_FORMAT_BLUE_SIZE_MASK           (1L <<  8)
-#define GLITZ_FORMAT_ALPHA_SIZE_MASK          (1L <<  9)
-#define GLITZ_FORMAT_DEPTH_SIZE_MASK          (1L << 10)
-#define GLITZ_FORMAT_STENCIL_SIZE_MASK        (1L << 11)
-#define GLITZ_FORMAT_DOUBLEBUFFER_MASK        (1L << 12)
-#define GLITZ_FORMAT_READ_ONSCREEN_MASK       (1L << 13)
-#define GLITZ_FORMAT_READ_OFFSCREEN_MASK      (1L << 14)
-#define GLITZ_FORMAT_DRAW_ONSCREEN_MASK       (1L << 15)
-#define GLITZ_FORMAT_DRAW_OFFSCREEN_MASK      (1L << 16)
-#define GLITZ_FORMAT_MULTISAMPLE_MASK         (1L << 17)
-#define GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK (1L << 18)
-
-typedef unsigned long int glitz_format_id_t;
-
-typedef struct _glitz_drawable_type_t {
-  glitz_bool_t onscreen;
-  glitz_bool_t offscreen;
-} glitz_drawable_type_t;
+#define GLITZ_FORMAT_ID_MASK         (1L <<  0)
+#define GLITZ_FORMAT_RED_SIZE_MASK   (1L <<  1)
+#define GLITZ_FORMAT_GREEN_SIZE_MASK (1L <<  2)
+#define GLITZ_FORMAT_BLUE_SIZE_MASK  (1L <<  3)
+#define GLITZ_FORMAT_ALPHA_SIZE_MASK (1L <<  4)
 
-typedef struct _glitz_multisample_format_t {
-  glitz_bool_t supported;
-  unsigned short samples;
-} glitz_multisample_format_t;
+typedef unsigned long glitz_format_id_t;
 
-typedef struct _glitz_format_t {
-  glitz_format_id_t id;
-  
+typedef struct _glitz_color_format_t {
   unsigned short red_size;
   unsigned short green_size;
   unsigned short blue_size;
   unsigned short alpha_size;
-  unsigned short depth_size;
-  unsigned short stencil_size;
-  
-  glitz_bool_t doublebuffer;
-  glitz_drawable_type_t read;
-  glitz_drawable_type_t draw;
-  glitz_multisample_format_t multisample;
-} glitz_format_t;
-
-typedef struct _glitz_surface glitz_surface_t;
-typedef struct _glitz_buffer glitz_buffer_t;
+} glitz_color_format_t;
 
   
 /* glitz_status.c */
   
 typedef enum {
-    GLITZ_STATUS_SUCCESS = 0,
-    GLITZ_STATUS_NO_MEMORY,
-    GLITZ_STATUS_BAD_COORDINATE,
-    GLITZ_STATUS_NOT_SUPPORTED,
-    GLITZ_STATUS_CONTENT_DESTROYED
+  GLITZ_STATUS_SUCCESS = 0,
+  GLITZ_STATUS_NO_MEMORY,
+  GLITZ_STATUS_BAD_COORDINATE,
+  GLITZ_STATUS_NOT_SUPPORTED,
+  GLITZ_STATUS_CONTENT_DESTROYED
 } glitz_status_t;
 
 const char *
 glitz_status_string (glitz_status_t status);
 
+
+/* glitz_drawable.c */
+
+typedef struct _glitz_drawable glitz_drawable_t;
+
+typedef enum {
+  GLITZ_DRAWABLE_BUFFER_FRONT_COLOR,
+  GLITZ_DRAWABLE_BUFFER_BACK_COLOR
+} glitz_drawable_buffer_t;
+    
+#define GLITZ_FORMAT_DEPTH_SIZE_MASK   (1L <<  5)
+#define GLITZ_FORMAT_STENCIL_SIZE_MASK (1L <<  6)
+#define GLITZ_FORMAT_DOUBLEBUFFER_MASK (1L <<  7)
+#define GLITZ_FORMAT_SAMPLES_MASK      (1L <<  8)
+#define GLITZ_FORMAT_WINDOW_MASK       (1L <<  9)
+#define GLITZ_FORMAT_PBUFFER_MASK      (1L << 10)
+    
+typedef struct _glitz_drawable_types_t {
+  glitz_bool_t window;
+  glitz_bool_t pbuffer;
+} glitz_drawable_types_t;
+
+typedef struct _glitz_drawable_format_t {
+  glitz_format_id_t      id;
+  glitz_color_format_t   color;
+  unsigned short         depth_size;
+  unsigned short         stencil_size;
+  unsigned short         samples;
+  glitz_bool_t           doublebuffer;
+  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,
+                                    const glitz_drawable_format_t *templ,
+                                    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);
+
+void
+glitz_drawable_destroy (glitz_drawable_t *drawable);
+
+void
+glitz_drawable_reference (glitz_drawable_t *drawable);
+
+void
+glitz_drawable_update_size (glitz_drawable_t *drawable,
+                            unsigned int     width,
+                            unsigned int     height);
+
+unsigned int
+glitz_drawable_get_width (glitz_drawable_t *drawable);
+
+unsigned int
+glitz_drawable_get_height (glitz_drawable_t *drawable);
+
+void
+glitz_drawable_swap_buffers (glitz_drawable_t *drawable);
+
+void
+glitz_drawable_flush (glitz_drawable_t *drawable);
+
+void
+glitz_drawable_finish (glitz_drawable_t *drawable);
+
+unsigned long
+glitz_drawable_get_features (glitz_drawable_t *drawable);
+
+glitz_drawable_format_t *
+glitz_drawable_get_format (glitz_drawable_t *drawable);
+
   
+/* glitz_format.c */
+
+#define GLITZ_FORMAT_TYPE_MASK (1L << 5)
+
+typedef enum {
+  GLITZ_FORMAT_TYPE_COLOR
+} glitz_format_type_t;
+    
+typedef struct _glitz_format_t {
+  glitz_format_id_t    id;
+  glitz_format_type_t  type;
+  glitz_color_format_t color;
+} glitz_format_t;
+
+glitz_format_t *
+glitz_find_standard_format (glitz_drawable_t    *drawable,
+                            glitz_format_name_t format_name);
+
+glitz_format_t *
+glitz_find_format (glitz_drawable_t     *drawable,
+                   unsigned long        mask,
+                   const glitz_format_t *templ,
+                   int                  count);
+
+
 /* glitz_surface.c */
 
+typedef struct _glitz_surface glitz_surface_t;
+  
+glitz_surface_t *
+glitz_surface_create (glitz_drawable_t *drawable,
+                      glitz_format_t   *format,
+                      unsigned int     width,
+                      unsigned int     height);
+
 void
 glitz_surface_destroy (glitz_surface_t *surface);
 
@@ -187,7 +271,26 @@
 glitz_surface_reference (glitz_surface_t *surface);
 
 void
-glitz_surface_set_transform (glitz_surface_t *surface,
+glitz_surface_attach (glitz_surface_t         *surface,
+                      glitz_drawable_t        *drawable,
+                      glitz_drawable_buffer_t buffer,
+                      int                     x,
+                      int                     y);
+
+void
+glitz_surface_detach (glitz_surface_t *surface);
+
+void
+glitz_surface_flush (glitz_surface_t *surface);
+
+glitz_drawable_t *
+glitz_surface_get_drawable (glitz_surface_t *surface);
+
+glitz_drawable_t *
+glitz_surface_get_attached_drawable (glitz_surface_t *surface);
+
+void
+glitz_surface_set_transform (glitz_surface_t   *surface,
                              glitz_transform_t *transform);
 
 typedef enum {
@@ -199,91 +302,56 @@
 
 void
 glitz_surface_set_fill (glitz_surface_t *surface,
-                        glitz_fill_t fill);
+                        glitz_fill_t    fill);
 
 void
 glitz_surface_set_component_alpha (glitz_surface_t *surface,
-                                   glitz_bool_t component_alpha);
+                                   glitz_bool_t    component_alpha);
 
 void
-glitz_surface_set_filter (glitz_surface_t *surface,
-                          glitz_filter_t filter,
+glitz_surface_set_filter (glitz_surface_t    *surface,
+                          glitz_filter_t     filter,
                           glitz_fixed16_16_t *params,
-                          int n_params);  
-
-typedef enum {
-  GLITZ_COLOR_BUFFER_FRONT,
-  GLITZ_COLOR_BUFFER_BACK
-} glitz_color_buffer_t;
-
-void
-glitz_surface_set_read_color_buffer (glitz_surface_t *surface,
-                                     glitz_color_buffer_t buffer);
-
-void
-glitz_surface_set_draw_color_buffer (glitz_surface_t *surface,
-                                     glitz_color_buffer_t buffer);
-  
-void
-glitz_surface_swap_buffers (glitz_surface_t *surface);
-
-void
-glitz_surface_flush (glitz_surface_t *surface);
+                          int                n_params);
 
 void
-glitz_surface_finish (glitz_surface_t *surface);
+glitz_surface_set_dither (glitz_surface_t *surface,
+                          glitz_bool_t    dither);
 
-int
+unsigned int
 glitz_surface_get_width (glitz_surface_t *surface);
 
-int
+unsigned int
 glitz_surface_get_height (glitz_surface_t *surface);
 
 glitz_status_t
 glitz_surface_get_status (glitz_surface_t *surface);
 
-unsigned long
-glitz_surface_get_features (glitz_surface_t *surface);
-
 glitz_format_t *
 glitz_surface_get_format (glitz_surface_t *surface);
 
-glitz_format_t *
-glitz_surface_find_similar_standard_format (glitz_surface_t *surface,
-                                            glitz_format_name_t format_name);
-
-glitz_format_t *
-glitz_surface_find_similar_format (glitz_surface_t *surface,
-                                   unsigned long mask,
-                                   const glitz_format_t *templ,
-                                   int count);
-
-glitz_surface_t *
-glitz_surface_create_similar (glitz_surface_t *templ,
-                              glitz_format_t *format,
-                              int width,
-                              int height);
-
   
 /* glitz_rect.c */
 
 void
-glitz_set_rectangle (glitz_surface_t *dst,
+glitz_set_rectangle (glitz_surface_t     *dst,
                      const glitz_color_t *color,
-                     int x,
-                     int y,
-                     unsigned int width,
-                     unsigned int height);
+                     int                 x,
+                     int                 y,
+                     unsigned int        width,
+                     unsigned int        height);
   
 void
-glitz_set_rectangles (glitz_surface_t *dst,
-                      const glitz_color_t *color,
+glitz_set_rectangles (glitz_surface_t         *dst,
+                      const glitz_color_t     *color,
                       const glitz_rectangle_t *rects,
-                      int n_rects);
+                      int                     n_rects);
 
 
 /* glitz_buffer.c */
-  
+
+typedef struct _glitz_buffer glitz_buffer_t;
+    
 typedef enum {
   GLITZ_BUFFER_HINT_STREAM_DRAW,
   GLITZ_BUFFER_HINT_STREAM_READ,
@@ -303,15 +371,15 @@
 } glitz_buffer_access_t;
 
 glitz_buffer_t *
-glitz_geometry_buffer_create (glitz_surface_t *surface,
-                              void *data,
-                              unsigned int size,
+glitz_geometry_buffer_create (glitz_drawable_t    *drawable,
+                              void                *data,
+                              unsigned int        size,
                               glitz_buffer_hint_t hint);
 
 glitz_buffer_t *
-glitz_pixel_buffer_create (glitz_surface_t *surface,
-                           void *data,
-                           unsigned int size,
+glitz_pixel_buffer_create (glitz_drawable_t    *drawable,
+                           void                *data,
+                           unsigned int        size,
                            glitz_buffer_hint_t hint);
 
 glitz_buffer_t *
@@ -325,18 +393,18 @@
 
 void
 glitz_buffer_set_data (glitz_buffer_t *buffer,
-                       int offset,
-                       unsigned int size,
-                       const void *data);
+                       int            offset,
+                       unsigned int   size,
+                       const void     *data);
 
 void
 glitz_buffer_get_data (glitz_buffer_t *buffer,
-                       int offset,
-                       unsigned int size,
-                       void *data);
+                       int            offset,
+                       unsigned int   size,
+                       void           *data);
        
 void *
-glitz_buffer_map (glitz_buffer_t *buffer,
+glitz_buffer_map (glitz_buffer_t        *buffer,
                   glitz_buffer_access_t access);
   
 glitz_status_t
@@ -351,7 +419,7 @@
 } glitz_pixel_scanline_order_t;
 
 typedef struct _glitz_pixel_masks {
-  int bpp;
+  int           bpp;
   unsigned long alpha_mask;
   unsigned long red_mask;
   unsigned long green_mask;
@@ -359,30 +427,30 @@
 } glitz_pixel_masks_t;
 
 typedef struct _glitz_pixel_format {
-  glitz_pixel_masks_t masks;
-  int xoffset;
-  int skip_lines;
-  int bytes_per_line;
+  glitz_pixel_masks_t          masks;
+  int                          xoffset;
+  int                          skip_lines;
+  int                          bytes_per_line;
   glitz_pixel_scanline_order_t scanline_order;
 } glitz_pixel_format_t;
 
 void
-glitz_set_pixels (glitz_surface_t *dst,
-                  int x_dst,
-                  int y_dst,
-                  int width,
-                  int height,
+glitz_set_pixels (glitz_surface_t      *dst,
+                  int                  x_dst,
+                  int                  y_dst,
+                  int                  width,
+                  int                  height,
                   glitz_pixel_format_t *format,
-                  glitz_buffer_t *buffer);                
+                  glitz_buffer_t       *buffer);                
 
 void
-glitz_get_pixels (glitz_surface_t *src,
-                  int x_src,
-                  int y_src,
-                  int width,
-                  int height,
+glitz_get_pixels (glitz_surface_t      *src,
+                  int                  x_src,
+                  int                  y_src,
+                  int                  width,
+                  int                  height,
                   glitz_pixel_format_t *format,
-                  glitz_buffer_t *buffer);
+                  glitz_buffer_t       *buffer);
   
   
 /* glitz_geometry.c */
@@ -400,6 +468,10 @@
 } glitz_geometry_edge_hint_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,
@@ -416,47 +488,47 @@
 } glitz_data_type_t;
 
 typedef struct _glitz_geometry_format {
-  glitz_geometry_mode_t mode;
+  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;
+  glitz_data_type_t          type;
+  int                        first;
+  unsigned int               count;
 } glitz_geometry_format_t;
 
 void
-glitz_set_geometry (glitz_surface_t *dst,
-                    int x_dst,
-                    int y_dst,
+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_buffer_t          *buffer);
   
 
 /* glitz.c */
 
 void
 glitz_composite (glitz_operator_t op,
-                 glitz_surface_t *src,
-                 glitz_surface_t *mask,
-                 glitz_surface_t *dst,
-                 int x_src,
-                 int y_src,
-                 int x_mask,
-                 int y_mask,
-                 int x_dst,
-                 int y_dst,
-                 int width,
-                 int height);
+                 glitz_surface_t  *src,
+                 glitz_surface_t  *mask,
+                 glitz_surface_t  *dst,
+                 int              x_src,
+                 int              y_src,
+                 int              x_mask,
+                 int              y_mask,
+                 int              x_dst,
+                 int              y_dst,
+                 int              width,
+                 int              height);
 
 void
 glitz_copy_area (glitz_surface_t *src,
                  glitz_surface_t *dst,
-                 int x_src,
-                 int y_src,
-                 int width,
-                 int height,
-                 int x_dst,
-                 int y_dst);
+                 int             x_src,
+                 int             y_src,
+                 int             width,
+                 int             height,
+                 int             x_dst,
+                 int             y_dst);
   
 #if defined(__cplusplus) || defined(c_plusplus)
 }

--- NEW FILE: glitz.pc.in ---
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@

Name: libglitz
Description: OpenGL compositing library
Version: @VERSION@
Libs: -L${libdir} -lglitz -lm
Cflags: -I${includedir}

--- glitz_agl_context.c DELETED ---

--- glitz_agl_extension.c DELETED ---

--- glitz_agl_format.c DELETED ---

--- glitz_agl_info.c DELETED ---

--- glitz_agl_pbuffer.c DELETED ---

--- glitz_agl_surface.c DELETED ---

--- glitz_aglint.h DELETED ---

Index: glitz_buffer.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_buffer.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- glitz_buffer.c	4 Oct 2004 11:40:48 -0000	1.4
+++ glitz_buffer.c	3 Nov 2004 22:50:58 -0000	1.5
@@ -30,17 +30,17 @@
 #include "glitzint.h"
 
 static glitz_status_t
-_glitz_buffer_init (glitz_buffer_t *buffer,
-                    glitz_surface_t *surface,
-                    void *data,
-                    unsigned int size,
+_glitz_buffer_init (glitz_buffer_t      *buffer,
+                    glitz_drawable_t    *drawable,
+                    void                *data,
+                    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;
@@ -71,21 +71,26 @@
     break;
   }
   
-  if (surface) {
-    buffer->surface = surface;
-    glitz_surface_reference (surface);
+  if (drawable) {
 
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+    GLITZ_GL_DRAWABLE (drawable);
+    
+    buffer->drawable = drawable;
+    glitz_drawable_reference (drawable);
 
-    surface->backend->gl.gen_buffers (1, &buffer->name);
+    drawable->backend->push_current (drawable, NULL,
+                                     GLITZ_ANY_CONTEXT_CURRENT);
+
+    gl->gen_buffers (1, &buffer->name);
     if (buffer->name) {
-      surface->backend->gl.bind_buffer (buffer->target, buffer->name);
-      surface->backend->gl.buffer_data (buffer->target, size, data, usage);
-      surface->backend->gl.bind_buffer (buffer->target, 0);
+      gl->bind_buffer (buffer->target, buffer->name);
+      gl->buffer_data (buffer->target, size, data, usage);
+      gl->bind_buffer (buffer->target, 0);
     }
-    glitz_surface_pop_current (buffer->surface);
+    
+    drawable->backend->pop_current (drawable);
   } else
-    buffer->surface = NULL;
+    buffer->drawable = NULL;
   
   if (size > 0 && buffer->name == 0) {
     buffer->data = malloc (size);
@@ -105,9 +110,9 @@
 }
 
 glitz_buffer_t *
-glitz_geometry_buffer_create (glitz_surface_t *surface,
-                              void *data,
-                              unsigned int size,
+glitz_geometry_buffer_create (glitz_drawable_t    *drawable,
+                              void                *data,
+                              unsigned int        size,
                               glitz_buffer_hint_t hint)
 {
   glitz_buffer_t *buffer;
@@ -116,14 +121,15 @@
   if (size == 0)
     return NULL;
 
-  buffer = malloc (sizeof (glitz_buffer_t));
+  buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
   if (buffer == NULL)
     return NULL;
   
   buffer->target = GLITZ_GL_ARRAY_BUFFER;
-
-  if (surface->backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)
-    status = _glitz_buffer_init (buffer, surface, data, size, hint);
+  
+  if (drawable->backend->feature_mask &
+      GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK)
+    status = _glitz_buffer_init (buffer, drawable, data, size, hint);
   else
     status = _glitz_buffer_init (buffer, NULL, data, size, hint);
   
@@ -136,9 +142,9 @@
 }
 
 glitz_buffer_t *
-glitz_pixel_buffer_create (glitz_surface_t *surface,
-                           void *data,
-                           unsigned int size,
+glitz_pixel_buffer_create (glitz_drawable_t    *drawable,
+                           void                *data,
+                           unsigned int        size,
                            glitz_buffer_hint_t hint)
 {
   glitz_buffer_t *buffer;
@@ -147,7 +153,7 @@
   if (size == 0)
     return NULL;
   
-  buffer = malloc (sizeof (glitz_buffer_t));
+  buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
   if (buffer == NULL)
     return NULL;
   
@@ -162,8 +168,8 @@
     break;
   }
 
-  if (surface->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
-    status = _glitz_buffer_init (buffer, surface, data, size, hint);
+  if (drawable->backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)
+    status = _glitz_buffer_init (buffer, drawable, data, size, hint);
   else
     status = _glitz_buffer_init (buffer, NULL, data, size, hint);
 
@@ -183,7 +189,7 @@
   if (data == NULL)
     return NULL;
   
-  buffer = malloc (sizeof (glitz_buffer_t));
+  buffer = (glitz_buffer_t *) malloc (sizeof (glitz_buffer_t));
   if (buffer == NULL)
     return NULL;
 
@@ -205,11 +211,12 @@
   if (buffer->ref_count)
     return;
   
-  if (buffer->surface) {
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
-    buffer->surface->backend->gl.delete_buffers (1, &buffer->name);
-    glitz_surface_pop_current (buffer->surface);
-    glitz_surface_destroy (buffer->surface);
+  if (buffer->drawable) {
+    buffer->drawable->backend->push_current (buffer->drawable, NULL,
+                                             GLITZ_ANY_CONTEXT_CURRENT);
+    buffer->drawable->backend->gl.delete_buffers (1, &buffer->name);
+    buffer->drawable->backend->pop_current (buffer->drawable);
+    glitz_drawable_destroy (buffer->drawable);
   } else if (buffer->owns_data)
     free (buffer->data);
   
@@ -227,19 +234,19 @@
 
 void
 glitz_buffer_set_data (glitz_buffer_t *buffer,
-                       int offset,
-                       unsigned int size,
-                       const void *data)
+                       int            offset,
+                       unsigned int   size,
+                       const void     *data)
 {
-  if (buffer->surface) {
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
-    
-    buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name);
-    buffer->surface->backend->gl.buffer_sub_data (buffer->target,
-                                                  offset, size, data);
-    buffer->surface->backend->gl.bind_buffer (buffer->target, 0);
+  if (buffer->drawable) {
+    GLITZ_GL_DRAWABLE (buffer->drawable);
     
-    glitz_surface_pop_current (buffer->surface);
+    buffer->drawable->backend->push_current (buffer->drawable, NULL,
+                                             GLITZ_ANY_CONTEXT_CURRENT);
+    gl->bind_buffer (buffer->target, buffer->name);
+    gl->buffer_sub_data (buffer->target, offset, size, data);
+    gl->bind_buffer (buffer->target, 0);
+    buffer->drawable->backend->pop_current (buffer->drawable);
   } else if (buffer->data)
     memcpy ((char *) buffer->data + offset, data, size);
 }
@@ -247,34 +254,39 @@
 
 void
 glitz_buffer_get_data (glitz_buffer_t *buffer,
-                       int offset,
-                       unsigned int size,
-                       void *data)
+                       int            offset,
+                       unsigned int   size,
+                       void           *data)
 {
-  if (buffer->surface) {
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+  if (buffer->drawable) {
+    GLITZ_GL_DRAWABLE (buffer->drawable);
     
-    buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name);
-    buffer->surface->backend->gl.get_buffer_sub_data (buffer->target,
-                                                      offset, size, data);
-    buffer->surface->backend->gl.bind_buffer (buffer->target, 0);
+    buffer->drawable->backend->push_current (buffer->drawable, NULL,
+                                             GLITZ_ANY_CONTEXT_CURRENT);
     
-    glitz_surface_pop_current (buffer->surface);
+    gl->bind_buffer (buffer->target, buffer->name);
+    gl->get_buffer_sub_data (buffer->target, offset, size, data);
+    gl->bind_buffer (buffer->target, 0);
+
+    buffer->drawable->backend->pop_current (buffer->drawable);
   } else if (buffer->data)
     memcpy (data, (char *) buffer->data + offset, size);
 }
 slim_hidden_def(glitz_buffer_get_data);
 
 void *
-glitz_buffer_map (glitz_buffer_t *buffer,
+glitz_buffer_map (glitz_buffer_t        *buffer,
                   glitz_buffer_access_t access)
 {
   void *pointer = NULL;
   
-  if (buffer->surface) {
+  if (buffer->drawable) {
     glitz_gl_enum_t buffer_access;
-    
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+
+    GLITZ_GL_DRAWABLE (buffer->drawable);
+
+    buffer->drawable->backend->push_current (buffer->drawable, NULL,
+                                             GLITZ_ANY_CONTEXT_CURRENT);
     
     switch (access) {
     case GLITZ_BUFFER_ACCESS_READ_ONLY:
@@ -288,11 +300,10 @@
       break;
     }
 
-    buffer->surface->backend->gl.bind_buffer (buffer->target, buffer->name);
-    pointer = buffer->surface->backend->gl.map_buffer (buffer->target,
-                                                       buffer_access);
+    gl->bind_buffer (buffer->target, buffer->name);
+    pointer = gl->map_buffer (buffer->target, buffer_access);
     
-    glitz_surface_pop_current (buffer->surface);
+    buffer->drawable->backend->pop_current (buffer->drawable);
   }
   
   if (pointer == NULL)
@@ -306,16 +317,18 @@
 {
   glitz_status_t status = GLITZ_STATUS_SUCCESS;
   
-  if (buffer->surface) {
-    glitz_surface_push_current (buffer->surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
+  if (buffer->drawable) {
+    GLITZ_GL_DRAWABLE (buffer->drawable);
     
-    if (buffer->surface->backend->gl.unmap_buffer (buffer->target) ==
-        GLITZ_GL_FALSE)
+    buffer->drawable->backend->push_current (buffer->drawable, NULL,
+                                             GLITZ_ANY_CONTEXT_CURRENT);
+    
+    if (gl->unmap_buffer (buffer->target) == GLITZ_GL_FALSE)
       status = GLITZ_STATUS_CONTENT_DESTROYED;
       
-    buffer->surface->backend->gl.bind_buffer (buffer->target, 0);
-    
-    glitz_surface_pop_current (buffer->surface);
+    gl->bind_buffer (buffer->target, 0);
+
+    buffer->drawable->backend->pop_current (buffer->drawable);
   }
 
   return status;
@@ -325,8 +338,8 @@
 glitz_buffer_bind (glitz_buffer_t *buffer,
                    glitz_gl_enum_t target)
 {
-  if (buffer->surface) {
-    buffer->surface->backend->gl.bind_buffer (target, buffer->name);
+  if (buffer->drawable) {
+    buffer->drawable->backend->gl.bind_buffer (target, buffer->name);
     buffer->target = target;
     
     return NULL;
@@ -338,6 +351,6 @@
 void
 glitz_buffer_unbind (glitz_buffer_t *buffer)
 {
-  if (buffer->surface)
-    buffer->surface->backend->gl.bind_buffer (buffer->target, 0);
+  if (buffer->drawable)
+    buffer->drawable->backend->gl.bind_buffer (buffer->target, 0);
 }

Index: glitz_compose.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_compose.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- glitz_compose.c	4 Oct 2004 11:40:48 -0000	1.9
+++ glitz_compose.c	3 Nov 2004 22:50:58 -0000	1.10
@@ -449,12 +449,13 @@
   glitz_surface_type_t src_type;
   glitz_surface_type_t mask_type;
   glitz_combine_t *combine;
+  unsigned long feature_mask;
 
   op->render_op = render_op;
   op->type = GLITZ_COMBINE_TYPE_NA;
   op->combine = NULL;
   op->alpha_mask = _default_alpha_mask;
-  op->gl = &dst->backend->gl;
+  op->gl = &dst->drawable->backend->gl;
   op->src = src;
   op->mask = mask;
   op->dst = dst;
@@ -463,14 +464,16 @@
   op->per_component = 0;
   op->fp = 0;
 
-  if (dst->indirect && (dst->format->stencil_size < 1))
+  feature_mask = dst->attached->backend->feature_mask;
+
+  if (dst->indirect && (dst->attached->format->stencil_size < 1))
     return;
   
-  src_type = _glitz_get_surface_type (src, dst->backend->feature_mask);
+  src_type = _glitz_get_surface_type (src, feature_mask);
   if (src_type < 1)
     return;
 
-  mask_type = _glitz_get_surface_type (mask, dst->backend->feature_mask);
+  mask_type = _glitz_get_surface_type (mask, feature_mask);
   if (mask_type < 0)
     return;
 
@@ -488,62 +491,51 @@
     src_type = GLITZ_SURFACE_TYPE_ARGB;
     
   combine = &_glitz_combine_map[src_type][mask_type];
-  if (combine->type == GLITZ_COMBINE_TYPE_NA) {
-    op->type = GLITZ_COMBINE_TYPE_INTERMEDIATE;
-    
+  if (!combine->type)
     return;
-  } 
   
   if (src_type == GLITZ_SURFACE_TYPE_SOLID) {
-    glitz_surface_ensure_solid (src);
+    glitz_surface_sync_solid (src);
     op->solid = &src->solid;
     op->src = NULL;
   }
   
   if (mask_type == GLITZ_SURFACE_TYPE_SOLID) {
-    glitz_surface_ensure_solid (mask);
+    glitz_surface_sync_solid (mask);
     op->alpha_mask = mask->solid;
     op->mask = NULL;
     op->combine = combine;
   } else if (mask_type == GLITZ_SURFACE_TYPE_SOLIDC) {
-    glitz_surface_ensure_solid (mask);
+    glitz_surface_sync_solid (mask);
     op->alpha_mask = mask->solid;
     op->mask = NULL;
     
     if (op->src) {
       op->per_component = 4;
       op->combine = combine;
-    } else if (dst->backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
+    } 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 (dst->backend->feature_mask &
-            GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
+        if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
           op->combine = combine;
-      } else if (dst->backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
+      } else if (feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK)
         op->combine = combine;
-    } else if (dst->backend->feature_mask &
-               GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
+    } else if (feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK)
       op->combine = combine;
   } else
     op->combine = combine;
 
-  if (!(dst->backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) {
-    if (op->src && op->mask) {
-      if (!op->per_component) {
-        op->type = GLITZ_COMBINE_TYPE_INTERMEDIATE;
-        return;
-      } else
-        op->combine = NULL;
-    }
+  if (!(feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK)) {
+    if (op->src && op->mask)
+      op->combine = NULL;
   }
 
   if (op->per_component &&
-      (!(dst->backend->feature_mask &
-         GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK)))
+      (!(feature_mask & GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK)))
     op->combine = NULL;
   
   if (op->combine == combine) {

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

Index: glitz_format.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_format.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- glitz_format.c	9 Sep 2004 09:50:26 -0000	1.8
+++ glitz_format.c	3 Nov 2004 22:50:58 -0000	1.9
@@ -1,28 +1,26 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * 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
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * 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
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
  *
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
- *          Peter Nilsson <c99pnn at cs.umu.se>
+ * Author: David Reveman <c99drn at cs.umu.se>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -33,87 +31,115 @@
 
 #include <stdlib.h>
 
-static glitz_format_t _texture_formats[] = {
-  {
-    GLITZ_GL_ALPHA4, 0, 0, 0, 4, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_ALPHA8, 0, 0, 0, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_ALPHA12, 0, 0, 0, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_ALPHA16, 0, 0, 0, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_R3_G3_B2, 3, 3, 2, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB4, 4, 4, 4, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB5, 5, 5, 5, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB8, 8, 8, 8, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB10, 10, 10, 10, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB12, 12, 12, 12, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB16, 16, 16, 16, 0, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGBA2, 2, 2, 2, 2, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB5_A1, 5, 5, 5, 1, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGBA8, 8, 8, 8, 8, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGB10_A2, 10, 10, 10, 2, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGBA12, 12, 12, 12, 12, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }, {
-    GLITZ_GL_RGBA16, 16, 16, 16, 16, 0, 0, 0, { 0, 1 }, { 0, 0 }, { 0, 0 }
-  }
+struct _texture_format {
+  glitz_gl_int_t texture_format;
+  glitz_format_t format;
+} _texture_formats[] = {
+  { GLITZ_GL_ALPHA4,   { 0, GLITZ_FORMAT_TYPE_COLOR, {  0,  0,  0,  4 } } },
+  { GLITZ_GL_ALPHA8,   { 0, GLITZ_FORMAT_TYPE_COLOR, {  0,  0,  0,  8 } } },
+  { GLITZ_GL_ALPHA12,  { 0, GLITZ_FORMAT_TYPE_COLOR, {  0,  0,  0, 12 } } },
+  { GLITZ_GL_ALPHA16,  { 0, GLITZ_FORMAT_TYPE_COLOR, {  0,  0,  0, 16 } } },
+  { GLITZ_GL_R3_G3_B2, { 0, GLITZ_FORMAT_TYPE_COLOR, {  3,  3,  2,  0 } } },
+  { GLITZ_GL_RGB4,     { 0, GLITZ_FORMAT_TYPE_COLOR, {  4,  4,  4,  0 } } },
+  { GLITZ_GL_RGB5,     { 0, GLITZ_FORMAT_TYPE_COLOR, {  5,  6,  5,  0 } } },
+  { GLITZ_GL_RGB8,     { 0, GLITZ_FORMAT_TYPE_COLOR, {  8,  8,  8,  0 } } },
+  { GLITZ_GL_RGB10,    { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10,  0 } } },
+  { GLITZ_GL_RGB12,    { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12,  0 } } },
+  { GLITZ_GL_RGB16,    { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16,  0 } } },
+  { GLITZ_GL_RGBA2,    { 0, GLITZ_FORMAT_TYPE_COLOR, {  2,  2,  2,  2 } } },
+  { GLITZ_GL_RGB5_A1,  { 0, GLITZ_FORMAT_TYPE_COLOR, {  5,  5,  5,  1 } } },
+  { GLITZ_GL_RGBA4,    { 0, GLITZ_FORMAT_TYPE_COLOR, {  4,  4,  4,  4 } } },
+  { GLITZ_GL_RGBA8,    { 0, GLITZ_FORMAT_TYPE_COLOR, {  8,  8,  8,  8 } } },
+  { GLITZ_GL_RGB10_A2, { 0, GLITZ_FORMAT_TYPE_COLOR, { 10, 10, 10,  2 } } },
+  { GLITZ_GL_RGBA12,   { 0, GLITZ_FORMAT_TYPE_COLOR, { 12, 12, 12, 12 } } },
+  { GLITZ_GL_RGBA16,   { 0, GLITZ_FORMAT_TYPE_COLOR, { 16, 16, 16, 16 } } }
 };
 
+static void
+_glitz_add_texture_format (glitz_format_t **formats,
+                           glitz_gl_int_t **texture_formats,
+                           int            *n_formats,
+                           glitz_gl_int_t texture_format,
+                           glitz_format_t *format)
+{
+  *formats = realloc (*formats, sizeof (glitz_format_t) * (*n_formats + 1));
+  *texture_formats = realloc (*texture_formats,
+                              sizeof (glitz_gl_enum_t) * (*n_formats + 1));
+
+  if (*formats && *texture_formats) {
+    (*texture_formats)[*n_formats] = texture_format;
+    (*formats)[*n_formats] = *format;
+    (*formats)[*n_formats].id = *n_formats;
+    (*n_formats)++;
+  } else
+    *n_formats = 0;
+}
+
 void
-glitz_format_for_each_texture_format (glitz_format_call_back_t call_back,
-				      glitz_gl_proc_address_list_t *gl,
-                                      void *ptr)
+glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
+                              glitz_format_t               **formats,
+                              glitz_gl_int_t               **texture_formats,
+                              int                          *n_formats)
 {
   glitz_gl_int_t value;
-  int i, n_texture_formats =
-    sizeof (_texture_formats) / sizeof (glitz_format_t);
-
+  int i, n_texture_formats;
+  
+  n_texture_formats =
+    sizeof (_texture_formats) / sizeof (struct _texture_format);
+  
   for (i = 0; i < n_texture_formats; i++) {
     gl->tex_image_2d (GLITZ_GL_PROXY_TEXTURE_2D, 0,
-		      _texture_formats[i].id, 1, 1,
-		      0, GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
-    gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
-				    GLITZ_GL_TEXTURE_RED_SIZE, &value);
-    if (value != _texture_formats[i].red_size)
-      continue;
+                      _texture_formats[i].texture_format, 1, 1, 0,
+                      GLITZ_GL_RGBA, GLITZ_GL_UNSIGNED_BYTE, NULL);
 
-    gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
-				    GLITZ_GL_TEXTURE_GREEN_SIZE, &value);
-    if (value != _texture_formats[i].green_size)
-      continue;
+    switch (_texture_formats[i].format.type) {
+    case GLITZ_FORMAT_TYPE_COLOR:
+      if (_texture_formats[i].format.color.red_size) {
+        gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
+                                        GLITZ_GL_TEXTURE_RED_SIZE, &value);
+        if (value != _texture_formats[i].format.color.red_size)
+          continue;
+      }
+      
+      if (_texture_formats[i].format.color.green_size) {
+        gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
+                                        GLITZ_GL_TEXTURE_GREEN_SIZE, &value);
+        if (value != _texture_formats[i].format.color.green_size)
+          continue;
+      }
 
-    gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
-				    GLITZ_GL_TEXTURE_BLUE_SIZE, &value);
-    if (value != _texture_formats[i].blue_size)
-      continue;
+      if (_texture_formats[i].format.color.blue_size) {
+        gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
+                                        GLITZ_GL_TEXTURE_BLUE_SIZE, &value);
+        if (value != _texture_formats[i].format.color.blue_size)
+          continue;
+      }
 
-    gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
-				    GLITZ_GL_TEXTURE_ALPHA_SIZE, &value);
-    if (value != _texture_formats[i].alpha_size)
+      if (_texture_formats[i].format.color.alpha_size) {
+        gl->get_tex_level_parameter_iv (GLITZ_GL_PROXY_TEXTURE_2D, 0,
+                                        GLITZ_GL_TEXTURE_ALPHA_SIZE, &value);
+        if (value != _texture_formats[i].format.color.alpha_size)
+          continue;
+      }
+      break;
+    default:
       continue;
-
-    call_back (&_texture_formats[i], ptr);
+    }
+    
+    _glitz_add_texture_format (formats,
+                               texture_formats,
+                               n_formats,
+                               _texture_formats[i].texture_format,
+                               &_texture_formats[i].format);
   }
 }
 
-glitz_format_t *
-glitz_format_find (glitz_format_t *formats,
-                   int n_formats,
-                   unsigned long mask,
-                   const glitz_format_t *templ,
-                   int count)
+glitz_drawable_format_t *
+glitz_drawable_format_find (glitz_drawable_format_t       *formats,
+                            int                           n_formats,
+                            unsigned long                 mask,
+                            const glitz_drawable_format_t *templ,
+                            int                           count)
 {
   for (; n_formats; n_formats--, formats++) {
     if (mask & GLITZ_FORMAT_ID_MASK)
@@ -121,19 +147,19 @@
         continue;
 
     if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
-      if (templ->red_size != formats->red_size)
+      if (templ->color.red_size != formats->color.red_size)
         continue;
 
     if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
-      if (templ->green_size != formats->green_size)
+      if (templ->color.green_size != formats->color.green_size)
         continue;
 
     if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
-      if (templ->blue_size != formats->blue_size)
+      if (templ->color.blue_size != formats->color.blue_size)
         continue;
 
     if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
-      if (templ->alpha_size != formats->alpha_size)
+      if (templ->color.alpha_size != formats->color.alpha_size)
         continue;
 
     if (mask & GLITZ_FORMAT_DEPTH_SIZE_MASK)
@@ -148,28 +174,55 @@
       if (templ->doublebuffer != formats->doublebuffer)
         continue;
 
-    if (mask & GLITZ_FORMAT_MULTISAMPLE_MASK)
-      if (templ->multisample.supported != formats->multisample.supported)
+    if (mask & GLITZ_FORMAT_SAMPLES_MASK)
+      if (templ->samples != formats->samples)
         continue;
 
-    if (mask & GLITZ_FORMAT_MULTISAMPLE_SAMPLES_MASK)
-      if (templ->multisample.samples != formats->multisample.samples)
+    if (mask & GLITZ_FORMAT_WINDOW_MASK)
+      if (templ->types.window != formats->types.window)
         continue;
 
-    if (mask & GLITZ_FORMAT_READ_ONSCREEN_MASK)
-      if (templ->read.onscreen != formats->read.onscreen)
+    if (mask & GLITZ_FORMAT_PBUFFER_MASK)
+      if (templ->types.pbuffer != formats->types.pbuffer)
         continue;
     
-    if (mask & GLITZ_FORMAT_READ_OFFSCREEN_MASK)
-      if (templ->read.offscreen != formats->read.offscreen)
+    if (count-- == 0)
+      return formats;    
+  }
+
+  return NULL;
+}
+
+static glitz_format_t *
+_glitz_format_find (glitz_format_t       *formats,
+                    int                  n_formats,
+                    unsigned long        mask,
+                    const glitz_format_t *templ,
+                    int                  count)
+{
+  for (; n_formats; n_formats--, formats++) {
+    if (mask & GLITZ_FORMAT_ID_MASK)
+      if (templ->id != formats->id)
         continue;
 
-    if (mask & GLITZ_FORMAT_DRAW_ONSCREEN_MASK)
-      if (templ->draw.onscreen != formats->draw.onscreen)
+    if (mask & GLITZ_FORMAT_TYPE_MASK)
+      if (templ->type != formats->type)
         continue;
-    
-    if (mask & GLITZ_FORMAT_DRAW_OFFSCREEN_MASK)
-      if (templ->draw.offscreen != formats->draw.offscreen)
+
+    if (mask & GLITZ_FORMAT_RED_SIZE_MASK)
+      if (templ->color.red_size != formats->color.red_size)
+        continue;
+
+    if (mask & GLITZ_FORMAT_GREEN_SIZE_MASK)
+      if (templ->color.green_size != formats->color.green_size)
+        continue;
+
+    if (mask & GLITZ_FORMAT_BLUE_SIZE_MASK)
+      if (templ->color.blue_size != formats->color.blue_size)
+        continue;
+
+    if (mask & GLITZ_FORMAT_ALPHA_SIZE_MASK)
+      if (templ->color.alpha_size != formats->color.alpha_size)
         continue;
 
     if (count-- == 0)
@@ -180,91 +233,53 @@
 }
 
 glitz_format_t *
-glitz_format_find_standard (glitz_format_t *formats,
-                            int n_formats,
+glitz_find_format (glitz_drawable_t     *drawable,
+                   unsigned long        mask,
+                   const glitz_format_t *templ,
+                   int                  count)
+{
+  return _glitz_format_find (drawable->backend->formats,
+                             drawable->backend->n_formats,
+                             mask, templ, count);
+}
+
+glitz_format_t *
+glitz_find_standard_format (glitz_drawable_t    *drawable,
                             glitz_format_name_t format_name)
 {
   glitz_format_t templ;
   unsigned long mask = GLITZ_FORMAT_RED_SIZE_MASK |
     GLITZ_FORMAT_GREEN_SIZE_MASK | GLITZ_FORMAT_BLUE_SIZE_MASK |
-    GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_READ_OFFSCREEN_MASK;
+    GLITZ_FORMAT_ALPHA_SIZE_MASK | GLITZ_FORMAT_TYPE_MASK;
 
-  /* only pick offscreen formats */
-  templ.read.offscreen = 1;
+  templ.type = GLITZ_FORMAT_TYPE_COLOR;
 
   switch (format_name) {
   case GLITZ_STANDARD_ARGB32:
-    templ.red_size = 8;
-    templ.green_size = 8;
-    templ.blue_size = 8;
-    templ.alpha_size = 8;
+    templ.color.red_size = 8;
+    templ.color.green_size = 8;
+    templ.color.blue_size = 8;
+    templ.color.alpha_size = 8;
     break;
   case GLITZ_STANDARD_RGB24:
-    templ.red_size = 8;
-    templ.green_size = 8;
-    templ.blue_size = 8;
-    templ.alpha_size = 0;
+    templ.color.red_size = 8;
+    templ.color.green_size = 8;
+    templ.color.blue_size = 8;
+    templ.color.alpha_size = 0;
     break;
   case GLITZ_STANDARD_A8:
-    templ.red_size = 0;
-    templ.green_size = 0;
-    templ.blue_size = 0;
-    templ.alpha_size = 8;
+    templ.color.red_size = 0;
+    templ.color.green_size = 0;
+    templ.color.blue_size = 0;
+    templ.color.alpha_size = 8;
     break;
   case GLITZ_STANDARD_A1:
-    templ.red_size = 0;
-    templ.green_size = 0;
-    templ.blue_size = 0;
-    templ.alpha_size = 1;
+    templ.color.red_size = 0;
+    templ.color.green_size = 0;
+    templ.color.blue_size = 0;
+    templ.color.alpha_size = 1;
     break;
   }
 
-  return glitz_format_find (formats, n_formats, mask, &templ, 0);
-}
-
-glitz_gl_int_t
-glitz_format_get_best_texture_format (glitz_format_t *formats,
-				      int n_formats,
-				      glitz_format_t *format)
-{
-  glitz_format_t templ;
-  unsigned long mask;
-  glitz_format_t *best_format, *texture_format;
-  int n_texture_formats =
-    sizeof (_texture_formats) / sizeof (glitz_format_t);
-  
-  if (format->draw.offscreen || format->draw.onscreen) {
-    unsigned int i = 0;
-  
-    templ.draw.offscreen = templ.draw.onscreen = 0;
-    templ.read.offscreen = 1;
-    mask = GLITZ_FORMAT_READ_OFFSCREEN_MASK | GLITZ_FORMAT_DRAW_ONSCREEN_MASK |
-      GLITZ_FORMAT_DRAW_OFFSCREEN_MASK;
-    
-    do {
-      best_format = glitz_format_find (formats, n_formats, mask, &templ, i++);
-      if (best_format &&
-          best_format->red_size >= format->red_size &&
-          best_format->green_size >= format->green_size &&
-          best_format->blue_size >= format->blue_size &&
-          best_format->alpha_size >= format->alpha_size)
-        break;
-    } while (best_format);
-    
-    if (!best_format)
-      return GLITZ_GL_RGBA;
-  } else
-    best_format = format;
-
-  mask = GLITZ_FORMAT_RED_SIZE_MASK | GLITZ_FORMAT_GREEN_SIZE_MASK | 
-    GLITZ_FORMAT_BLUE_SIZE_MASK | GLITZ_FORMAT_ALPHA_SIZE_MASK;
-  
-  texture_format =
-    glitz_format_find (_texture_formats, n_texture_formats,
-                       mask, best_format, 0);
-  
-  if (!texture_format)
-    return GLITZ_GL_RGBA;
-
-  return (glitz_gl_int_t) texture_format->id;
+  return glitz_find_format (drawable, mask, &templ, 0);
 }

Index: glitz_geometry.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_geometry.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- glitz_geometry.c	4 Oct 2004 11:40:48 -0000	1.3
+++ glitz_geometry.c	3 Nov 2004 22:50:58 -0000	1.4
@@ -99,25 +99,38 @@
 };
 
 void
-glitz_set_geometry (glitz_surface_t *dst,
-                    int x_dst,
-                    int y_dst,
+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_buffer_t          *buffer)
 {
-  if (dst->geometry.buffer) {
-    glitz_buffer_destroy (dst->geometry.buffer);
-    dst->geometry.buffer = NULL;
-  }
+  glitz_drawable_t *drawable = (dst->attached)? dst->attached: dst->drawable;
 
   if (buffer) {
-    dst->geometry.buffer = buffer;
     glitz_buffer_reference (buffer);
     
-    dst->geometry.x_offset = x_dst;
-    dst->geometry.y_offset = y_dst;
+    if (dst->geometry.buffer)
+      glitz_buffer_destroy (dst->geometry.buffer);
+
+    dst->geometry.buffer = buffer;
+    
+    dst->geometry.x_offset = FIXED_TO_FLOAT (x_dst);
+    dst->geometry.y_offset = FIXED_TO_FLOAT (y_dst);
 
     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;
@@ -156,7 +169,7 @@
     dst->geometry.first = format->first;
     dst->geometry.count = format->count;
 
-    if (dst->format->multisample.samples > 1) {
+    if (drawable->format->samples > 1) {
       if (format->edge_hint != GLITZ_GEOMETRY_EDGE_HINT_SHARP) {
         dst->flags |= GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
 
@@ -164,29 +177,25 @@
           dst->flags |= GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK;
         else
           dst->flags &= ~GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK;
-        
-        dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK;
-      } else {
+      } else
         dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
-        dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK;
-      }
     } else {
       if (format->mode == GLITZ_GEOMETRY_MODE_INDIRECT) {
         switch (format->edge_hint) {
         case GLITZ_GEOMETRY_EDGE_HINT_BEST_SMOOTH:
-          if (dst->format->stencil_size >= 4) {
+          if (drawable->format->stencil_size >= 4) {
             dst->indirect = &_8x_multi_sample;
             break;
           }
           /* fall-through */
         case GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH:
-          if (dst->format->stencil_size >= 3) {
+          if (drawable->format->stencil_size >= 3) {
             dst->indirect = &_4x_multi_sample;
             break;
           }
           /* fall-through */
         case GLITZ_GEOMETRY_EDGE_HINT_FAST_SMOOTH:
-          if (dst->format->stencil_size >= 2) {
+          if (drawable->format->stencil_size >= 2) {
             dst->indirect = &_2x_multi_sample;
             break;
           }
@@ -200,19 +209,20 @@
         dst->indirect = NULL;
     }
   } else {
-    if (dst->format->multisample.samples > 1) {
-      dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
-      dst->update_mask |= GLITZ_UPDATE_MULTISAMPLE_MASK;
-    } else
-      dst->indirect = NULL;
+    if (dst->geometry.buffer)
+      glitz_buffer_destroy (dst->geometry.buffer);
+
+    dst->geometry.buffer = NULL;
+    dst->flags &= ~GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK;
+    dst->indirect = NULL;
   }
 }
 slim_hidden_def(glitz_set_geometry);
 
 void
 glitz_geometry_enable_default (glitz_gl_proc_address_list_t *gl,
-                               glitz_surface_t *dst,
-                               glitz_bounding_box_t *box)
+                               glitz_surface_t              *dst,
+                               glitz_box_t                  *box)
 {
   dst->geometry.data[0] = box->x1;
   dst->geometry.data[1] = box->y1;
@@ -228,11 +238,11 @@
 
 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_bounding_box_t *box)
+                       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;
@@ -257,9 +267,10 @@
 
 void
 glitz_geometry_disable (glitz_gl_proc_address_list_t *gl,
-                        glitz_surface_t *dst)
+                        glitz_surface_t              *dst)
 {
   if (dst->geometry.buffer &&
-      (dst->backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK))
+      (dst->drawable->backend->feature_mask &
+       GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK))
     gl->bind_buffer (GLITZ_GL_ARRAY_BUFFER, 0);
 }

Index: glitz_gl.h
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_gl.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- glitz_gl.h	4 Oct 2004 11:40:48 -0000	1.12
+++ glitz_gl.h	3 Nov 2004 22:50:58 -0000	1.13
@@ -53,6 +53,9 @@
 #define GLITZ_GL_NO_ERROR          0x0
 #define GLITZ_GL_INVALID_OPERATION 0x0502
 
+#define GLITZ_GL_VERSION                     0x1F02
+#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
@@ -75,6 +78,10 @@
 #define GLITZ_GL_FLOAT  0x1406
 #define GLITZ_GL_DOUBLE 0x140A
 
+#define GLITZ_GL_POINTS         0x0000
+#define GLITZ_GL_LINES          0x0001
+#define GLITZ_GL_LINE_LOOP      0x0002
+#define GLITZ_GL_LINE_STRIP     0x0003
 #define GLITZ_GL_TRIANGLES      0x0004
 #define GLITZ_GL_TRIANGLE_STRIP 0x0005
 #define GLITZ_GL_TRIANGLE_FAN   0x0006
@@ -88,6 +95,9 @@
 #define GLITZ_GL_FRONT          0x0404
 #define GLITZ_GL_BACK           0x0405
 #define GLITZ_GL_CULL_FACE      0x0B44
+
+#define GLITZ_GL_POINT_SMOOTH   0x0B10
+#define GLITZ_GL_LINE_SMOOTH    0x0B20
 #define GLITZ_GL_POLYGON_SMOOTH 0x0B41
 
 #define GLITZ_GL_SCISSOR_TEST 0x0C11
@@ -297,6 +307,8 @@
      (glitz_gl_enum_t cap);
 typedef glitz_gl_enum_t (* glitz_gl_get_error_t)
      (glitz_gl_void_t);
+typedef glitz_gl_ubyte_t *(* glitz_gl_get_string_t)
+     (glitz_gl_enum_t);
 typedef glitz_gl_void_t (* glitz_gl_enable_client_state_t)
      (glitz_gl_enum_t cap);
 typedef glitz_gl_void_t (* glitz_gl_disable_client_state_t)

--- glitz_glx_context.c DELETED ---

--- glitz_glx_extension.c DELETED ---

--- glitz_glx_format.c DELETED ---

--- glitz_glx_info.c DELETED ---

--- glitz_glx_pbuffer.c DELETED ---

--- glitz_glx_surface.c DELETED ---

--- glitz_glxext.h DELETED ---

--- glitz_glxint.h DELETED ---

Index: glitz_operator.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_operator.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- glitz_operator.c	3 Sep 2004 14:27:58 -0000	1.5
+++ glitz_operator.c	3 Nov 2004 22:50:58 -0000	1.6
@@ -86,13 +86,5 @@
     gl->enable (GLITZ_GL_BLEND);
     gl->blend_func (GLITZ_GL_ONE, GLITZ_GL_ONE);
     break;
-  case GLITZ_OPERATOR_SATURATE:
-    gl->enable (GLITZ_GL_BLEND);
-    gl->blend_func (GLITZ_GL_SRC_ALPHA_SATURATE, GLITZ_GL_ONE);
-    break;
-  default:
-    gl->enable (GLITZ_GL_BLEND);
-    gl->blend_func (GLITZ_GL_ZERO, GLITZ_GL_ONE);
-    break;
   }
 }

Index: glitz_pixel.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_pixel.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- glitz_pixel.c	20 Oct 2004 23:03:36 -0000	1.12
+++ glitz_pixel.c	3 Nov 2004 22:50:58 -0000	1.13
@@ -31,13 +31,15 @@
 
 #include <string.h>
 
-typedef struct _glitz_gl_pixel_format glitz_gl_pixel_format_t;
-  
-static struct _glitz_gl_pixel_format {
+#include <stdio.h>
+
+typedef struct _glitz_gl_pixel_format {
   glitz_pixel_format_t pixel;
-  glitz_gl_enum_t format;
-  glitz_gl_enum_t type;
-}  _gl_format_map[] = {
+  glitz_gl_enum_t      format;
+  glitz_gl_enum_t      type;
+} glitz_gl_pixel_format_t;
+  
+static glitz_gl_pixel_format_t _gl_pixel_formats[] = {
   {
     {
       {
@@ -55,8 +57,8 @@
   }, {
     {
       {
-        24,
-        0x00000000,
+        32,
+        0xff000000,
         0x00ff0000,
         0x0000ff00,
         0x000000ff
@@ -64,41 +66,41 @@
       0, 0, 0,
       GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
     },
+    GLITZ_GL_BGRA,
     
-#if IMAGE_BYTE_ORDER == MSBFirst
-    GLITZ_GL_RGB,
+#if IMAGE_BYTE_ORDER == MSBFirst  
+    GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV
 #else
-    GLITZ_GL_BGR,
+    GLITZ_GL_UNSIGNED_BYTE
 #endif
     
-    GLITZ_GL_UNSIGNED_BYTE
-  }, {
+  }
+};
+
+static glitz_gl_pixel_format_t _gl_packed_pixel_formats[] = {
+  {
     {
       {
-        32,
-        0xff000000,
-        0x00ff0000,
-        0x0000ff00,
-        0x000000ff
+        16,
+        0x00000000,
+        0x0000f800,
+        0x000007e0,
+        0x0000001f
       },
       0, 0, 0,
       GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP
     },
-    GLITZ_GL_BGRA,
+    GLITZ_GL_BGR,
     
 #if IMAGE_BYTE_ORDER == MSBFirst  
-    GLITZ_GL_UNSIGNED_INT_8_8_8_8_REV
+    GLITZ_GL_UNSIGNED_SHORT_5_6_5_REV
 #else
-    GLITZ_GL_UNSIGNED_BYTE
+    GLITZ_GL_UNSIGNED_SHORT_5_6_5
 #endif
     
   }
 };
 
-#define GLITZ_GL_FORMAT_A    0
-#define GLITZ_GL_FORMAT_RGB  1
-#define GLITZ_GL_FORMAT_ARGB 2
-
 typedef struct _glitz_pixel_color {
   uint32_t r, g, b, a;
 } glitz_pixel_color_t;
@@ -286,10 +288,12 @@
 _glitz_pixel_transform (unsigned long transform,
                         glitz_image_t *src,
                         glitz_image_t *dst,
-                        int x_src,
-                        int x_dst,
-                        int width,
-                        int height)
+                        int           x_src,
+                        int           y_src,
+                        int           x_dst,
+                        int           y_dst,
+                        int           width,
+                        int           height)
 {
   int src_stride, dst_stride;
   int x, y, bytes_per_pixel = 0;
@@ -352,11 +356,11 @@
 
   for (y = 0; y < height; y++) {
     if (src->format->scanline_order != dst->format->scanline_order)
-      src_op.line = &src->data[(src->height - y - 1) * src_stride];
+      src_op.line = &src->data[(src->height - (y + y_src) - 1) * src_stride];
     else
-      src_op.line = &src->data[y * src_stride];
+      src_op.line = &src->data[(y + y_src) * src_stride];
 
-    dst_op.line = &dst->data[y * dst_stride];
+    dst_op.line = &dst->data[(y + y_dst) * dst_stride];
     
     if (transform & GLITZ_TRANSFORM_PIXELS_MASK) {
       for (x = 0; x < width; x++) {
@@ -371,7 +375,7 @@
          it will never be used for bitmaps */
       if (bytes_per_pixel == 0)
         bytes_per_pixel = src->format->masks.bpp / 8;
-      
+
       memcpy (&dst_op.line[x_dst * bytes_per_pixel],
               &src_op.line[x_src * bytes_per_pixel],
               width * bytes_per_pixel);
@@ -379,49 +383,174 @@
   }
 }
 
+static glitz_bool_t
+_glitz_format_match (glitz_pixel_masks_t  *masks1,
+                     glitz_pixel_masks_t  *masks2,
+                     glitz_color_format_t *internal_color)
+{
+  if (masks1->bpp != masks2->bpp)
+    return 0;
+    
+  if (internal_color->red_size)
+    if (masks1->red_mask != masks2->red_mask)
+      return 0;
+
+  if (internal_color->green_size)
+    if (masks1->green_mask != masks2->green_mask)
+      return 0;
+
+  if (internal_color->blue_size)
+    if (masks1->blue_mask != masks2->blue_mask)
+      return 0;
+  
+  if (internal_color->alpha_size)
+    if (masks1->alpha_mask != masks2->alpha_mask)
+      return 0;
+  
+  return 1;
+}
+
 static glitz_gl_pixel_format_t *
-_glitz_find_gl_pixel_format (glitz_pixel_format_t *format)
+_glitz_find_gl_pixel_format (glitz_pixel_format_t *format,
+                             glitz_color_format_t *internal_color,
+                             unsigned long        feature_mask)
 {
   int i, n_formats;
 
-  n_formats = sizeof (_gl_format_map) / sizeof (glitz_gl_pixel_format_t);
+  n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t);
   for (i = 0; i < n_formats; i++) {
-    if (memcmp (&_gl_format_map[i].pixel.masks, &format->masks,
-                sizeof (glitz_pixel_masks_t)) == 0)
-      return &_gl_format_map[i];
+    if (_glitz_format_match (&_gl_pixel_formats[i].pixel.masks, &format->masks,
+                             internal_color))
+      return &_gl_pixel_formats[i];
+  }
+  
+  if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) {
+    n_formats = sizeof (_gl_packed_pixel_formats) /
+      sizeof (glitz_gl_pixel_format_t);
+    
+    for (i = 0; i < n_formats; i++) {
+      if (_glitz_format_match (&_gl_packed_pixel_formats[i].pixel.masks,
+                               &format->masks,
+                               internal_color))
+        return &_gl_packed_pixel_formats[i];
+    }
   }
   
   return NULL;
 }
 
+static int
+_component_size (unsigned long mask)
+{
+  unsigned long y;
+  
+  /* HACKMEM 169 */
+  y = (mask >> 1) & 033333333333;
+  y = mask - y - ((y >> 1) & 033333333333);
+  return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+static glitz_bool_t
+_glitz_format_diff (glitz_pixel_masks_t  *masks,
+                    glitz_color_format_t *pixel_color,
+                    glitz_color_format_t *internal_color,
+                    int                  *diff)
+{
+  int size;
+  
+  *diff = 0;
+
+  size = _component_size (masks->red_mask);
+  if (size < pixel_color->red_size && size < internal_color->red_size)
+    return 0;
+  
+  *diff += abs (size - internal_color->red_size);
+
+  size = _component_size (masks->green_mask);
+  if (size < pixel_color->green_size && size < internal_color->green_size)
+    return 0;
+  
+  *diff += abs (size - internal_color->green_size);
+
+  size = _component_size (masks->blue_mask);
+  if (size < pixel_color->blue_size && size < internal_color->blue_size)
+    return 0;
+  
+  *diff += abs (size - internal_color->blue_size);
+
+  size = _component_size (masks->alpha_mask);
+  if (size < pixel_color->alpha_size && size < internal_color->alpha_size)
+    return 0;
+  
+  *diff += abs (size - internal_color->alpha_size);
+  
+  return 1;
+}
+
 static glitz_gl_pixel_format_t *
-_glitz_best_gl_pixel_format (glitz_format_t *format)
+_glitz_find_best_gl_pixel_format (glitz_pixel_format_t *format,
+                                  glitz_color_format_t *internal_color,
+                                  unsigned long        feature_mask)
 {
-  if (format->red_size) {
-    if (format->alpha_size)
-      return &_gl_format_map[GLITZ_GL_FORMAT_ARGB];
-    else
-      return &_gl_format_map[GLITZ_GL_FORMAT_RGB];
-  } else
-    return &_gl_format_map[GLITZ_GL_FORMAT_A];
+  glitz_gl_pixel_format_t *best = NULL;
+  glitz_color_format_t color;
+  int i, n_formats, diff, best_diff = MAXSHORT;
+
+  color.red_size = _component_size (format->masks.red_mask);
+  color.green_size = _component_size (format->masks.green_mask);
+  color.blue_size = _component_size (format->masks.blue_mask);
+  color.alpha_size = _component_size (format->masks.alpha_mask);
+
+  n_formats = sizeof (_gl_pixel_formats) / sizeof (glitz_gl_pixel_format_t);
+  for (i = 0; best_diff > 0 && i < n_formats; i++) {
+    if (_glitz_format_diff (&_gl_pixel_formats[i].pixel.masks,
+                            &color,
+                            internal_color,
+                            &diff)) {
+      if (diff < best_diff) {
+        best = &_gl_pixel_formats[i];
+        best_diff = diff;
+      }
+    }
+  }
+  
+  if (feature_mask & GLITZ_FEATURE_PACKED_PIXELS_MASK) {
+    n_formats = sizeof (_gl_packed_pixel_formats) /
+      sizeof (glitz_gl_pixel_format_t);
+    
+    for (i = 0; best_diff > 0 && i < n_formats; i++) {
+      if (_glitz_format_diff (&_gl_packed_pixel_formats[i].pixel.masks,
+                              &color,
+                              internal_color,
+                              &diff)) {
+        if (diff < best_diff) {
+          best = &_gl_packed_pixel_formats[i];
+          best_diff = diff;
+        }
+      }
+    }
+  }
+
+  return best;
 }
 
 void
-glitz_set_pixels (glitz_surface_t *dst,
-                  int x_dst,
-                  int y_dst,
-                  int width,
-                  int height,
+glitz_set_pixels (glitz_surface_t      *dst,
+                  int                  x_dst,
+                  int                  y_dst,
+                  int                  width,
+                  int                  height,
                   glitz_pixel_format_t *format,
-                  glitz_buffer_t *buffer)
+                  glitz_buffer_t       *buffer)
 {
-  glitz_gl_proc_address_list_t *gl;
-  glitz_bool_t to_drawable;
   glitz_texture_t *texture;
   char *pixels, *data = NULL;
   glitz_gl_pixel_format_t *gl_format = NULL;
   unsigned long transform = 0;
   int xoffset, bytes_per_line, bpp;
+  glitz_box_t box;
+
+  GLITZ_GL_SURFACE (dst);
 
   if (x_dst < 0 || x_dst > (dst->width - width) ||
       y_dst < 0 || y_dst > (dst->height - height)) {
@@ -429,28 +558,24 @@
     return;
   }
 
-  gl = &dst->backend->gl;
-
-  if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
-    transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
-
   /* find direct format */
-  gl_format = _glitz_find_gl_pixel_format (format);
+  gl_format =
+    _glitz_find_gl_pixel_format (format,
+                                 &dst->format->color,
+                                 dst->drawable->backend->feature_mask);
   if (gl_format == NULL) {
     transform |= GLITZ_TRANSFORM_PIXELS_MASK;
-    gl_format = _glitz_best_gl_pixel_format (dst->format);
+    gl_format =
+      _glitz_find_best_gl_pixel_format (format,
+                                        &dst->format->color,
+                                        dst->drawable->backend->feature_mask);
   }
 
-  if (SURFACE_DRAWABLE (dst))
-    to_drawable = 1;
-  else
-    to_drawable = 0;
-
-  if (to_drawable) {
-    if (!glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT))
-      to_drawable = 0;
-  } else
-    glitz_surface_push_current (dst, GLITZ_CN_ANY_CONTEXT_CURRENT);
+  /* should not happen */
+  if (gl_format == NULL)
+    return;
+  
+  glitz_surface_push_current (dst, GLITZ_ANY_CONTEXT_CURRENT);
 
   texture = glitz_surface_get_texture (dst, 1);
   if (!texture) {
@@ -458,6 +583,11 @@
     return;
   }
 
+  if (height > 1) {
+    if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
+      transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
+  }
+
   glitz_texture_bind (gl, texture);
   
   if (transform) {
@@ -488,8 +618,8 @@
     _glitz_pixel_transform (transform,
                             &src_image,
                             &dst_image,
-                            format->xoffset,
-                            0,
+                            format->xoffset, 0,
+                            0, 0,
                             width, height);
 
     glitz_buffer_unmap (buffer);
@@ -534,42 +664,17 @@
 
   if (transform == 0)
     glitz_buffer_unbind (buffer);
-
-  if (to_drawable) {
-    glitz_bounding_box_t box;
-
-    box.x1 = x_dst;
-    box.y1 = y_dst;
-    box.x2 = box.x1 + width;
-    box.y2 = box.y1 + height;
-    
-    glitz_texture_set_tex_gen (gl, texture, 0, 0, 0); 
-
-    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_set_operator (gl, GLITZ_OPERATOR_SRC);
-
-    gl->scissor (box.x1,
-                 dst->height - box.y2,
-                 width, height);
-
-    glitz_geometry_enable_default (gl, dst, &box);
-
-    gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
-
-    if (x_dst == 0 && y_dst == 0 &&
-        width == dst->width && height == dst->height)
-      dst->flags &= ~GLITZ_SURFACE_FLAG_DIRTY_MASK;
-  }
   
   glitz_texture_unbind (gl, texture);
 
-  dst->flags |= GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK;
+  box.x1 = x_dst;
+  box.y1 = y_dst;
+  box.x2 = box.x1 + width;
+  box.y2 = box.y1 + height;
+
+  glitz_surface_damage (dst, &box,
+                        GLITZ_DAMAGE_DRAWABLE_MASK |
+                        GLITZ_DAMAGE_SOLID_MASK);
   
   glitz_surface_pop_current (dst);
   
@@ -578,15 +683,14 @@
 }
 
 void
-glitz_get_pixels (glitz_surface_t *src,
-                  int x_src,
-                  int y_src,
-                  int width,
-                  int height,
+glitz_get_pixels (glitz_surface_t      *src,
+                  int                  x_src,
+                  int                  y_src,
+                  int                  width,
+                  int                  height,
                   glitz_pixel_format_t *format,
-                  glitz_buffer_t *buffer)
+                  glitz_buffer_t       *buffer)
 {
-  glitz_gl_proc_address_list_t *gl;
   glitz_bool_t from_drawable;
   glitz_texture_t *texture = NULL;
   char *pixels, *data = NULL;
@@ -594,6 +698,9 @@
   unsigned long transform = 0;
   int src_x = 0, src_y = 0, src_w = width, src_h = height;
   int xoffset, bytes_per_line, bpp;
+  glitz_color_format_t *color;
+
+  GLITZ_GL_SURFACE (src);
   
   if (x_src < 0 || x_src > (src->width - width) ||
       y_src < 0 || y_src > (src->height - height)) {
@@ -601,12 +708,12 @@
     return;
   }
 
-  gl = &src->backend->gl;
-
-  if (glitz_surface_push_current (src, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
+  if (glitz_surface_push_current (src, GLITZ_DRAWABLE_CURRENT)) {
     from_drawable = 1;
+    color = &src->attached->format->color;
   } else {
     from_drawable = 0;
+    color = &src->format->color;
     
     texture = glitz_surface_get_texture (src, 0);
     if (!texture) {
@@ -614,17 +721,31 @@
       return;
     }
 
-    transform |= GLITZ_TRANSFORM_COPY_BOX_MASK;
+    if (texture->width > width || texture->height > height)
+      transform |= GLITZ_TRANSFORM_COPY_BOX_MASK;
   }
   
-  if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
-    transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
-  
+  if (transform || height > 1) {
+    if (format->scanline_order == GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN)
+      transform |= GLITZ_TRANSFORM_SCANLINE_ORDER_MASK;
+  }
+
   /* find direct format */
-  gl_format = _glitz_find_gl_pixel_format (format);
+  gl_format =
+    _glitz_find_gl_pixel_format (format, color,
+                                 src->drawable->backend->feature_mask);
   if (gl_format == NULL) {
     transform |= GLITZ_TRANSFORM_PIXELS_MASK;
-    gl_format = _glitz_best_gl_pixel_format (src->format);
+    
+    gl_format =
+      _glitz_find_best_gl_pixel_format (format, color,
+                                        src->drawable->backend->feature_mask);
+  }
+
+  /* should not happen */
+  if (gl_format == NULL) {
+    glitz_surface_pop_current (src);
+    return;
   }
   
   if (transform) {
@@ -675,21 +796,18 @@
     gl->pixel_store_i (GLITZ_GL_PACK_ROW_LENGTH, 0);
   }
 
-  if (from_drawable) {
-    if (SURFACE_OFFSCREEN (src)) {
-       x_src += src->texture.box.x1;
-       y_src += src->texture.box.y1;
-    }
-
-    if (src->format->doublebuffer)
-      gl->read_buffer (src->read_buffer);
+  if (from_drawable) {    
+    gl->read_buffer (src->buffer);
+    
+    gl->disable (GLITZ_GL_SCISSOR_TEST);
 
-    gl->scissor (0, 0, src->width, src->height);
-      
-    gl->read_pixels (x_src, src->height - y_src - height,
+    gl->read_pixels (x_src + src->x,
+                     src->attached->height - (y_src + src->y) - height,
                      width, height,
                      gl_format->format, gl_format->type,
                      pixels);
+    
+    gl->enable (GLITZ_GL_SCISSOR_TEST);
   } else {
     glitz_texture_bind (gl, texture);
     gl->get_tex_image (texture->target, 0,
@@ -700,29 +818,22 @@
 
   if (transform) {
     glitz_image_t src_image, dst_image;
-    int stride;
 
-    src_image.data = data + src_y * bytes_per_line;
+    src_image.data = data;
     src_image.format = &gl_format->pixel;
     src_image.width = src_w;
     src_image.height = src_h;
 
-    if (format->bytes_per_line)
-      stride = format->bytes_per_line;
-    else
-      stride = (((width * format->masks.bpp) / 8) + 3) & -4;
-    
     dst_image.data = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
-    dst_image.data += format->skip_lines * stride;
     dst_image.format = format;
     dst_image.width = width;
     dst_image.height = height;
-    
+
     _glitz_pixel_transform (transform,
                             &src_image,
                             &dst_image,
-                            src_x,
-                            format->xoffset,
+                            src_x, src_y,
+                            format->xoffset, format->skip_lines,
                             width, height);
 
     glitz_buffer_unmap (buffer);

Index: glitz_program.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_program.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- glitz_program.c	20 Sep 2004 04:59:34 -0000	1.15
+++ glitz_program.c	3 Nov 2004 22:50:58 -0000	1.16
@@ -346,9 +346,9 @@
 #define GRADIENT_STOP_SIZE 256
 
 static glitz_gl_uint_t
-_glitz_create_fragment_program (glitz_composite_op_t *op,
-                                int fp_type,
-                                int id,
+_glitz_create_fragment_program (glitz_composite_op_t         *op,
+                                int                          fp_type,
+                                int                          id,
                                 const glitz_program_expand_t *expand)
 {
   char buffer[1024], *program = NULL, *tex, *p = NULL;
@@ -481,7 +481,7 @@
 
 void
 glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
-                        glitz_program_map_t *map)
+                        glitz_program_map_t          *map)
 {
   glitz_gl_uint_t program;
   int i, j, k, x, y;
@@ -518,15 +518,16 @@
 
 glitz_gl_uint_t
 glitz_get_fragment_program (glitz_composite_op_t *op,
-                            int fp_type,
-                            int id)
+                            int                  fp_type,
+                            int                  id)
 {
+  glitz_program_map_t *map;
   glitz_program_t *program;
   int t0 = TEXTURE_INDEX (op->src);
   int t1 = TEXTURE_INDEX (op->mask);
 
-  program =
-    &op->dst->backend->program_map->filters[op->type][fp_type].fp[t0][t1];
+  map = op->dst->drawable->backend->program_map;
+  program = &map->filters[op->type][fp_type].fp[t0][t1];
   
   if (program->size < id) {
     int old_size;
@@ -544,7 +545,7 @@
   }
   
   if (program->name[id - 1] == 0) {
-    glitz_surface_push_current (op->dst, GLITZ_CN_SURFACE_CONTEXT_CURRENT);
+    glitz_surface_push_current (op->dst, GLITZ_CONTEXT_CURRENT);
     
     program->name[id - 1] =
       _glitz_create_fragment_program (op, fp_type, id,

Index: glitz_rect.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_rect.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- glitz_rect.c	4 Oct 2004 11:40:48 -0000	1.13
+++ glitz_rect.c	3 Nov 2004 22:50:58 -0000	1.14
@@ -37,8 +37,8 @@
 
 static void
 glitz_rectangle_bounds (const glitz_rectangle_t *rects,
-                        int n_rects,
-                        glitz_bounding_box_t *box)
+                        int                     n_rects,
+                        glitz_box_t             *box)
 {
   box->x1 = MAXSHORT;
   box->x2 = MINSHORT;
@@ -58,31 +58,34 @@
 }
 
 void
-glitz_set_rectangles (glitz_surface_t *dst,
-                      const glitz_color_t *color,
+glitz_set_rectangles (glitz_surface_t         *dst,
+                      const glitz_color_t     *color,
                       const glitz_rectangle_t *rects,
-                      int n_rects)
+                      int                     n_rects)
 {
-  glitz_bounding_box_t bounds;
-  glitz_gl_proc_address_list_t *gl = &dst->backend->gl;
+  glitz_box_t bounds;
+
+  GLITZ_GL_SURFACE (dst);
 
   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) && SURFACE_OFFSCREEN (dst) &&
+  if (SURFACE_SOLID (dst) &&
       (bounds.x2 - bounds.x1) > 0 && (bounds.y2 - bounds.y1) > 0) {
-    STORE_16 (dst->solid.red, dst->format->red_size, color->red);
-    STORE_16 (dst->solid.green, dst->format->green_size, color->green);
-    STORE_16 (dst->solid.blue, dst->format->blue_size, color->blue);
-    STORE_16 (dst->solid.alpha, dst->format->alpha_size, color->alpha);
-    
-    dst->flags |= GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK;
+    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);
+
+    glitz_surface_damage (dst, &bounds,
+                          GLITZ_DAMAGE_TEXTURE_MASK |
+                          GLITZ_DAMAGE_DRAWABLE_MASK);
     return;
   }
 
-  if (glitz_surface_push_current (dst, GLITZ_CN_SURFACE_DRAWABLE_CURRENT)) {
+  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,
@@ -90,12 +93,14 @@
 
     for (; n_rects; n_rects--, rects++) {
       gl->scissor (rects->x,
-                   dst->height - rects->y - rects->height,
+                   dst->attached->height - dst->y - rects->y - rects->height,
                    rects->width,
                    rects->height);
       gl->clear (GLITZ_GL_COLOR_BUFFER_BIT);
     }
-    glitz_surface_dirty (dst, &bounds);
+    glitz_surface_damage (dst, &bounds,
+                          GLITZ_DAMAGE_TEXTURE_MASK |
+                          GLITZ_DAMAGE_SOLID_MASK);
   } else {
     static glitz_pixel_format_t pf = {
       {
@@ -154,12 +159,12 @@
 slim_hidden_def(glitz_set_rectangles);
 
 void
-glitz_set_rectangle (glitz_surface_t *dst,
+glitz_set_rectangle (glitz_surface_t     *dst,
                      const glitz_color_t *color,
-                     int x,
-                     int y,
-                     unsigned int width,
-                     unsigned int height)
+                     int                 x,
+                     int                 y,
+                     unsigned int        width,
+                     unsigned int        height)
 {
   glitz_rectangle_t rect;
 

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

Index: glitz_surface.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_surface.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- glitz_surface.c	4 Oct 2004 11:40:48 -0000	1.23
+++ glitz_surface.c	3 Nov 2004 22:50:58 -0000	1.24
@@ -32,94 +32,92 @@
 #include <stdlib.h>
 #include <string.h>
 
-void
-glitz_surface_init (glitz_surface_t *surface,
-                    glitz_surface_backend_t *backend,
-                    glitz_format_t *format,
-                    int width,
-                    int height)
+glitz_surface_t *
+glitz_surface_create (glitz_drawable_t *drawable,
+                      glitz_format_t   *format,
+                      unsigned int     width,
+                      unsigned int     height)
 {
-  surface->backend = backend;
+  glitz_surface_t *surface;
+  
+  if (width == 0 || height == 0)
+    return NULL;
 
-  surface->ref_count = 1;
+  surface = (glitz_surface_t *) calloc (1, sizeof (glitz_surface_t));
+  if (surface == NULL)
+    return NULL;
 
-  surface->filter = GLITZ_FILTER_NEAREST;
+  surface->drawable = drawable;
+  glitz_drawable_reference (drawable);
   
+  surface->ref_count = 1;
+  surface->filter = GLITZ_FILTER_NEAREST;  
   surface->format = format;
-  surface->width = width;
-  surface->height = height;
-  surface->update_mask = GLITZ_UPDATE_ALL_MASK;
+  surface->width = (int) width;
+  surface->height = (int) height;
+  surface->buffer = GLITZ_GL_FRONT;
 
-  if (format->doublebuffer)
-    surface->draw_buffer = surface->read_buffer = GLITZ_GL_BACK;
-  else
-    surface->draw_buffer = surface->read_buffer = GLITZ_GL_FRONT;
+  REGION_INIT (&surface->texture_damage, NULL_BOX);
+  REGION_INIT (&surface->drawable_damage, NULL_BOX);
 
   if (width == 1 && height == 1) {
     surface->flags |= GLITZ_SURFACE_FLAG_SOLID_MASK;
-    surface->solid.red = surface->solid.green = surface->solid.blue = 0x0;
     surface->solid.alpha = 0xffff;
   }
-
-  glitz_texture_init (&surface->texture,
-                      width, height,
-                      glitz_format_get_best_texture_format (backend->formats,
-                                                            backend->n_formats,
-                                                            format),
-                      backend->feature_mask);
+  
+  glitz_texture_init (&surface->texture, width, height,
+                      drawable->backend->texture_formats[format->id],
+                      drawable->backend->feature_mask);
+  
+  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;
 }
 
 void
-glitz_surface_fini (glitz_surface_t *surface)
+glitz_surface_destroy (glitz_surface_t *surface)
 {
-  if (surface->geometry.buffer)
-    glitz_buffer_destroy (surface->geometry.buffer);
-   
+  if (!surface)
+    return;
+
+  surface->ref_count--;
+  if (surface->ref_count)
+    return;
+
   if (surface->texture.name) {
-    glitz_surface_push_current (surface, GLITZ_CN_ANY_CONTEXT_CURRENT);
-    glitz_texture_fini (&surface->backend->gl, &surface->texture);
+    glitz_surface_push_current (surface, GLITZ_ANY_CONTEXT_CURRENT);
+    glitz_texture_fini (&surface->drawable->backend->gl, &surface->texture);
     glitz_surface_pop_current (surface);
   }
+
+  REGION_UNINIT (&surface->texture_damage);
+  REGION_UNINIT (&surface->drawable_damage);
+  
+  if (surface->geometry.buffer)
+    glitz_buffer_destroy (surface->geometry.buffer);
   
   if (surface->transform)
     free (surface->transform);
   
   if (surface->filter_params)
     glitz_filter_params_destroy (surface->filter_params);
-}
 
-glitz_format_t *
-glitz_surface_find_similar_standard_format (glitz_surface_t *surface,
-                                            glitz_format_name_t format_name)
-{
-  return
-    glitz_format_find_standard (surface->backend->formats,
-                                surface->backend->n_formats,
-                                format_name);
-}
-slim_hidden_def(glitz_surface_find_similar_standard_format);
-
-glitz_format_t *
-glitz_surface_find_similar_format (glitz_surface_t *surface,
-                                   unsigned long mask,
-                                   const glitz_format_t *templ,
-                                   int count)
-{
-  return glitz_format_find (surface->backend->formats,
-                            surface->backend->n_formats,
-                            mask, templ, count);
-}
-
-glitz_surface_t *
-glitz_surface_create_similar (glitz_surface_t *templ,
-                              glitz_format_t *format,
-                              int width,
-                              int height)
-{
-  if (width < 1 || height < 1)
-    return NULL;
+  if (surface->attached)
+    glitz_drawable_destroy (surface->attached);
   
-  return templ->backend->create_similar (templ, format, width, height);
+  glitz_drawable_destroy (surface->drawable);
+
+  free (surface);
 }
 
 void
@@ -131,70 +129,161 @@
   surface->ref_count++;
 }
 
-void
-glitz_surface_destroy (glitz_surface_t *surface)
+static void
+_glitz_surface_sync_texture (glitz_surface_t *surface)
 {
-  if (!surface)
-    return;
+  if (REGION_NOTEMPTY (&surface->texture_damage)) {
+    glitz_box_t *box;
+    int         n_box;
 
-  surface->ref_count--;
-  if (surface->ref_count)
-    return;
+    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 (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;
+    }
+
+    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);
   
-  surface->backend->destroy (surface);
+    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);
+  }
 }
 
 static void
-_glitz_surface_solid_store (glitz_surface_t *surface) {
-  glitz_gl_proc_address_list_t *gl = &surface->backend->gl;
-
-  if (SURFACE_DRAWABLE (surface)) {
-    glitz_bounding_box_t box;
+_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);
 
-    box.x1 = box.y1 = 0;
-    box.x2 = box.y2 = 1;
+    texture = glitz_surface_get_texture (surface, 0);
+    if (!texture)
+      return;
     
-    gl->color_4us (surface->solid.red,
-                   surface->solid.green,
-                   surface->solid.blue,
-                   surface->solid.alpha);
+    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_set_operator (gl, GLITZ_OPERATOR_SRC);
+    gl->tex_env_f (GLITZ_GL_TEXTURE_ENV, GLITZ_GL_TEXTURE_ENV_MODE,
+                   GLITZ_GL_REPLACE);
+    gl->color_4us (0x0, 0x0, 0x0, 0xffff);
     
-    glitz_geometry_enable_default (gl, surface, &box);
+    glitz_texture_ensure_wrap (gl, texture, GLITZ_GL_CLAMP_TO_EDGE);
+    glitz_texture_ensure_filter (gl, texture, GLITZ_GL_NEAREST);
     
-    gl->draw_arrays (GLITZ_GL_QUADS, 0, 4);
+    glitz_set_operator (gl, GLITZ_OPERATOR_SRC);
     
-    glitz_geometry_disable (gl, surface);
-  } else {
-    glitz_gl_float_t color[4];
+    gl->scissor (surface->x + ext->x1,
+                 surface->attached->height - surface->y - ext->y2,
+                 ext->x2 - ext->x1,
+                 ext->y2 - ext->y1);
 
-    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);
+    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++;
+      }
+
+      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);
     }
+
+    glitz_texture_unbind (gl, texture);
+    
+    REGION_EMPTY (&surface->drawable_damage);
   }
-  surface->flags &= ~GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK;
 }
 
 void
-glitz_surface_ensure_solid (glitz_surface_t *surface)
+glitz_surface_sync_solid (glitz_surface_t *surface)
 {
-  if (SURFACE_DIRTY (surface) || SURFACE_SOLID_DIRTY (surface)) {
-    glitz_gl_proc_address_list_t *gl = &surface->backend->gl;
+  if (SURFACE_SOLID_DAMAGE (surface)) {
     glitz_gl_float_t *c, color[64];
     glitz_texture_t *texture;
 
-    texture = glitz_surface_get_texture (surface, 0);
+    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);
@@ -205,37 +294,257 @@
       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;
 
-    surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK;
+    surface->flags &= ~GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK;
   }
 }
 
-glitz_bool_t
-glitz_surface_push_current (glitz_surface_t *surface,
-                            glitz_constraint_t constraint)
+glitz_texture_t *
+glitz_surface_get_texture (glitz_surface_t *surface,
+                           glitz_bool_t    allocate)
 {
-  if (!surface->backend->push_current (surface, constraint))
-    return 0;
+  GLITZ_GL_SURFACE (surface);
 
-  if (SURFACE_SOLID (surface) && SURFACE_DRAWABLE_DIRTY (surface))
-    _glitz_surface_solid_store (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;
+  
+  return NULL;
+}
+
+void
+glitz_surface_damage (glitz_surface_t *surface,
+                      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 (what & GLITZ_DAMAGE_DRAWABLE_MASK) {
+      REGION_EMPTY (&surface->drawable_damage);
+      REGION_INIT (&surface->drawable_damage, &b);
+    }
+
+    if (what & GLITZ_DAMAGE_TEXTURE_MASK) {
+      REGION_EMPTY (&surface->texture_damage);
+      REGION_INIT (&surface->texture_damage, &b);
+    }
+  }
+
+  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)
+{
+  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);
+    
+    viewport->x = surface->x;
+    viewport->y = surface->y;
+    viewport->width = surface->width;
+    viewport->height = surface->height;
+    
+    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->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);
+  }
+}
+
+void
+glitz_surface_attach (glitz_surface_t         *surface,
+                      glitz_drawable_t        *drawable,
+                      glitz_drawable_buffer_t buffer,
+                      int                     x,
+                      int                     y)
+{
+  glitz_drawable_reference (drawable);
+
+  if (surface->attached)
+    glitz_drawable_destroy (surface->attached);
+  
+  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;
+  }
+
+  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 (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;
+    
+  REGION_EMPTY (&surface->drawable_damage);
+  REGION_INIT (&surface->drawable_damage, &box);
+}
+
+glitz_drawable_t *
+glitz_surface_get_drawable (glitz_surface_t *surface)
+{
+  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;
+}
+slim_hidden_def(glitz_surface_get_attached_drawable);
+
+glitz_bool_t
+glitz_surface_push_current (glitz_surface_t    *surface,
+                            glitz_constraint_t constraint)
+{
+  if (surface->attached) {
+    surface->attached->backend->push_current (surface->attached, surface,
+                                              constraint);
+    if (constraint == GLITZ_DRAWABLE_CURRENT) {
+      _glitz_surface_update_state (surface);
+      _glitz_surface_sync_drawable (surface);
+    }
+  } else {
+    surface->drawable->backend->push_current (surface->drawable, NULL,
+                                              constraint);
+    if (constraint == GLITZ_DRAWABLE_CURRENT)
+      return 0;
+  }
+  
   return 1;
 }
 
 void
 glitz_surface_pop_current (glitz_surface_t *surface)
 {
-  surface->backend->pop_current (surface);
+  glitz_surface_t *other;
+  
+  if (surface->attached)
+    other = surface->attached->backend->pop_current (surface->attached);
+  else
+    other = surface->drawable->backend->pop_current (surface->drawable);
+
+  if (other)
+    _glitz_surface_update_state (other);
+}
+
+glitz_status_t
+glitz_surface_make_current_read (glitz_surface_t *surface)
+{
+  if (surface->attached)
+    return surface->attached->backend->make_current_read (surface->attached);
+  else
+    return surface->drawable->backend->make_current_read (surface->drawable);
 }
 
 void
-glitz_surface_set_transform (glitz_surface_t *surface,
+glitz_surface_set_transform (glitz_surface_t   *surface,
                              glitz_transform_t *transform)
 {
   static glitz_transform_t identity = {
@@ -357,7 +666,7 @@
 
 void
 glitz_surface_set_fill (glitz_surface_t *surface,
-                        glitz_fill_t fill)
+                        glitz_fill_t    fill)
 {
   switch (fill) {
   case GLITZ_FILL_TRANSPARENT:
@@ -388,9 +697,9 @@
 
 void
 glitz_surface_set_component_alpha (glitz_surface_t *surface,
-                                   glitz_bool_t component_alpha)
+                                   glitz_bool_t    component_alpha)
 {
-  if (component_alpha && surface->format->red_size)
+  if (component_alpha && surface->format->color.red_size)
     surface->flags |= GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK;
   else
     surface->flags &= ~GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK;
@@ -398,10 +707,10 @@
 slim_hidden_def(glitz_surface_set_component_alpha);
 
 void
-glitz_surface_set_filter (glitz_surface_t *surface,
-                          glitz_filter_t filter,
+glitz_surface_set_filter (glitz_surface_t    *surface,
+                          glitz_filter_t     filter,
                           glitz_fixed16_16_t *params,
-                          int n_params)
+                          int                n_params)
 {
   glitz_status_t status;
   
@@ -442,143 +751,40 @@
 }
 slim_hidden_def(glitz_surface_set_filter);
 
-int
-glitz_surface_get_width (glitz_surface_t *surface)
-{
-  return surface->width;
-}
-slim_hidden_def(glitz_surface_get_width);
-
-int
-glitz_surface_get_height (glitz_surface_t *surface)
-{
-  return surface->height;
-}
-slim_hidden_def(glitz_surface_get_height);
-
-glitz_texture_t *
-glitz_surface_get_texture (glitz_surface_t *surface,
-                           glitz_bool_t allocate)
-{
-  glitz_texture_t *texture;
-
-  if (SURFACE_SOLID (surface) && SURFACE_DRAWABLE_DIRTY (surface)) {
-    texture = surface->backend->get_texture (surface, 1);
-    _glitz_surface_solid_store (surface);
-  } else
-    texture = surface->backend->get_texture (surface, allocate);
-
-  return texture;
-}
-
-static glitz_gl_enum_t
-_gl_color_buffer (glitz_color_buffer_t buffer)
-{
-  switch (buffer) {
-  case GLITZ_COLOR_BUFFER_FRONT:
-    return GLITZ_GL_FRONT;
-  case GLITZ_COLOR_BUFFER_BACK:
-    return GLITZ_GL_BACK;
-  default:
-    return GLITZ_GL_BACK;
-  }
-}
-
 void
-glitz_surface_set_read_color_buffer (glitz_surface_t *surface,
-                                     glitz_color_buffer_t buffer)
-{
-  glitz_gl_enum_t mode;
-  
-  if (!surface->format->doublebuffer)
-    return;
-    
-  mode = _gl_color_buffer (buffer);
-  if (mode != surface->read_buffer) {
-    surface->read_buffer = mode;
-    glitz_surface_dirty (surface, NULL);
-  }
-}
-slim_hidden_def(glitz_surface_set_read_color_buffer);
-
-void
-glitz_surface_set_draw_color_buffer (glitz_surface_t *surface,
-                                     glitz_color_buffer_t buffer)
-{
-  if (!surface->format->doublebuffer)
-    return;
-
-  surface->draw_buffer = _gl_color_buffer (buffer);
-
-  surface->update_mask |= GLITZ_UPDATE_DRAW_BUFFER_MASK;
-}
-slim_hidden_def(glitz_surface_set_draw_color_buffer);
-
-void
-glitz_surface_swap_buffers (glitz_surface_t *surface)
+glitz_surface_set_dither (glitz_surface_t *surface,
+                          glitz_bool_t    dither)
 {
-  if (!surface->format->doublebuffer)
-    return;
-  
-  surface->backend->swap_buffers (surface);
+  if (dither)
+    surface->flags |= GLITZ_SURFACE_FLAG_DITHER_MASK;
+  else
+    surface->flags &= ~GLITZ_SURFACE_FLAG_DITHER_MASK;
 }
-slim_hidden_def(glitz_surface_swap_buffers);
+slim_hidden_def(glitz_surface_set_dither);
 
 void
 glitz_surface_flush (glitz_surface_t *surface)
 {
-  if (glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT))
-    surface->backend->gl.flush ();
-  
-  glitz_surface_pop_current (surface);
+  if (surface->attached && REGION_NOTEMPTY (&surface->drawable_damage)) {
+    glitz_surface_push_current (surface, GLITZ_DRAWABLE_CURRENT);
+    glitz_surface_pop_current (surface);
+  }
 }
 slim_hidden_def(glitz_surface_flush);
 
-void
-glitz_surface_finish (glitz_surface_t *surface)
-{
-  if (glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT))
-    surface->backend->gl.finish ();
-  
-  glitz_surface_pop_current (surface);
-}
-slim_hidden_def(glitz_surface_finish);
-
-glitz_bool_t
-glitz_surface_make_current_read (glitz_surface_t *surface)
+unsigned int
+glitz_surface_get_width (glitz_surface_t *surface)
 {
-  return surface->backend->make_current_read (surface);
-}
-
-void
-glitz_surface_dirty (glitz_surface_t *surface,
-                     glitz_bounding_box_t *box)
-{ 
-  if (surface->draw_buffer != surface->read_buffer)
-    return;
-  
-  if (!box) {
-    surface->dirty_box.x1 = surface->dirty_box.y1 = 0;
-    surface->dirty_box.x2 = surface->width;
-    surface->dirty_box.y2 = surface->height;
-  } else {
-    if (!SURFACE_DIRTY (surface)) {
-      surface->dirty_box = *box;
-    } else
-      glitz_union_bounding_box (box,
-                                &surface->dirty_box,
-                                &surface->dirty_box);
-  }
-  
-  surface->flags |=
-    (GLITZ_SURFACE_FLAG_DIRTY_MASK | GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK);
+  return (unsigned int) surface->width;
 }
+slim_hidden_def(glitz_surface_get_width);
 
-void
-glitz_surface_status_add (glitz_surface_t *surface, int flags)
+unsigned int
+glitz_surface_get_height (glitz_surface_t *surface)
 {
-  surface->status_mask |= flags;
+  return (unsigned int) surface->height;
 }
+slim_hidden_def(glitz_surface_get_height);
 
 glitz_status_t
 glitz_surface_get_status (glitz_surface_t *surface)
@@ -587,72 +793,6 @@
 }
 slim_hidden_def(glitz_surface_get_status);
 
-void
-glitz_surface_update_state (glitz_surface_t *surface)
-{
-  glitz_gl_proc_address_list_t *gl = &surface->backend->gl;
-  
-  if (surface->update_mask & GLITZ_UPDATE_VIEWPORT_MASK) {
-    gl->viewport (0, 0, surface->width, surface->height);
-    gl->matrix_mode (GLITZ_GL_PROJECTION);
-    gl->load_identity ();
-    gl->ortho (0.0, surface->width, 0.0, surface->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->height, 0.0f);
-    gl->disable (GLITZ_GL_DEPTH_TEST); 
-    gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST);
-    gl->disable (GLITZ_GL_CULL_FACE);
-    gl->depth_mask (GLITZ_GL_FALSE);  
-    gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL);
-    gl->disable (GLITZ_GL_POLYGON_SMOOTH);
-    gl->shade_model (GLITZ_GL_FLAT);
-    gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE,
-                    GLITZ_GL_TRUE);
-    gl->disable (GLITZ_GL_DITHER);
-    gl->enable (GLITZ_GL_SCISSOR_TEST);
-    gl->scissor (0, 0, surface->width, surface->height);
-    gl->disable (GLITZ_GL_STENCIL_TEST);
-    gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY);
-    
-    surface->update_mask &= ~GLITZ_UPDATE_VIEWPORT_MASK;
-  }
-  
-  if (surface->update_mask & GLITZ_UPDATE_DRAW_BUFFER_MASK) {
-    if (surface->format->doublebuffer)
-      gl->draw_buffer (surface->draw_buffer);
-    
-    surface->update_mask &= ~GLITZ_UPDATE_DRAW_BUFFER_MASK;
-  }
-
-  if (surface->update_mask & GLITZ_UPDATE_MULTISAMPLE_MASK) {
-    if (surface->format->multisample.samples) {
-      if (SURFACE_MULTISAMPLE (surface)) {
-        gl->enable (GLITZ_GL_MULTISAMPLE);
-        
-        if (surface->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);
-    }
-    
-    surface->update_mask &= ~GLITZ_UPDATE_MULTISAMPLE_MASK;
-  }
-}
-
-unsigned long
-glitz_surface_get_features (glitz_surface_t *surface)
-{
-  return surface->backend->feature_mask;
-}
-slim_hidden_def(glitz_surface_get_features);
-
 glitz_format_t *
 glitz_surface_get_format (glitz_surface_t *surface)
 {

Index: glitz_texture.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_texture.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- glitz_texture.c	4 Oct 2004 11:40:48 -0000	1.15
+++ glitz_texture.c	3 Nov 2004 22:50:58 -0000	1.16
@@ -1,28 +1,26 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * 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
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * 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
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
  *
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
- *          Peter Nilsson <c99pnn at cs.umu.se>
+ * Author: David Reveman <c99drn at cs.umu.se>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -33,10 +31,10 @@
 
 void
 glitz_texture_init (glitz_texture_t *texture,
-                    unsigned int width,
-                    unsigned int height,
-                    unsigned int texture_format,
-                    unsigned long feature_mask)
+                    int             width,
+                    int             height,
+                    glitz_gl_int_t  texture_format,
+                    unsigned long   feature_mask)
 {
   texture->filter = 0;
   texture->wrap = 0;
@@ -89,9 +87,9 @@
 
 void
 glitz_texture_size_check (glitz_gl_proc_address_list_t *gl,
-                          glitz_texture_t *texture,
-                          glitz_gl_int_t max_2d,
-                          glitz_gl_int_t max_rect) {
+                          glitz_texture_t              *texture,
+                          glitz_gl_int_t               max_2d,
+                          glitz_gl_int_t               max_rect) {
   glitz_gl_enum_t proxy_target;
   glitz_gl_int_t value, max;
 
@@ -126,7 +124,7 @@
 
 void
 glitz_texture_allocate (glitz_gl_proc_address_list_t *gl,
-                        glitz_texture_t *texture)
+                        glitz_texture_t              *texture)
 {
   char *data = NULL;
   
@@ -162,7 +160,7 @@
 
 void 
 glitz_texture_fini (glitz_gl_proc_address_list_t *gl,
-                    glitz_texture_t *texture)
+                    glitz_texture_t              *texture)
 {
   if (texture->name)
     gl->delete_textures (1, &texture->name);
@@ -170,8 +168,8 @@
 
 void
 glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl,
-                             glitz_texture_t *texture,
-                             glitz_gl_enum_t filter)
+                             glitz_texture_t              *texture,
+                             glitz_gl_enum_t              filter)
 {
   if (!texture->name)
     return;
@@ -185,8 +183,8 @@
 
 void
 glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl,
-                           glitz_texture_t *texture,
-                           glitz_gl_enum_t wrap)
+                           glitz_texture_t              *texture,
+                           glitz_gl_enum_t              wrap)
 {
   if (!texture->name)
     return;
@@ -200,7 +198,7 @@
 
 void
 glitz_texture_bind (glitz_gl_proc_address_list_t *gl,
-                    glitz_texture_t *texture)
+                    glitz_texture_t              *texture)
 {  
   gl->disable (GLITZ_GL_TEXTURE_RECTANGLE);
   gl->disable (GLITZ_GL_TEXTURE_2D);
@@ -214,48 +212,37 @@
 
 void
 glitz_texture_unbind (glitz_gl_proc_address_list_t *gl,
-                      glitz_texture_t *texture)
+                      glitz_texture_t              *texture)
 {
   gl->bind_texture (texture->target, 0);
   gl->disable (texture->target);
 }
 
 void
-glitz_texture_copy_surface (glitz_texture_t *texture,
-                            glitz_surface_t *surface,
-                            int x_surface,
-                            int y_surface,
-                            int width,
-                            int height,
-                            int x_texture,
-                            int y_texture)
+glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl,
+                             glitz_texture_t              *texture,
+                             glitz_drawable_t             *drawable,
+                             int                          x_drawable,
+                             int                          y_drawable,
+                             int                          width,
+                             int                          height,
+                             int                          x_texture,
+                             int                          y_texture)
 {
-  glitz_gl_proc_address_list_t *gl = &surface->backend->gl;
-  
-  glitz_surface_push_current (surface, GLITZ_CN_SURFACE_DRAWABLE_CURRENT);
-  
-  glitz_texture_bind (gl, texture);
-
-  if (surface->format->doublebuffer)
-    gl->read_buffer (surface->read_buffer);
-
   gl->copy_tex_sub_image_2d (texture->target, 0,
                              texture->box.x1 + x_texture,
                              texture->box.y2 - y_texture - height,
-                             x_surface,
-                             surface->height - y_surface - height,
+                             x_drawable,
+                             drawable->height - y_drawable - height,
                              width, height);
-
-  glitz_texture_unbind (gl, texture);
-  glitz_surface_pop_current (surface);
 }
 
 void
 glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
-                           glitz_texture_t *texture,
-                           int x_src,
-                           int y_src,
-                           unsigned long flags)
+                           glitz_texture_t              *texture,
+                           int                          x_src,
+                           int                          y_src,
+                           unsigned long                flags)
 {
   glitz_vec4_t plane;
 

Index: glitz_util.c
===================================================================
RCS file: /cvs/cairo/glitz/src/glitz_util.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- glitz_util.c	7 Sep 2004 14:28:21 -0000	1.10
+++ glitz_util.c	3 Nov 2004 22:50:58 -0000	1.11
@@ -1,28 +1,26 @@
 /*
- * Copyright © 2004 David Reveman, Peter Nilsson
- *
+ * 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
- * David Reveman and Peter Nilsson not be used in advertising or
- * publicity pertaining to distribution of the software without
- * specific, written prior permission. David Reveman and Peter Nilsson
- * makes no representations about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty.
+ * 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
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
  *
- * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
- * PETER NILSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
- * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * Authors: David Reveman <c99drn at cs.umu.se>
- *          Peter Nilsson <c99pnn at cs.umu.se>
+ * Author: David Reveman <c99drn at cs.umu.se>
  */
 
 #ifdef HAVE_CONFIG_H
@@ -34,33 +32,35 @@
 #include <stdlib.h>
 #include <string.h>
 
-void
-glitz_intersect_bounding_box (glitz_bounding_box_t *box1,
-                              glitz_bounding_box_t *box2,
-                              glitz_bounding_box_t *return_box)
-{
-  return_box->x1 = (box1->x1 >= box2->x1)? box1->x1: box2->x1;
-  return_box->x2 = (box1->x2 <= box2->x2)? box1->x2: box2->x2;
-  return_box->y1 = (box1->y1 >= box2->y1)? box1->y1: box2->y1;
-  return_box->y2 = (box1->y2 <= box2->y2)? box1->y2: box2->y2;
-
-  if (return_box->x1 >= return_box->x2)
-    return_box->x1 = return_box->x2 = 0;
-  
-  if (return_box->y1 >= return_box->y2)
-    return_box->y1 = return_box->y2 = 0;
-}
-
-void
-glitz_union_bounding_box (glitz_bounding_box_t *box1,
-                          glitz_bounding_box_t *box2,
-                          glitz_bounding_box_t *return_box)
-{
-  return_box->x1 = (box1->x1 <= box2->x1)? box1->x1: box2->x1;
-  return_box->x2 = (box1->x2 >= box2->x2)? box1->x2: box2->x2;
-  return_box->y1 = (box1->y1 <= box2->y1)? box1->y1: box2->y1;
-  return_box->y2 = (box1->y2 >= box2->y2)? box1->y2: box2->y2;
-}
+static glitz_extension_map gl_extensions[] = {
+  { 0.0, "GL_ARB_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
+  { 0.0, "GL_EXT_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
+  { 0.0, "GL_NV_texture_rectangle", GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK },
+  { 0.0, "GL_ARB_texture_non_power_of_two",
+    GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK },
+  { 0.0, "GL_ARB_texture_mirrored_repeat",
+    GLITZ_FEATURE_TEXTURE_MIRRORED_REPEAT_MASK },
+  { 0.0, "GL_ARB_texture_border_clamp",
+    GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK },
+  { 0.0, "GL_ARB_texture_env_combine",
+    GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK },
+  { 0.0, "GL_EXT_texture_env_combine",
+    GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK },
+  { 0.0, "GL_ARB_texture_env_dot3", GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK },
+  { 0.0, "GL_ARB_multisample", GLITZ_FEATURE_MULTISAMPLE_MASK },
+  { 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_ARB_fragment_program", GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK },
+  { 0.0, "GL_ARB_vertex_buffer_object",
+    GLITZ_FEATURE_VERTEX_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 },
+  { 0.0, "GL_ARB_imaging", GLITZ_FEATURE_BLEND_COLOR_MASK },
+  { 0.0, "GL_APPLE_packed_pixels", GLITZ_FEATURE_PACKED_PIXELS_MASK },
+  { 0.0, NULL, 0 }
+};
 
 static glitz_bool_t
 _glitz_extension_check (const char *extensions,
@@ -87,8 +87,8 @@
 }
 
 unsigned long
-glitz_extensions_query (glitz_gl_float_t version,
-                        const char *extensions_string,
+glitz_extensions_query (glitz_gl_float_t    version,
+                        const char          *extensions_string,
                         glitz_extension_map *extensions_map)
 {
   unsigned long mask = 0;
@@ -103,6 +103,167 @@
   return mask;
 }
 
+static glitz_status_t
+_glitz_query_gl_extensions (glitz_gl_proc_address_list_t *gl,
+                            glitz_gl_float_t             *gl_version,
+                            unsigned long                *feature_mask)
+{
+  const char *gl_extensions_string;
+
+  *gl_version = atof ((const char *) gl->get_string (GLITZ_GL_VERSION));
+  if (*gl_version < 1.2f)
+    return GLITZ_STATUS_NOT_SUPPORTED;
+  
+  gl_extensions_string = (const char *) gl->get_string (GLITZ_GL_EXTENSIONS);
+  
+  *feature_mask = glitz_extensions_query (*gl_version,
+                                          gl_extensions_string,
+                                          gl_extensions);
+  
+  if ((*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_COMBINE_MASK) &&
+      (*feature_mask & GLITZ_FEATURE_TEXTURE_ENV_DOT3_MASK)) {
+    glitz_gl_int_t max_texture_units;
+    
+    gl->get_integer_v (GLITZ_GL_MAX_TEXTURE_UNITS, &max_texture_units);
+    if (max_texture_units >= 3)
+      *feature_mask |= GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK;
+  }
+
+  return GLITZ_STATUS_SUCCESS;
+}
+
+static void
+_glitz_gl_proc_address_lookup (glitz_backend_t               *backend,
+                               glitz_get_proc_address_proc_t get_proc_address,
+                               void                          *closure)
+{
+  if (backend->feature_mask & GLITZ_FEATURE_BLEND_COLOR_MASK) {
+    if (backend->gl_version >= 1.4f) {
+      backend->gl.blend_color = (glitz_gl_blend_color_t)
+        get_proc_address ("glBlendColor", closure);
+    } else {
+      backend->gl.blend_color = (glitz_gl_blend_color_t)
+        get_proc_address ("glBlendColorEXT", closure);
+    }
+
+    if (!backend->gl.blend_color)
+      backend->feature_mask &= ~GLITZ_FEATURE_BLEND_COLOR_MASK;
+  }
+
+  if (backend->feature_mask & GLITZ_FEATURE_MULTITEXTURE_MASK) {
+    if (backend->gl_version >= 1.3f) {
+      backend->gl.active_texture = (glitz_gl_active_texture_t)
+        get_proc_address ("glActiveTexture", closure);
+    } else {
+      backend->gl.active_texture = (glitz_gl_active_texture_t)
+        get_proc_address ("glActiveTextureARB", closure);
+    }
+
+    if (!backend->gl.active_texture) {
+      backend->feature_mask &= ~GLITZ_FEATURE_MULTITEXTURE_MASK;
+      backend->feature_mask &= ~GLITZ_FEATURE_PER_COMPONENT_RENDERING_MASK;
+    }
+  }
+
+  if (backend->feature_mask & GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK) {
+    backend->gl.gen_programs = (glitz_gl_gen_programs_t)
+      get_proc_address ("glGenProgramsARB", closure);
+    backend->gl.delete_programs = (glitz_gl_delete_programs_t)
+      get_proc_address ("glDeleteProgramsARB", closure);
+    backend->gl.program_string = (glitz_gl_program_string_t)
+      get_proc_address ("glProgramStringARB", closure);
+    backend->gl.bind_program = (glitz_gl_bind_program_t)
+      get_proc_address ("glBindProgramARB", closure);
+    backend->gl.program_local_param_4fv = (glitz_gl_program_local_param_4fv_t)
+      get_proc_address ("glProgramLocalParameter4fvARB", closure);
+    backend->gl.get_program_iv = (glitz_gl_get_program_iv_t)
+      get_proc_address ("glGetProgramivARB", closure);
+
+    if ((!backend->gl.gen_programs) ||
+        (!backend->gl.delete_programs) ||
+        (!backend->gl.program_string) ||
+        (!backend->gl.bind_program) ||
+        (!backend->gl.program_local_param_4fv))
+      backend->feature_mask &= ~GLITZ_FEATURE_FRAGMENT_PROGRAM_MASK;
+  }
+
+  if ((backend->feature_mask & GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK) ||
+      (backend->feature_mask & GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK)) {
+    if (backend->gl_version >= 1.5f) {
+      backend->gl.gen_buffers = (glitz_gl_gen_buffers_t)
+        get_proc_address ("glGenBuffers", closure);
+      backend->gl.delete_buffers = (glitz_gl_delete_buffers_t)
+        get_proc_address ("glDeleteBuffers", closure);
+      backend->gl.bind_buffer = (glitz_gl_bind_buffer_t)
+        get_proc_address ("glBindBuffer", closure);
+      backend->gl.buffer_data = (glitz_gl_buffer_data_t)
+        get_proc_address ("glBufferData", closure);
+      backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t)
+        get_proc_address ("glBufferSubData", closure);
+      backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t)
+        get_proc_address ("glGetBufferSubData", closure);
+      backend->gl.map_buffer = (glitz_gl_map_buffer_t)
+        get_proc_address ("glMapBuffer", closure);
+      backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t)
+        get_proc_address ("glUnmapBuffer", closure);
+    } else {
+      backend->gl.gen_buffers = (glitz_gl_gen_buffers_t)
+        get_proc_address ("glGenBuffersARB", closure);
+      backend->gl.delete_buffers = (glitz_gl_delete_buffers_t)
+        get_proc_address ("glDeleteBuffersARB", closure);
+      backend->gl.bind_buffer = (glitz_gl_bind_buffer_t)
+        get_proc_address ("glBindBufferARB", closure);
+      backend->gl.buffer_data = (glitz_gl_buffer_data_t)
+        get_proc_address ("glBufferDataARB", closure);
+      backend->gl.buffer_sub_data = (glitz_gl_buffer_sub_data_t)
+        get_proc_address ("glBufferSubDataARB", closure);
+      backend->gl.get_buffer_sub_data = (glitz_gl_get_buffer_sub_data_t)
+        get_proc_address ("glGetBufferSubDataARB", closure);
+      backend->gl.map_buffer = (glitz_gl_map_buffer_t)
+        get_proc_address ("glMapBufferARB", closure);
+      backend->gl.unmap_buffer = (glitz_gl_unmap_buffer_t)
+        get_proc_address ("glUnmapBufferARB", closure);
+    }
+
+    if ((!backend->gl.gen_buffers) ||
+        (!backend->gl.delete_buffers) ||
+        (!backend->gl.bind_buffer) ||
+        (!backend->gl.buffer_data) ||
+        (!backend->gl.buffer_sub_data) ||
+        (!backend->gl.get_buffer_sub_data) ||
+        (!backend->gl.map_buffer) ||
+        (!backend->gl.unmap_buffer)) {
+      backend->feature_mask &= ~GLITZ_FEATURE_VERTEX_BUFFER_OBJECT_MASK;
+      backend->feature_mask &= ~GLITZ_FEATURE_PIXEL_BUFFER_OBJECT_MASK;
+    }
+  }
+}
+
+void
+glitz_backend_init (glitz_backend_t               *backend,
+                    glitz_get_proc_address_proc_t get_proc_address,
+                    void                          *closure)
+{
+  if (!_glitz_query_gl_extensions (&backend->gl,
+                                   &backend->gl_version,
+                                   &backend->feature_mask)) {
+    _glitz_gl_proc_address_lookup (backend, get_proc_address, closure);
+    glitz_create_surface_formats (&backend->gl,
+                                  &backend->formats,
+                                  &backend->texture_formats,
+                                  &backend->n_formats);
+  }
+  
+  backend->gl.get_integer_v (GLITZ_GL_MAX_TEXTURE_SIZE,
+                             &backend->max_texture_2d_size);
+  
+  if (backend->feature_mask & GLITZ_FEATURE_TEXTURE_RECTANGLE_MASK)
+    backend->gl.get_integer_v (GLITZ_GL_MAX_RECTANGLE_TEXTURE_SIZE,
+                               &backend->max_texture_rect_size);
+  else
+    backend->max_texture_rect_size = 0;
+}
+
 unsigned int
 glitz_uint_to_power_of_two (unsigned int x)
 {
@@ -117,8 +278,8 @@
 
 void
 glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl,
-                      int x,
-                      int y)
+                      int                          x,
+                      int                          y)
 {
   gl->push_attrib (GLITZ_GL_TRANSFORM_BIT | GLITZ_GL_VIEWPORT_BIT);
   gl->matrix_mode (GLITZ_GL_PROJECTION);
@@ -148,3 +309,22 @@
   else if (*value > max)
     *value = max;
 }
+
+void
+glitz_initiate_state (glitz_gl_proc_address_list_t *gl)
+{
+  gl->disable (GLITZ_GL_DEPTH_TEST); 
+  gl->hint (GLITZ_GL_PERSPECTIVE_CORRECTION_HINT, GLITZ_GL_FASTEST);
+  gl->disable (GLITZ_GL_CULL_FACE);
+  gl->depth_mask (GLITZ_GL_FALSE);  
+  gl->polygon_mode (GLITZ_GL_FRONT_AND_BACK, GLITZ_GL_FILL);
+  gl->disable (GLITZ_GL_POLYGON_SMOOTH);
+  gl->disable (GLITZ_GL_LINE_SMOOTH);
+  gl->disable (GLITZ_GL_POINT_SMOOTH);
+  gl->shade_model (GLITZ_GL_FLAT);
+  gl->color_mask (GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE, GLITZ_GL_TRUE);
+  gl->enable (GLITZ_GL_SCISSOR_TEST);
+  gl->disable (GLITZ_GL_STENCIL_TEST);
+  gl->enable_client_state (GLITZ_GL_VERTEX_ARRAY);
+  gl->disable (GLITZ_GL_DEPTH_TEST); 
+}

Index: glitzint.h
===================================================================
RCS file: /cvs/cairo/glitz/src/glitzint.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- glitzint.h	4 Oct 2004 11:40:48 -0000	1.29
+++ glitzint.h	3 Nov 2004 22:50:58 -0000	1.30
@@ -67,88 +67,95 @@
 #define GLITZ_STATUS_NOT_SUPPORTED_MASK      (1L << 2)
 #define GLITZ_STATUS_CONTENT_DESTROYED_MASK  (1L << 3)
 
-#define GLITZ_FORMAT_ALL_EXCEPT_ID_MASK ((1L << 19) - 2)
+#define GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK ((1L << 11) - 2)
 
 #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);
+
 typedef struct _glitz_gl_proc_address_list_t {
-  glitz_gl_enable_t enable;
-  glitz_gl_disable_t disable;
-  glitz_gl_get_error_t get_error;
-  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_draw_arrays_t draw_arrays;
-  glitz_gl_tex_env_f_t tex_env_f;
-  glitz_gl_tex_env_fv_t tex_env_fv;
-  glitz_gl_tex_gen_i_t tex_gen_i;
-  glitz_gl_tex_gen_fv_t tex_gen_fv;
-  glitz_gl_color_4us_t color_4us;
-  glitz_gl_color_4f_t color_4f;
-  glitz_gl_scissor_t scissor;
-  glitz_gl_blend_func_t blend_func;
-  glitz_gl_clear_t clear;
-  glitz_gl_clear_color_t clear_color;
-  glitz_gl_clear_stencil_t clear_stencil;
-  glitz_gl_stencil_func_t stencil_func;
-  glitz_gl_stencil_op_t stencil_op;
-  glitz_gl_push_attrib_t push_attrib;
-  glitz_gl_pop_attrib_t pop_attrib;
-  glitz_gl_matrix_mode_t matrix_mode;
-  glitz_gl_push_matrix_t push_matrix;
-  glitz_gl_pop_matrix_t pop_matrix;
-  glitz_gl_load_identity_t load_identity;
-  glitz_gl_load_matrix_f_t load_matrix_f;
-  glitz_gl_depth_range_t depth_range;
-  glitz_gl_viewport_t viewport;
-  glitz_gl_raster_pos_2f_t raster_pos_2f;
-  glitz_gl_bitmap_t bitmap;
-  glitz_gl_read_buffer_t read_buffer;
-  glitz_gl_draw_buffer_t draw_buffer;
-  glitz_gl_copy_pixels_t copy_pixels;
-  glitz_gl_flush_t flush;
-  glitz_gl_finish_t finish;
-  glitz_gl_pixel_store_i_t pixel_store_i;
-  glitz_gl_ortho_t ortho;
-  glitz_gl_scale_f_t scale_f;
-  glitz_gl_translate_f_t translate_f;
-  glitz_gl_hint_t hint;
-  glitz_gl_depth_mask_t depth_mask;
-  glitz_gl_polygon_mode_t polygon_mode;
-  glitz_gl_shade_model_t shade_model;
-  glitz_gl_color_mask_t color_mask;
-  glitz_gl_read_pixels_t read_pixels;
-  glitz_gl_get_tex_image_t get_tex_image;
-  glitz_gl_tex_sub_image_2d_t tex_sub_image_2d;
-  glitz_gl_gen_textures_t gen_textures;
-  glitz_gl_delete_textures_t delete_textures;
-  glitz_gl_bind_texture_t bind_texture;
-  glitz_gl_tex_image_2d_t tex_image_2d;
-  glitz_gl_tex_parameter_i_t tex_parameter_i;
+  
+  /* core */
+  glitz_gl_enable_t                     enable;
+  glitz_gl_disable_t                    disable;
+  glitz_gl_get_error_t                  get_error;
+  glitz_gl_get_string_t                 get_string;
+  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_draw_arrays_t                draw_arrays;
+  glitz_gl_tex_env_f_t                  tex_env_f;
+  glitz_gl_tex_env_fv_t                 tex_env_fv;
+  glitz_gl_tex_gen_i_t                  tex_gen_i;
+  glitz_gl_tex_gen_fv_t                 tex_gen_fv;
+  glitz_gl_color_4us_t                  color_4us;
+  glitz_gl_color_4f_t                   color_4f;
+  glitz_gl_scissor_t                    scissor;
+  glitz_gl_blend_func_t                 blend_func;
+  glitz_gl_clear_t                      clear;
+  glitz_gl_clear_color_t                clear_color;
+  glitz_gl_clear_stencil_t              clear_stencil;
+  glitz_gl_stencil_func_t               stencil_func;
+  glitz_gl_stencil_op_t                 stencil_op;
+  glitz_gl_push_attrib_t                push_attrib;
+  glitz_gl_pop_attrib_t                 pop_attrib;
+  glitz_gl_matrix_mode_t                matrix_mode;
+  glitz_gl_push_matrix_t                push_matrix;
+  glitz_gl_pop_matrix_t                 pop_matrix;
+  glitz_gl_load_identity_t              load_identity;
+  glitz_gl_load_matrix_f_t              load_matrix_f;
+  glitz_gl_depth_range_t                depth_range;
+  glitz_gl_viewport_t                   viewport;
+  glitz_gl_raster_pos_2f_t              raster_pos_2f;
+  glitz_gl_bitmap_t                     bitmap;
+  glitz_gl_read_buffer_t                read_buffer;
+  glitz_gl_draw_buffer_t                draw_buffer;
+  glitz_gl_copy_pixels_t                copy_pixels;
+  glitz_gl_flush_t                      flush;
+  glitz_gl_finish_t                     finish;
+  glitz_gl_pixel_store_i_t              pixel_store_i;
+  glitz_gl_ortho_t                      ortho;
+  glitz_gl_scale_f_t                    scale_f;
+  glitz_gl_translate_f_t                translate_f;
+  glitz_gl_hint_t                       hint;
+  glitz_gl_depth_mask_t                 depth_mask;
+  glitz_gl_polygon_mode_t               polygon_mode;
+  glitz_gl_shade_model_t                shade_model;
+  glitz_gl_color_mask_t                 color_mask;
+  glitz_gl_read_pixels_t                read_pixels;
+  glitz_gl_get_tex_image_t              get_tex_image;
+  glitz_gl_tex_sub_image_2d_t           tex_sub_image_2d;
+  glitz_gl_gen_textures_t               gen_textures;
+  glitz_gl_delete_textures_t            delete_textures;
+  glitz_gl_bind_texture_t               bind_texture;
+  glitz_gl_tex_image_2d_t               tex_image_2d;
+  glitz_gl_tex_parameter_i_t            tex_parameter_i;
   glitz_gl_get_tex_level_parameter_iv_t get_tex_level_parameter_iv;
-  glitz_gl_copy_tex_sub_image_2d_t copy_tex_sub_image_2d;
-  glitz_gl_get_integer_v_t get_integer_v;
+  glitz_gl_copy_tex_sub_image_2d_t      copy_tex_sub_image_2d;
+  glitz_gl_get_integer_v_t              get_integer_v;
 
-  glitz_gl_blend_color_t blend_color;
-  glitz_gl_active_texture_t active_texture;
-  glitz_gl_gen_programs_t gen_programs;
-  glitz_gl_delete_programs_t delete_programs;
-  glitz_gl_program_string_t program_string;
-  glitz_gl_bind_program_t bind_program;
-  glitz_gl_program_local_param_4fv_t program_local_param_4fv;
-  glitz_gl_get_program_iv_t get_program_iv;
-  glitz_gl_gen_buffers_t gen_buffers;
-  glitz_gl_delete_buffers_t delete_buffers;
-  glitz_gl_bind_buffer_t bind_buffer;
-  glitz_gl_buffer_data_t buffer_data;
-  glitz_gl_buffer_sub_data_t buffer_sub_data;
-  glitz_gl_get_buffer_sub_data_t get_buffer_sub_data;
-  glitz_gl_map_buffer_t map_buffer;
-  glitz_gl_unmap_buffer_t unmap_buffer;
-  
-  glitz_bool_t need_lookup;
+  /* extensions */
+  glitz_gl_blend_color_t                blend_color;
+  glitz_gl_active_texture_t             active_texture;
+  glitz_gl_gen_programs_t               gen_programs;
+  glitz_gl_delete_programs_t            delete_programs;
+  glitz_gl_program_string_t             program_string;
+  glitz_gl_bind_program_t               bind_program;
+  glitz_gl_program_local_param_4fv_t    program_local_param_4fv;
+  glitz_gl_get_program_iv_t             get_program_iv;
+  glitz_gl_gen_buffers_t                gen_buffers;
+  glitz_gl_delete_buffers_t             delete_buffers;
+  glitz_gl_bind_buffer_t                bind_buffer;
+  glitz_gl_buffer_data_t                buffer_data;
+  glitz_gl_buffer_sub_data_t            buffer_sub_data;
+  glitz_gl_get_buffer_sub_data_t        get_buffer_sub_data;
+  glitz_gl_map_buffer_t                 map_buffer;
+  glitz_gl_unmap_buffer_t               unmap_buffer;
 } glitz_gl_proc_address_list_t;
 
 typedef int glitz_surface_type_t;
@@ -164,8 +171,7 @@
 
 typedef int glitz_combine_type_t;
 
-#define GLITZ_COMBINE_TYPE_NA            -1
-#define GLITZ_COMBINE_TYPE_INTERMEDIATE   0
+#define GLITZ_COMBINE_TYPE_NA             0
 #define GLITZ_COMBINE_TYPE_ARGB           1
 #define GLITZ_COMBINE_TYPE_ARGB_ARGB      2
 #define GLITZ_COMBINE_TYPE_ARGB_ARGBC     3
@@ -201,7 +207,7 @@
 
 typedef struct _glitz_program_t {
   glitz_gl_int_t *name;
-  unsigned int size;
+  unsigned int   size;
 } glitz_program_t;
 
 typedef struct _glitz_filter_map_t {
@@ -213,15 +219,133 @@
 } glitz_program_map_t;
 
 typedef enum {
-  GLITZ_CN_NONE,
-  GLITZ_CN_ANY_CONTEXT_CURRENT,
-  GLITZ_CN_SURFACE_CONTEXT_CURRENT,
-  GLITZ_CN_SURFACE_DRAWABLE_CURRENT
+  GLITZ_NONE,
+  GLITZ_ANY_CONTEXT_CURRENT,
+  GLITZ_CONTEXT_CURRENT,
+  GLITZ_DRAWABLE_CURRENT
 } glitz_constraint_t;
 
-typedef struct _glitz_bounding_box_t {
-  int x1, x2, y1, y2;
-} glitz_bounding_box_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;
+  int         n_box;
+  void        *data;
+  int         size;
+} glitz_region_t;
+
+#define NULL_BOX ((glitz_box_t *) 0)
+
+#define REGION_INIT(region, __box) \
+  { \
+    if (__box) { \
+      (region)->extents = *(__box); \
+      (region)->box = &(region)->extents; \
+      (region)->n_box = 1; \
+    } else { \
+      (region)->extents.x1 = 0; \
+      (region)->extents.y1 = 0; \
+      (region)->extents.x2 = 0; \
+      (region)->extents.y2 = 0; \
+      (region)->box = NULL; \
+      (region)->n_box = 0; \
+    } \
+  }
+
+#define REGION_EMPTY(region) \
+  { \
+    (region)->extents.x1 = 0; \
+    (region)->extents.y1 = 0; \
+    (region)->extents.x2 = 0; \
+    (region)->extents.y2 = 0; \
+    (region)->box = NULL; \
+    (region)->n_box = 0; \
+  }
+
+#define REGION_UNINIT(region) \
+  { \
+    REGION_EMPTY (region); \
+    if ((region)->data) \
+      free ((region)->data); \
+    (region)->data = NULL; \
+    (region)->size = 0; \
+  }
+
+#define REGION_NOTEMPTY(region) \
+  ((region)->n_box)
+
+#define REGION_RECTS(region) \
+  ((region)->box)
+
+#define REGION_NUM_RECTS(region) \
+  ((region)->n_box)
+
+#define REGION_EXTENTS(region) \
+ (&(region)->extents)
+
+#define REGION_UNION(region, box) \
+  glitz_region_union (region, box)
+
+extern glitz_status_t __internal_linkage
+glitz_region_union (glitz_region_t *region,
+                    glitz_box_t    *box);
+
+typedef struct glitz_backend {
+  glitz_drawable_t *
+  (*create_pbuffer)            (void                       *drawable,
+                                glitz_drawable_format_t    *format,
+                                glitz_pbuffer_attributes_t *attributes,
+                                unsigned long              mask);
+  
+  void
+  (*destroy)                   (void *drawable);
+
+  void
+  (*push_current)              (void               *drawable,
+                                glitz_surface_t    *surface,
+                                glitz_constraint_t constraint);
+
+  glitz_surface_t *
+  (*pop_current)               (void *drawable);
+
+  void
+  (*swap_buffers)              (void *drawable);
+
+  glitz_status_t
+  (*make_current_read)         (void *drawable);
+
+  glitz_gl_proc_address_list_t gl;
+  
+  glitz_drawable_format_t      *drawable_formats;
+  int                          n_drawable_formats;
+
+  glitz_gl_int_t               *texture_formats;
+  glitz_format_t               *formats;
+  int                          n_formats;
+
+  glitz_gl_float_t             gl_version;
+  glitz_gl_int_t               max_texture_2d_size;
+  glitz_gl_int_t               max_texture_rect_size;
+  unsigned long                feature_mask;
+  
+  glitz_program_map_t          *program_map;
+} glitz_backend_t;
+
+struct _glitz_drawable {
+  glitz_backend_t         *backend;
+
+  int                     ref_count;
+  glitz_drawable_format_t *format;
+  int                     width, height;
+  glitz_rectangle_t       viewport;
+  glitz_bool_t            update_all;
+};
+
+#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;
@@ -251,96 +375,56 @@
 typedef struct _glitz_texture {
   glitz_gl_uint_t name;
   glitz_gl_enum_t target;
-  glitz_gl_enum_t format;
-  unsigned long flags;
+  glitz_gl_int_t  format;
+  unsigned long   flags;
   
   glitz_gl_enum_t filter;
   glitz_gl_enum_t wrap;
   
-  unsigned int width;
-  unsigned int height;
+  int             width;
+  int             height;
 
-  glitz_bounding_box_t box;
+  glitz_box_t     box;
   
-  glitz_float_t texcoord_width_unit;
-  glitz_float_t texcoord_height_unit;
+  glitz_float_t   texcoord_width_unit;
+  glitz_float_t   texcoord_height_unit;
 } glitz_texture_t;
 
 struct _glitz_buffer {
-  glitz_gl_uint_t name;
-  glitz_gl_enum_t target;
-  void *data;
-  int owns_data;
-  int ref_count;
-  glitz_surface_t *surface;
+  glitz_gl_uint_t  name;
+  glitz_gl_enum_t  target;
+  void             *data;
+  int              owns_data;
+  int              ref_count;
+  glitz_drawable_t *drawable;
 };
 
 typedef struct _glitz_geometry {
-  glitz_gl_enum_t primitive;
-  glitz_gl_enum_t type;
-  glitz_gl_int_t first;
+  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_buffer_t   *buffer;
+  glitz_float_t    x_offset;
+  glitz_float_t    y_offset;
   glitz_gl_float_t data[8];
 } glitz_geometry_t;
 
-typedef struct glitz_surface_backend {
-  glitz_surface_t *
-  (*create_similar) (void *surface,
-                     glitz_format_t *format,
-                     int width,
-                     int height);
-  
-  void
-  (*destroy) (void *surface);
-  
-  glitz_bool_t
-  (*push_current) (void *surface,
-                   glitz_constraint_t constraint);
-
-  void
-  (*pop_current) (void *surface);
-
-  glitz_texture_t *
-  (*get_texture) (void *surface,
-                  glitz_bool_t allocate);
-  
-  void
-  (*swap_buffers) (void *surface);
-
-  glitz_bool_t
-  (*make_current_read) (void *surface);
-
-  glitz_gl_proc_address_list_t gl;
-  glitz_format_t *formats;
-  int n_formats;
-  glitz_program_map_t *program_map;
-  unsigned long feature_mask;
-} glitz_surface_backend_t;
-
 #define GLITZ_SURFACE_FLAG_SOLID_MASK                   (1L <<  0)
-#define GLITZ_SURFACE_FLAG_OFFSCREEN_MASK               (1L <<  1)
-#define GLITZ_SURFACE_FLAG_REPEAT_MASK                  (1L <<  2)
-#define GLITZ_SURFACE_FLAG_MIRRORED_MASK                (1L <<  3)
-#define GLITZ_SURFACE_FLAG_PAD_MASK                     (1L <<  4)
-#define GLITZ_SURFACE_FLAG_DIRTY_MASK                   (1L <<  5)
-#define GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK         (1L <<  6)
-#define GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK             (1L <<  7)
-#define GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK      (1L <<  8)
-#define GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK             (1L <<  9)
-#define GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK          (1L << 10)
-#define GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK         (1L << 11)
-#define GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK (1L << 12)
-#define GLITZ_SURFACE_FLAG_DRAWABLE_MASK                (1L << 13)
-#define GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK             (1L << 14)
-#define GLITZ_SURFACE_FLAG_EYE_COORDS_MASK              (1L << 15)
-#define GLITZ_SURFACE_FLAG_TRANSFORM_MASK               (1L << 16)
-#define GLITZ_SURFACE_FLAG_PROJECTIVE_TRANSFORM_MASK    (1L << 17)
-
-#define SURFACE_OFFSCREEN(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_OFFSCREEN_MASK)
+#define GLITZ_SURFACE_FLAG_REPEAT_MASK                  (1L <<  1)
+#define GLITZ_SURFACE_FLAG_MIRRORED_MASK                (1L <<  2)
+#define GLITZ_SURFACE_FLAG_PAD_MASK                     (1L <<  3)
+#define GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK         (1L <<  4)
+#define GLITZ_SURFACE_FLAG_DITHER_MASK                  (1L <<  5)
+#define GLITZ_SURFACE_FLAG_MULTISAMPLE_MASK             (1L <<  6)
+#define GLITZ_SURFACE_FLAG_NICEST_MULTISAMPLE_MASK      (1L <<  7)
+#define GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK            (1L <<  8)
+#define GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK         (1L <<  9)
+#define GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK (1L << 10)
+#define GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK             (1L << 11)
+#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 SURFACE_SOLID(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_MASK)
@@ -356,23 +440,20 @@
   (((surface)->flags & GLITZ_SURFACE_FLAG_PAD_MASK) && \
    (!((surface)->flags & GLITZ_SURFACE_FLAG_IGNORE_WRAP_MASK)))
 
-#define SURFACE_DIRTY(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_DIRTY_MASK)
-
 #define SURFACE_COMPONENT_ALPHA(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_COMPONENT_ALPHA_MASK)
 
+#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_DIRTY(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DIRTY_MASK)
-
-#define SURFACE_DRAWABLE_DIRTY(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_DRAWABLE_DIRTY_MASK)
+#define SURFACE_SOLID_DAMAGE(surface) \
+  ((surface)->flags & GLITZ_SURFACE_FLAG_SOLID_DAMAGE_MASK)
 
 #define SURFACE_FRAGMENT_FILTER(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_FRAGMENT_FILTER_MASK)
@@ -380,9 +461,6 @@
 #define SURFACE_LINEAR_TRANSFORM_FILTER(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_LINEAR_TRANSFORM_FILTER_MASK)
 
-#define SURFACE_DRAWABLE(surface) \
-  ((surface)->flags & GLITZ_SURFACE_FLAG_DRAWABLE_MASK)
-
 #define SURFACE_EYE_COORDS(surface) \
   ((surface)->flags & GLITZ_SURFACE_FLAG_EYE_COORDS_MASK)
 
@@ -399,8 +477,8 @@
 
 typedef struct _glitz_multi_sample_info {
   glitz_sample_offset_t *offsets;
-  unsigned short *weights;
-  int n_samples;
+  unsigned short        *weights;
+  int                   n_samples;
 } glitz_sample_info_t;
 
 typedef struct _glitz_filter_params_t glitz_filter_params_t;
@@ -410,186 +488,194 @@
   glitz_float_t m[16];
 } glitz_matrix_t;
 
-#define GLITZ_UPDATE_VIEWPORT_MASK    (1L << 0)
-#define GLITZ_UPDATE_DRAW_BUFFER_MASK (1L << 1)
-#define GLITZ_UPDATE_MULTISAMPLE_MASK (1L << 2)
-#define GLITZ_UPDATE_ALL_MASK         ((1L << 3) - 1)
+#define GLITZ_DAMAGE_TEXTURE_MASK  (1 << 0)
+#define GLITZ_DAMAGE_DRAWABLE_MASK (1 << 1)
+#define GLITZ_DAMAGE_SOLID_MASK    (1 << 2)
 
 struct _glitz_surface {
-  glitz_surface_backend_t *backend;
-
-  int ref_count;
-  glitz_format_t *format;
-  glitz_texture_t texture;
-  unsigned long status_mask;
-  unsigned long update_mask;
-  glitz_filter_t filter;
+  int                   ref_count;
+  glitz_format_t        *format;
+  glitz_texture_t       texture;
+  glitz_drawable_t      *drawable;
+  glitz_drawable_t      *attached;
+  unsigned long         status_mask;
+  glitz_filter_t        filter;
   glitz_filter_params_t *filter_params;
-  glitz_matrix_t *transform;
-  int width, height;
-  glitz_bounding_box_t dirty_box;
-  unsigned long flags;
-  glitz_gl_enum_t draw_buffer;
-  glitz_gl_enum_t read_buffer;
-  glitz_sample_info_t *indirect;
-  glitz_color_t solid;
-  glitz_geometry_t geometry;
+  glitz_matrix_t        *transform;
+  int                   x, y;
+  int                   width, height;
+  glitz_gl_enum_t       buffer;
+  unsigned long         flags;
+  glitz_sample_info_t   *indirect;
+  glitz_color_t         solid;
+  glitz_geometry_t      geometry;
+  glitz_region_t        texture_damage;
+  glitz_region_t        drawable_damage;
 };
 
+#define GLITZ_GL_SURFACE(surface) \
+  glitz_gl_proc_address_list_t *gl = &(surface)->drawable->backend->gl;
+
 typedef struct _glitz_composite_op_t glitz_composite_op_t;
 
 typedef void (*glitz_combine_function_t) (glitz_composite_op_t *);
 
 typedef struct _glitz_combine_t {
-  glitz_combine_type_t type;
+  glitz_combine_type_t     type;
   glitz_combine_function_t enable;
-  int texture_units;
-  int fragment_processing;
+  int                      texture_units;
+  int                      fragment_processing;
 } glitz_combine_t;
 
 struct _glitz_composite_op_t {
-  glitz_combine_type_t type;
-  glitz_combine_t *combine;
+  glitz_combine_type_t         type;
+  glitz_combine_t              *combine;
   glitz_gl_proc_address_list_t *gl;
-  glitz_operator_t render_op;
-  glitz_surface_t *src;
-  glitz_surface_t *mask;
-  glitz_surface_t *dst;
-  glitz_color_t *solid;
-  glitz_color_t alpha_mask;
-  int per_component;
-  glitz_gl_uint_t fp;
-  int count;
+  glitz_operator_t             render_op;
+  glitz_surface_t              *src;
+  glitz_surface_t              *mask;
+  glitz_surface_t              *dst;
+  glitz_color_t                *solid;
+  glitz_color_t                alpha_mask;
+  int                          per_component;
+  glitz_gl_uint_t              fp;
+  int                          count;
 };
 
 typedef struct _glitz_extension_map {
   glitz_gl_float_t version;
-  char *name;
-  int mask;
+  char             *name;
+  int              mask;
 } glitz_extension_map;
 
 extern void __internal_linkage
-glitz_set_operator (glitz_gl_proc_address_list_t *gl, glitz_operator_t op);
-
-void
-glitz_intersect_bounding_box (glitz_bounding_box_t *box1,
-                              glitz_bounding_box_t *box2,
-                              glitz_bounding_box_t *return_box);
-
-extern void __internal_linkage
-glitz_union_bounding_box (glitz_bounding_box_t *box1,
-                          glitz_bounding_box_t *box2,
-                          glitz_bounding_box_t *return_box);
+glitz_set_operator (glitz_gl_proc_address_list_t *gl,
+                    glitz_operator_t             op);
 
 unsigned long
-glitz_extensions_query (glitz_gl_float_t version,
-                        const char *extensions_string,
+glitz_extensions_query (glitz_gl_float_t    version,
+                        const char          *extensions_string,
                         glitz_extension_map *extensions_map);
 
+typedef glitz_function_pointer_t (* glitz_get_proc_address_proc_t)
+     (const char *name, void *closure);
+
+void
+glitz_backend_init (glitz_backend_t               *backend,
+                    glitz_get_proc_address_proc_t get_proc_address,
+                    void                          *closure);
+
 extern unsigned int __internal_linkage
 glitz_uint_to_power_of_two (unsigned int x);
 
 extern void __internal_linkage
 glitz_set_raster_pos (glitz_gl_proc_address_list_t *gl,
-                      int x,
-                      int y);
+                      int                          x,
+                      int                          y);
 
 extern void __internal_linkage
 glitz_clamp_value (glitz_float_t *value,
-                   glitz_float_t min, glitz_float_t max);
+                   glitz_float_t min,
+                   glitz_float_t max);
+
+void
+glitz_initiate_state (glitz_gl_proc_address_list_t *gl);
+
+void
+glitz_create_surface_formats (glitz_gl_proc_address_list_t *gl,
+                              glitz_format_t               **formats,
+                              glitz_gl_int_t               **texture_formats,
+                              int                          *n_formats);
+
+glitz_drawable_format_t *
+glitz_drawable_format_find (glitz_drawable_format_t       *formats,
+                            int                           n_formats,
+                            unsigned long                 mask,
+                            const glitz_drawable_format_t *templ,
+                            int                           count);
 
 void
 glitz_texture_init (glitz_texture_t *texture,
-                    unsigned int width,
-                    unsigned int height,
-                    unsigned int texture_format,
-                    unsigned long feature_mask);
+                    int             width,
+                    int             height,
+                    glitz_gl_int_t  texture_format,
+                    unsigned long   feature_mask);
 
 void
 glitz_texture_fini (glitz_gl_proc_address_list_t *gl,
-                    glitz_texture_t *texture);
+                    glitz_texture_t              *texture);
 
 void
 glitz_texture_size_check (glitz_gl_proc_address_list_t *gl,
-                          glitz_texture_t *texture,
-                          glitz_gl_int_t max_2d,
-                          glitz_gl_int_t max_rect);
+                          glitz_texture_t              *texture,
+                          glitz_gl_int_t               max_2d,
+                          glitz_gl_int_t               max_rect);
 
 void
 glitz_texture_allocate (glitz_gl_proc_address_list_t *gl,
-                        glitz_texture_t *texture);
+                        glitz_texture_t              *texture);
 
 extern void __internal_linkage
 glitz_texture_ensure_filter (glitz_gl_proc_address_list_t *gl,
-                             glitz_texture_t *texture,
-                             glitz_filter_t filter);
+                             glitz_texture_t              *texture,
+                             glitz_filter_t               filter);
 
 extern void __internal_linkage
 glitz_texture_ensure_wrap (glitz_gl_proc_address_list_t *gl,
-                           glitz_texture_t *texture,
-                           glitz_gl_enum_t wrap);
+                           glitz_texture_t              *texture,
+                           glitz_gl_enum_t              wrap);
 
 void
 glitz_texture_bind (glitz_gl_proc_address_list_t *gl,
-                    glitz_texture_t *texture);
+                    glitz_texture_t              *texture);
 
 void
 glitz_texture_unbind (glitz_gl_proc_address_list_t *gl,
-                      glitz_texture_t *texture);
+                      glitz_texture_t              *texture);
 
 void
-glitz_texture_copy_surface (glitz_texture_t *texture,
-                            glitz_surface_t *surface,
-                            int x_surface,
-                            int y_surface,
-                            int width,
-                            int height,
-                            int x_texture,
-                            int y_texture);
+glitz_texture_copy_drawable (glitz_gl_proc_address_list_t *gl,
+                             glitz_texture_t              *texture,
+                             glitz_drawable_t             *drawable,
+                             int                          x_drawable,
+                             int                          y_drawable,
+                             int                          width,
+                             int                          height,
+                             int                          x_texture,
+                             int                          y_texture);
 
 void
 glitz_texture_set_tex_gen (glitz_gl_proc_address_list_t *gl,
-                           glitz_texture_t *texture,
-                           int x_src,
-                           int y_src,
-                           unsigned long flags);
-
-void
-glitz_surface_init (glitz_surface_t *surface,
-                    glitz_surface_backend_t *backend,
-                    glitz_format_t *format,
-                    int width,
-                    int height);
-
-void
-glitz_surface_fini (glitz_surface_t *surface);
+                           glitz_texture_t              *texture,
+                           int                          x_src,
+                           int                          y_src,
+                           unsigned long                flags);
 
 extern glitz_texture_t *__internal_linkage
 glitz_surface_get_texture (glitz_surface_t *surface,
-                           glitz_bool_t allocate);
+                           glitz_bool_t    allocate);
 
 extern void __internal_linkage
-glitz_surface_ensure_solid (glitz_surface_t *surface);
+glitz_surface_sync_solid (glitz_surface_t *surface);
 
-glitz_bool_t
-glitz_surface_push_current (glitz_surface_t *surface,
+extern glitz_bool_t __internal_linkage
+glitz_surface_push_current (glitz_surface_t    *surface,
                             glitz_constraint_t constraint);
 
-void
+extern void __internal_linkage
 glitz_surface_pop_current (glitz_surface_t *surface);
 
-extern glitz_bool_t __internal_linkage
+extern glitz_status_t __internal_linkage
 glitz_surface_make_current_read (glitz_surface_t *surface);
 
 extern void __internal_linkage
-glitz_surface_dirty (glitz_surface_t *surface,
-                     glitz_bounding_box_t *box);
+glitz_surface_damage (glitz_surface_t *surface,
+                      glitz_box_t     *box,
+                      int             what);
 
 extern void __internal_linkage
-glitz_surface_status_add (glitz_surface_t *surface, int flags);
-
-void
-glitz_surface_update_state (glitz_surface_t *surface);
+glitz_surface_status_add (glitz_surface_t *surface,
+                          int             flags);
 
 extern unsigned long __internal_linkage
 glitz_status_to_status_mask (glitz_status_t status);
@@ -597,48 +683,24 @@
 extern glitz_status_t __internal_linkage
 glitz_status_pop_from_mask (unsigned long *mask);
 
-typedef void (*glitz_format_call_back_t) (glitz_format_t *, void *ptr);
-
-void
-glitz_format_for_each_texture_format (glitz_format_call_back_t call_back,
-                                      glitz_gl_proc_address_list_t *gl,
-                                      void *ptr);
-
-glitz_format_t *
-glitz_format_find (glitz_format_t *formats,
-                   int n_formats,
-                   unsigned long mask,
-                   const glitz_format_t *templ,
-                   int count);
-
-glitz_format_t *
-glitz_format_find_standard (glitz_format_t *formats,
-                            int n_formats,
-                            glitz_format_name_t format_name);
-
-extern glitz_gl_int_t __internal_linkage
-glitz_format_get_best_texture_format (glitz_format_t *formats,
-                                      int n_formats,
-                                      glitz_format_t *format);
-
 void
 glitz_program_map_init (glitz_program_map_t *map);
      
 void
 glitz_program_map_fini (glitz_gl_proc_address_list_t *gl,
-                        glitz_program_map_t *map);
+                        glitz_program_map_t          *map);
 
 extern glitz_gl_uint_t __internal_linkage
 glitz_get_fragment_program (glitz_composite_op_t *op,
-                            int fp_type,
-                            int id);
+                            int                  fp_type,
+                            int                  id);
 
 extern void __internal_linkage
 glitz_composite_op_init (glitz_composite_op_t *op,
-                         glitz_operator_t render_op,
-                         glitz_surface_t *src,
-                         glitz_surface_t *mask,
-                         glitz_surface_t *dst);
+                         glitz_operator_t     render_op,
+                         glitz_surface_t      *src,
+                         glitz_surface_t      *mask,
+                         glitz_surface_t      *dst);
 
 extern void __internal_linkage
 glitz_composite_enable (glitz_composite_op_t *op);
@@ -647,53 +709,54 @@
 glitz_composite_disable (glitz_composite_op_t *op);
 
 extern void *__internal_linkage
-glitz_buffer_bind (glitz_buffer_t *buffer,
+glitz_buffer_bind (glitz_buffer_t  *buffer,
                    glitz_gl_enum_t target);
 
 extern void __internal_linkage
 glitz_buffer_unbind (glitz_buffer_t *buffer);
 
 extern glitz_status_t __internal_linkage
-glitz_filter_set_params (glitz_surface_t *surface,
-                         glitz_filter_t filter,
+glitz_filter_set_params (glitz_surface_t    *surface,
+                         glitz_filter_t     filter,
                          glitz_fixed16_16_t *params,
-                         int n_params);
+                         int                n_params);
 
 extern void __internal_linkage
 glitz_filter_set_type (glitz_surface_t *surface,
-                       glitz_filter_t filter);
+                       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_filter_get_vertex_program (glitz_surface_t      *surface,
                                  glitz_composite_op_t *op);
 
 extern glitz_gl_uint_t __internal_linkage
-glitz_filter_get_fragment_program (glitz_surface_t *surface,
+glitz_filter_get_fragment_program (glitz_surface_t      *surface,
                                    glitz_composite_op_t *op);
 
 extern void __internal_linkage
-glitz_filter_enable (glitz_surface_t *surface,
+glitz_filter_enable (glitz_surface_t      *surface,
                      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_bounding_box_t *box);
+                               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_bounding_box_t *box);
+                       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_surface_t              *dst);
+
 
 #define MAXSHORT SHRT_MAX
 #define MINSHORT SHRT_MIN
@@ -768,26 +831,31 @@
 
 #define POWER_OF_TWO(v) ((v & (v - 1)) == 0)
 
-typedef void (*glitz_function_pointer_t) (void);
-
 
 /* Avoid unnecessary PLT entries.  */
 
-slim_hidden_proto(glitz_surface_find_similar_standard_format)
+slim_hidden_proto(glitz_find_similar_drawable_format)
+slim_hidden_proto(glitz_create_pbuffer_drawable)
+slim_hidden_proto(glitz_drawable_get_width)
+slim_hidden_proto(glitz_drawable_get_height)
+slim_hidden_proto(glitz_drawable_swap_buffers)
+slim_hidden_proto(glitz_drawable_swap_buffers)
+slim_hidden_proto(glitz_drawable_flush)
+slim_hidden_proto(glitz_drawable_finish)
+slim_hidden_proto(glitz_drawable_get_features)
+slim_hidden_proto(glitz_drawable_get_format)
 slim_hidden_proto(glitz_surface_set_transform)
 slim_hidden_proto(glitz_surface_set_fill)
 slim_hidden_proto(glitz_surface_set_component_alpha)
+slim_hidden_proto(glitz_surface_set_dither)
 slim_hidden_proto(glitz_surface_set_filter)
 slim_hidden_proto(glitz_surface_get_width)
 slim_hidden_proto(glitz_surface_get_height)
-slim_hidden_proto(glitz_surface_set_read_color_buffer)
-slim_hidden_proto(glitz_surface_set_draw_color_buffer)
 slim_hidden_proto(glitz_surface_flush)
-slim_hidden_proto(glitz_surface_swap_buffers)
-slim_hidden_proto(glitz_surface_finish)
 slim_hidden_proto(glitz_surface_get_status)
-slim_hidden_proto(glitz_surface_get_features)
 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_set_rectangle)
 slim_hidden_proto(glitz_set_rectangles)
 slim_hidden_proto(glitz_set_geometry)




More information about the cairo-commit mailing list