Merge branch multiple-texture-rectangle into master
authorNeil Roberts <neil@linux.intel.com>
Wed, 7 Jan 2009 16:10:25 +0000 (16:10 +0000)
committerNeil Roberts <neil@linux.intel.com>
Wed, 7 Jan 2009 16:25:26 +0000 (16:25 +0000)
Bug 1289 - Draw multiple glyphs at once

The multiple-texture-rectangle branch adds a new Cogl texture function
called cogl_texture_multiple_rectangles which is used to draw multiple
rectangles out of a texture using a single GL call. This is
significantly faster than drawing the rectangles with individual calls
on some platforms. The Pango renderer now uses this to speed up
rendering.

The conflicts are just due to the whitespace fixes in cb569a5.

Conflicts:

clutter/cogl/gl/cogl-context.c
clutter/cogl/gl/cogl-context.h
clutter/cogl/gl/cogl-texture.c

1  2 
clutter/cogl/cogl-texture.h
clutter/cogl/gl/cogl-context.c
clutter/cogl/gl/cogl-context.h
clutter/cogl/gl/cogl-texture.c

Simple merge
@@@ -48,16 -48,18 +48,18 @@@ cogl_create_context (
    /* Init default values */
    _context->feature_flags = 0;
    _context->features_cached = FALSE;
 -  
 +
    _context->enable_flags = 0;
    _context->color_alpha = 255;
 -  
 +
    _context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
    _context->last_path = 0;
 -  
 +
    _context->texture_handles = NULL;
-   _context->texture_vertices_size = 0;
-   _context->texture_vertices = NULL;
+   _context->texture_vertices = g_array_new (FALSE, FALSE,
+                                             sizeof (CoglTextureGLVertex));
+   _context->texture_indices = g_array_new (FALSE, FALSE,
+                                            sizeof (GLushort));
  
    _context->fbo_handles = NULL;
    _context->draw_buffer = COGL_WINDOW_BUFFER;
@@@ -60,11 -60,17 +60,17 @@@ typedef struc
  
    /* Cache of inverse projection matrix */
    GLfloat           inverse_projection[16];
 -  
 +
    /* Textures */
    GArray            *texture_handles;
-   CoglTextureGLVertex *texture_vertices;
-   gulong               texture_vertices_size;
+   GArray              *texture_vertices;
+   GArray              *texture_indices;
+   /* The gl texture number that the above vertices apply to. This to
+      detect when a different slice is encountered so that the vertices
+      can be flushed */
+   GLuint               texture_current;
+   GLenum               texture_target;
+   GLenum               texture_wrap_mode;
  
    /* Framebuffer objects */
    GArray           *fbo_handles;
@@@ -2231,26 -2275,77 +2275,77 @@@ cogl_texture_multiple_rectangles (CoglH
    /* Make sure we got stuff to draw */
    if (tex->slice_gl_handles == NULL)
      return;
 -  
 +
    if (tex->slice_gl_handles->len == 0)
      return;
 -  
 +
-   if (tx1 == tx2 || ty1 == ty2)
-     return;
-   /* If there is only one GL texture and either the texture is NPOT
-      (no waste) or all of the coordinates are in the range [0,1] then
-      we can use hardware tiling */
-   if (tex->slice_gl_handles->len == 1
-       && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
-            && tex->gl_target == GL_TEXTURE_2D)
-           || (tx1 >= 0 && tx1 <= COGL_FIXED_1
-               && tx2 >= 0 && tx2 <= COGL_FIXED_1
-               && ty1 >= 0 && ty1 <= COGL_FIXED_1
-               && ty2 >= 0 && ty2 <= COGL_FIXED_1)))
-     _cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
+   /* Prepare GL state */
+   if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
+     enable_flags |= COGL_ENABLE_TEXTURE_RECT;
    else
-     _cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
+     enable_flags |= COGL_ENABLE_TEXTURE_2D;
+   if (ctx->color_alpha < 255
+       || tex->bitmap.format & COGL_A_BIT)
+     enable_flags |= COGL_ENABLE_BLEND;
+   if (ctx->enable_backface_culling)
+     enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+   cogl_enable (enable_flags);
+   g_array_set_size (ctx->texture_vertices, 0);
+   while (n_rects-- > 0)
+     {
+       if (verts[4] != verts[6] && verts[5] != verts[7])
+         {
+           /* If there is only one GL texture and either the texture is
+              NPOT (no waste) or all of the coordinates are in the
+              range [0,1] then we can use hardware tiling */
+           if (tex->slice_gl_handles->len == 1
+               && ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
+                    && tex->gl_target == GL_TEXTURE_2D)
+                   || (verts[4] >= 0 && verts[4] <= COGL_FIXED_1
+                       && verts[6] >= 0 && verts[6] <= COGL_FIXED_1
+                       && verts[5] >= 0 && verts[5] <= COGL_FIXED_1
+                       && verts[7] >= 0 && verts[7] <= COGL_FIXED_1)))
+             _cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
+                                    verts[4],verts[5], verts[6],verts[7]);
+           else
+             _cogl_texture_quad_sw (tex, verts[0],verts[1], verts[2],verts[3],
+                                    verts[4],verts[5], verts[6],verts[7]);
+         }
+       verts += 8;
+     }
+   _cogl_texture_flush_vertices ();
+ }
+ void
+ cogl_texture_rectangle (CoglHandle   handle,
+                       CoglFixed x1,
+                       CoglFixed y1,
+                       CoglFixed x2,
+                       CoglFixed y2,
+                       CoglFixed tx1,
+                       CoglFixed ty1,
+                       CoglFixed tx2,
+                       CoglFixed ty2)
+ {
+   CoglFixed verts[8];
+   verts[0] = x1;
+   verts[1] = y1;
+   verts[2] = x2;
+   verts[3] = y2;
+   verts[4] = tx1;
+   verts[5] = ty1;
+   verts[6] = tx2;
+   verts[7] = ty2;
+   cogl_texture_multiple_rectangles (handle, verts, 1);
  }
  
  void