
/*
 * Mesa 3-D graphics library
 * Version:  6.5
 *
 * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Keith Whitwell <keith@tungstengraphics.com>
 */

/* Split indexed primitives with per-vertex copying.
 */

#include "main/glheader.h"
#include "main/imports.h"
#include "main/macros.h"
#include "main/enums.h"
#include "main/mtypes.h"

#include "vbo_split.h"
#include "vbo.h"


#define ELT_TABLE_SIZE 16

/* Used for vertex-level splitting of indexed buffers.  Note that
 * non-indexed primitives may be converted to indexed in some cases
 * (eg loops, fans) in order to use this splitting path.
 */
struct copy_context {

   GLcontext *ctx;
   const struct gl_client_array **array;
   const struct _mesa_prim *prim;
   GLuint nr_prims;
   const struct _mesa_index_buffer *ib;
   vbo_draw_func draw;

   const struct split_limits *limits;

   struct {
      GLuint attr;
      GLuint size;
      const struct gl_client_array *array;
      const GLubyte *src_ptr;

      struct gl_client_array dstarray;

   } varying[VERT_ATTRIB_MAX];
   GLuint nr_varying;

   const struct gl_client_array *dstarray_ptr[VERT_ATTRIB_MAX];
   struct _mesa_index_buffer dstib;

   GLuint *translated_elt_buf;
   const GLuint *srcelt;

   /* A baby hash table to avoid re-emitting (some) duplicate
    * vertices when splitting indexed primitives.
    */
   struct { 
      GLuint in;
      GLuint out;
   } vert_cache[ELT_TABLE_SIZE];
      

   GLuint vertex_size;
   GLubyte *dstbuf;
   GLubyte *dstptr;		/* dstptr == dstbuf + dstelt_max * vertsize */
   GLuint dstbuf_size;	/* in vertices */
   GLuint dstbuf_nr;		/* count of emitted vertices, also the
				 * largest value in dstelt.  Our
				 * MaxIndex.
				 */

   GLuint *dstelt;
   GLuint dstelt_nr;
   GLuint dstelt_size;

#define MAX_PRIM 32
   struct _mesa_prim dstprim[MAX_PRIM];
   GLuint dstprim_nr;

};


static GLuint type_size( GLenum type )
{
   switch(type) {
   case GL_BYTE: return sizeof(GLbyte);
   case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
   case GL_SHORT: return sizeof(GLshort);
   case GL_UNSIGNED_SHORT: return sizeof(GLushort);
   case GL_INT: return sizeof(GLint);
   case GL_UNSIGNED_INT: return sizeof(GLuint);
   case GL_FLOAT: return sizeof(GLfloat);
   case GL_DOUBLE: return sizeof(GLdouble);
   default: return 0;
   }
}

static GLuint attr_size( const struct gl_client_array *array )
{
   return array->Size * type_size(array->Type);
}


/* Starts returning true slightly before the buffer fills, to ensure
 * that there is sufficient room for any remaining vertices to finish
 * off the prim:
 */
static GLboolean check_flush( struct copy_context *copy )
{
   GLenum mode = copy->dstprim[copy->dstprim_nr].mode; 

   if (GL_TRIANGLE_STRIP == mode &&
       copy->dstelt_nr & 1) { /* see bug9962 */
       return GL_FALSE;
   }

   if (copy->dstbuf_nr + 4 > copy->dstbuf_size)
      return GL_TRUE;

   if (copy->dstelt_nr + 4 > copy->dstelt_size)
      return GL_TRUE;

   return GL_FALSE;
}

static void flush( struct copy_context *copy )
{
   GLuint i;

   /* Set some counters: 
    */
   copy->dstib.count = copy->dstelt_nr;

   copy->draw( copy->ctx,
	       copy->dstarray_ptr,
	       copy->dstprim,
	       copy->dstprim_nr,
	       &copy->dstib,
	       0,
	       copy->dstbuf_nr );

   /* Reset all pointers: 
    */
   copy->dstprim_nr = 0;
   copy->dstelt_nr = 0;
   copy->dstbuf_nr = 0;
   copy->dstptr = copy->dstbuf;

   /* Clear the vertex cache:
    */
   for (i = 0; i < ELT_TABLE_SIZE; i++)
      copy->vert_cache[i].in = ~0;
}



static void begin( struct copy_context *copy, GLenum mode, GLboolean begin_flag )
{
   struct _mesa_prim *prim = &copy->dstprim[copy->dstprim_nr];

/*    _mesa_printf("begin %s (%d)\n", _mesa_lookup_enum_by_nr(mode), begin_flag); */
		
   prim->mode = mode;
   prim->begin = begin_flag;
}


/* Use a hashtable to attempt to identify recently-emitted vertices
 * and avoid re-emitting them.
 */
static GLuint elt(struct copy_context *copy, GLuint elt_idx)
{
   GLuint elt = copy->srcelt[elt_idx];
   GLuint slot = elt & (ELT_TABLE_SIZE-1);

/*    _mesa_printf("elt %d\n", elt); */

   /* Look up the incoming element in the vertex cache.  Re-emit if
    * necessary.   
    */
   if (copy->vert_cache[slot].in != elt) {
      GLubyte *csr = copy->dstptr;
      GLuint i;

/*       _mesa_printf("  --> emit to dstelt %d\n", copy->dstbuf_nr); */

      for (i = 0; i < copy->nr_varying; i++) {
	 const struct gl_client_array *srcarray = copy->varying[i].array;
	 const GLubyte *srcptr = copy->varying[i].src_ptr + elt * srcarray->StrideB;

	 memcpy(csr, srcptr, copy->varying[i].size);
	 csr += copy->varying[i].size;

	 if (0) 
	 {
	    const GLuint *f = (const GLuint *)srcptr;
	    GLuint j;
	    _mesa_printf("  varying %d: ", i);
	    for(j = 0; j < copy->varying[i].size / 4; j++)
	       _mesa_printf("%x ", f[j]);
	    _mesa_printf("\n");
	 }
	       
      }

      copy->vert_cache[slot].in = elt;
      copy->vert_cache[slot].out = copy->dstbuf_nr++;
      copy->dstptr += copy->vertex_size;

      assert(csr == copy->dstptr);
      assert(copy->dstptr == (copy->dstbuf + 
				    copy->dstbuf_nr * 
				    copy->vertex_size));
   }
/*    else */
/*       _mesa_printf("  --> reuse vertex\n"); */
   
/*    _mesa_printf("  --> emit %d\n", copy->vert_cache[slot].out); */
   copy->dstelt[copy->dstelt_nr++] = copy->vert_cache[slot].out;
   return check_flush(copy);
}

static void end( struct copy_context *copy, GLboolean end_flag )
{
   struct _mesa_prim *prim = &copy->dstprim[copy->dstprim_nr];

/*    _mesa_printf("end (%d)\n", end_flag); */

   prim->end = end_flag;
   prim->count = copy->dstelt_nr - prim->start;

   if (++copy->dstprim_nr == MAX_PRIM ||
       check_flush(copy)) 
      flush(copy);
}



static void replay_elts( struct copy_context *copy )
{
   GLuint i, j, k;
   GLboolean split;

   for (i = 0; i < copy->nr_prims; i++) {
      const struct _mesa_prim *prim = &copy->prim[i];
      const GLuint start = prim->start;
      GLuint first, incr;

      switch (prim->mode) {
	 
      case GL_LINE_LOOP:
	 /* Convert to linestrip and emit the final vertex explicitly,
	  * but only in the resultant strip that requires it.
	  */
	 j = 0;
	 while (j != prim->count) {
	    begin(copy, GL_LINE_STRIP, prim->begin && j == 0);

	    for (split = GL_FALSE; j != prim->count && !split; j++)
	       split = elt(copy, start + j);

	    if (j == prim->count) {
	       /* Done, emit final line.  Split doesn't matter as
		* it is always raised a bit early so we can emit
		* the last verts if necessary!
		*/
	       if (prim->end) 
		  (void)elt(copy, start + 0);

	       end(copy, prim->end);
	    }
	    else {
	       /* Wrap
		*/
	       assert(split);
	       end(copy, 0);
	       j--;
	    }
	 }
	 break;

      case GL_TRIANGLE_FAN:
      case GL_POLYGON:
	 j = 2;
	 while (j != prim->count) {
	    begin(copy, prim->mode, prim->begin && j == 0);

	    split = elt(copy, start+0); 
	    assert(!split);

	    split = elt(copy, start+j-1); 
	    assert(!split);

	    for (; j != prim->count && !split; j++)
	       split = elt(copy, start+j);

	    end(copy, prim->end && j == prim->count);

	    if (j != prim->count) {
	       /* Wrapped the primitive, need to repeat some vertices:
		*/
	       j -= 1;
	    }
	 }
	 break;

      default:
	 (void)split_prim_inplace(prim->mode, &first, &incr);
	 
	 j = 0;
	 while (j != prim->count) {

	    begin(copy, prim->mode, prim->begin && j == 0);

	    split = 0;
	    for (k = 0; k < first; k++, j++)
	       split |= elt(copy, start+j);

	    assert(!split);

	    for (; j != prim->count && !split; )
	       for (k = 0; k < incr; k++, j++)
		  split |= elt(copy, start+j);

	    end(copy, prim->end && j == prim->count);

	    if (j != prim->count) {
	       /* Wrapped the primitive, need to repeat some vertices:
		*/
	       assert(j > first - incr);
	       j -= (first - incr);
	    }
	 }
	 break;
      }
   }

   if (copy->dstprim_nr)
      flush(copy);
}


static void replay_init( struct copy_context *copy )
{
   GLcontext *ctx = copy->ctx;
   GLuint i;
   GLuint offset;
   const GLvoid *srcptr;

   /* Make a list of varying attributes and their vbo's.  Also
    * calculate vertex size.
    */
   copy->vertex_size = 0;
   for (i = 0; i < VERT_ATTRIB_MAX; i++) {
      struct gl_buffer_object *vbo = copy->array[i]->BufferObj;

      if (copy->array[i]->StrideB == 0) {
	 copy->dstarray_ptr[i] = copy->array[i];
      }
      else {
	 GLuint j = copy->nr_varying++;
	 
	 copy->varying[j].attr = i;
	 copy->varying[j].array = copy->array[i];
	 copy->varying[j].size = attr_size(copy->array[i]);
	 copy->vertex_size += attr_size(copy->array[i]);
      
	 if (vbo->Name && !vbo->Pointer) 
	    ctx->Driver.MapBuffer(ctx,
				  GL_ARRAY_BUFFER_ARB, 
				  GL_WRITE_ONLY, /* XXX */
				  vbo);

	 copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer,
						 copy->array[i]->Ptr);

	 copy->dstarray_ptr[i] = &copy->varying[j].dstarray;
      }
   }

   /* There must always be an index buffer.  Currently require the
    * caller convert non-indexed prims to indexed.  Could alternately
    * do it internally.
    */
   if (copy->ib->obj->Name && !copy->ib->obj->Pointer) 
      ctx->Driver.MapBuffer(ctx, 
			    GL_ARRAY_BUFFER_ARB, /* XXX */
			    GL_WRITE_ONLY, /* XXX */
			    copy->ib->obj);

   srcptr = (const GLubyte *)ADD_POINTERS(copy->ib->obj->Pointer, copy->ib->ptr);

   switch (copy->ib->type) {
   case GL_UNSIGNED_BYTE:
      copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count);
      copy->srcelt = copy->translated_elt_buf;

      for (i = 0; i < copy->ib->count; i++)
	 copy->translated_elt_buf[i] = ((const GLubyte *)srcptr)[i];
      break;

   case GL_UNSIGNED_SHORT:
      copy->translated_elt_buf = _mesa_malloc(sizeof(GLuint) * copy->ib->count);
      copy->srcelt = copy->translated_elt_buf;

      for (i = 0; i < copy->ib->count; i++)
	 copy->translated_elt_buf[i] = ((const GLushort *)srcptr)[i];
      break;

   case GL_UNSIGNED_INT:
      copy->translated_elt_buf = NULL;
      copy->srcelt = (const GLuint *)srcptr;
      break;
   }
   

   /* Figure out the maximum allowed vertex buffer size:
    */
   if (copy->vertex_size * copy->limits->max_verts <= copy->limits->max_vb_size) {
      copy->dstbuf_size = copy->limits->max_verts;
   }
   else {
      copy->dstbuf_size = copy->limits->max_vb_size / copy->vertex_size;
   }

   /* Allocate an output vertex buffer:
    *
    * XXX:  This should be a VBO!
    */
   copy->dstbuf = _mesa_malloc(copy->dstbuf_size * 
			       copy->vertex_size);   
   copy->dstptr = copy->dstbuf;

   /* Setup new vertex arrays to point into the output buffer: 
    */
   for (offset = 0, i = 0; i < copy->nr_varying; i++) {
      const struct gl_client_array *src = copy->varying[i].array;
      struct gl_client_array *dst = &copy->varying[i].dstarray;

      dst->Size = src->Size;
      dst->Type = src->Type;
      dst->Stride = copy->vertex_size;
      dst->StrideB = copy->vertex_size;
      dst->Ptr = copy->dstbuf + offset;
      dst->Enabled = GL_TRUE;
      dst->Normalized = src->Normalized; 
      dst->BufferObj = ctx->Array.NullBufferObj;
      dst->_MaxElement = copy->dstbuf_size; /* may be less! */

      offset += copy->varying[i].size;
   }

   /* Allocate an output element list:
    */
   copy->dstelt_size = MIN2(65536,
			    copy->ib->count * 2 + 3);
   copy->dstelt_size = MIN2(copy->dstelt_size,
			    copy->limits->max_indices);
   copy->dstelt = _mesa_malloc(sizeof(GLuint) * copy->dstelt_size);
   copy->dstelt_nr = 0;

   /* Setup the new index buffer to point to the allocated element
    * list:
    */
   copy->dstib.count = 0;	/* duplicates dstelt_nr */
   copy->dstib.type = GL_UNSIGNED_INT;
   copy->dstib.obj = ctx->Array.NullBufferObj;
   copy->dstib.ptr = copy->dstelt;
}


static void replay_finish( struct copy_context *copy )
{
   GLcontext *ctx = copy->ctx;
   GLuint i;

   /* Free our vertex and index buffers: 
    */
   _mesa_free(copy->translated_elt_buf);
   _mesa_free(copy->dstbuf);
   _mesa_free(copy->dstelt);
   
   /* Unmap VBO's 
    */
   for (i = 0; i < copy->nr_varying; i++) {
      struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;

      if (vbo->Name && vbo->Pointer) 
	 ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, vbo);
   }

   /* Unmap index buffer:
    */
   if (copy->ib->obj->Name && copy->ib->obj->Pointer) {
      ctx->Driver.UnmapBuffer(ctx, 
			      GL_ARRAY_BUFFER_ARB, /* XXX */
			      copy->ib->obj);
   }
}

void vbo_split_copy( GLcontext *ctx,
		     const struct gl_client_array *arrays[],
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     vbo_draw_func draw,
		     const struct split_limits *limits )
{
   struct copy_context copy;
   GLuint i;

   memset(&copy, 0, sizeof(copy));

   /* Require indexed primitives:
    */
   assert(ib);
   
   copy.ctx = ctx;
   copy.array = arrays;
   copy.prim = prim;
   copy.nr_prims = nr_prims;
   copy.ib = ib;
   copy.draw = draw;
   copy.limits = limits;


   /* Clear the vertex cache:
    */
   for (i = 0; i < ELT_TABLE_SIZE; i++)
      copy.vert_cache[i].in = ~0;


   replay_init(&copy);
   replay_elts(&copy);
   replay_finish(&copy);
}
