/*
 * Copyright (C) 1997-2009, R3vis Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
 *
 * Original Contributor:
 *   Wes Bethel, R3vis Corporation, Marin County, California
 *   http://www.r3vis.com/
 * Additional Contributor(s):
 *
 * The OpenRM project is located at http://openrm.sourceforge.net/.
 */
/*
 * $Id: rmmultis.h,v 1.9 2005/06/26 18:54:16 wes Exp $
 * Version: $Name: v180-alpha-02 $
 * $Revision: 1.9 $
 * $Log: rmmultis.h,v $
 * Revision 1.9  2005/06/26 18:54:16  wes
 * New opcode consolidating  local state and OpenGL attrib stack push/pop.
 *
 * Revision 1.8  2005/06/06 02:04:29  wes
 * Lots of small additions to clean up compiler warnings.
 *
 * Revision 1.7  2005/02/24 16:17:25  wes
 * Added support for fbClears to be set at the RMpipe level. Apps can
 * still set them at the RMnode level if desired for fine-grained control.
 *
 * Revision 1.6  2005/02/19 16:22:50  wes
 * Distro sync and consolidation.
 *
 * Revision 1.5  2005/01/23 17:04:03  wes
 * Copyright update to 2005.
 *
 * Revision 1.4  2004/01/16 16:46:09  wes
 * Updated copyright line for 2004.
 *
 * Revision 1.3  2003/04/05 14:09:31  wes
 * Added prototypes for private RMpipe routines that clean up interstage buffers.
 *
 * Revision 1.2  2003/02/02 02:07:15  wes
 * Updated copyright to 2003.
 *
 * Revision 1.1.1.1  2003/01/28 02:15:23  wes
 * Manual rebuild of rm150 repository.
 *
 * Revision 1.6  2002/08/29 22:20:32  wes
 *
 * Massive upgrade to accommodate dynamic object reallocation within
 * the component manager, and within the context cache. Use the
 * debug #define DEBUG_LEVEL DEBUG_REALLOC_TRACE to get a printf
 * whenever a realloc occurs. With this upgrade, there are no
 * OpenRM limits on the size of the scene graph. There will be external
 * limits, such as the amount of RAM and the amount of space available
 * to your OpenGL implementation.
 *
 * Revision 1.5  2002/08/17 15:12:19  wes
 * Added #defines for render-stage pre- and post-traversal callbacks.
 *
 * Revision 1.4  2002/06/17 01:04:10  wes
 * Increased amount of space allocated for matrices to be the same
 * as RM_COMPONENT_POOL_SIZE. This is overkill.
 *
 * Revision 1.3  2002/06/02 15:15:34  wes
 * Added RMstateCache code to help eliminate the number of state changes
 * made during the render traversal. The RMstateCache tracks
 * the actual OpenGL rendering state w/o the need for querying OpenGL
 * directly, and  is queried by draw code that then decides if any
 * real state changes are required given the configuration of data
 * within an RMprimitive.
 *
 * Revision 1.2  2002/04/30 19:32:47  wes
 * Updated copyright dates.
 *
 * Revision 1.1  2001/03/31 17:12:11  wes
 * v1.4.0-alpha-2 checkin.
 *
 */

#ifndef __rmmtrend_h
#define __rmmtrend_h

#include "barrier.h"

/* 8/11/02 wes. MT_NUM_MATRIX_PAIRS is set to be RM_COMPONENT_POOL_SIZE
   inside the code in rmmtview.c via the extern global variable */
/* #define MT_NUM_MATRIX_PAIRS RM_COMPONENT_POOL_SIZE */
#define MT_MAX_STATE_STACK_SIZE 16


typedef enum
{
    MT_NOOP                      = 0x0,
    MT_PUSHATTRIB                = 0x01,
    MT_POPATTRIB                 = 0x02,
    MT_PUSHLOAD_MODELVIEW_MATRIX = 0x03,
    MT_POP_MODELVIEW_MATRIX      = 0x04,
    MT_PUSHLOAD_PROJ_MATRIX      = 0x05,
    MT_POP_PROJ_MATRIX           = 0x06,
    MT_PUSHLOAD_TEXTURE_MATRIX   = 0x07,
    MT_POP_TEXTURE_MATRIX        = 0x08,
    MT_DRAW                      = 0x09,
    MT_FBCLEAR                   = 0x0A,
    MT_PUSH_TEXTPROPS            = 0x0B,
    MT_POP_TEXTPROPS             = 0x0C,
    MT_PUSH_STATE                = 0x0D,
    MT_POP_STATE                 = 0x0E,
    MT_PRETRAVERSAL_FUNC         = 0x0F,
    MT_POSTTRAVERSAL_FUNC        = 0x10,
    MT_PUSH_STATE_ATTRIB         = 0x11, /* June 2005 */
    MT_POP_STATE_ATTRIB          = 0x12
} RMdisplayListOpcode;

typedef struct
{
    int nOpCodes, maxOpCodes;
    RMdisplayListOpcode *opCodes;

    int nIndices, maxIndices;
    int *indices;

    int nMatrices, maxMatrices;
    RMmatrix *matrices;
} RMdisplayList;

typedef struct
{
    /* double buffered, stereo-capable multipass display list buffers. */
    RMdisplayList *globals[2];
    RMdisplayList *opaque3D[2], *transparent3D[2], *opaque2D[2];
    RMdisplayList *rightGlobals[2];
    RMdisplayList *rightOpaque3D[2], *rightTransparent3D[2], *rightOpaque2D[2];
} RMmultipassDisplayList;

#define THREAD_WORK 0
#define THREAD_QUIT 1

typedef struct
{
    RMpipe *p;
    RMnode *n;
    int     commandOpcode;
    int     frameNumber;

    RMmatrix *initModel;
    RMmatrix *initView;
    RMmatrix *initProjection;
    RMmatrix *initTexture;

    barrier_t *one, *two;
} RMthreadArgs;

typedef struct
{
    int           nThreads;
    RMthread     *threadIDs;
    RMthreadArgs *args;
} RMmultiStageThreadControl;

/*#define MTWORKPARMS() (RMpipe *p, RMnode *n, RMstate *s, RMdisplayList *mt, int indx, RMstateCache *rsc) */
#define MTWORKPARMS() (RMpipe *p, RMnode *n, RMstate *s, int indx, RMstateCache *rsc)

void           private_rmPipeDisplayListsNew(RMpipe *p);
RMdisplayList *private_rmPipeDisplayListNew(int nOpcodes, int nIndices, int nMatrices);

void           private_rmPipeDisplayListDelete(RMdisplayList *t);
void           private_rmPipeDisplayListsDelete(RMpipe *p);

void           private_rmPipeDisplayListsInit(RMpipe *p, int evenOdd);

void           private_rmView (RMpipe *p, RMnode *n, int frameNumber, RMmatrix *initModelMatrix, RMmatrix *initViewMatrix, RMmatrix *initProjectionMatrix, RMmatrix *initTextureMatrix);

void           private_rmRender (RMpipe *p, int frameNumber);

void          *private_rmViewThreadFunc(void *args);
void          *private_rmRenderThreadFunc(void *args);

#define private_rmSelectEvenOddBuffer(a) (((a) & 1) ? 1 : 0)

#endif
/* EOF */
