📄 dlist.c
字号:
/*
* Mesa 3-D graphics library
* Version: 6.3
*
* Copyright (C) 1999-2004 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.
*/
/**
* \file dlist.c
* Display lists management functions.
*/
#include "glheader.h"
#include "imports.h"
#include "api_arrayelt.h"
#include "api_loopback.h"
#include "config.h"
#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
#include "arbprogram.h"
#include "program.h"
#endif
#include "attrib.h"
#include "blend.h"
#include "buffers.h"
#if FEATURE_ARB_vertex_buffer_object
#include "bufferobj.h"
#endif
#include "clip.h"
#include "colormac.h"
#include "colortab.h"
#include "context.h"
#include "convolve.h"
#include "depth.h"
#include "dlist.h"
#include "enable.h"
#include "enums.h"
#include "eval.h"
#include "extensions.h"
#include "feedback.h"
#include "get.h"
#include "glapi.h"
#include "hash.h"
#include "histogram.h"
#include "image.h"
#include "light.h"
#include "lines.h"
#include "dlist.h"
#include "macros.h"
#include "matrix.h"
#include "occlude.h"
#include "pixel.h"
#include "points.h"
#include "polygon.h"
#include "state.h"
#include "texobj.h"
#include "teximage.h"
#include "texstate.h"
#include "mtypes.h"
#include "varray.h"
#if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
#include "nvprogram.h"
#include "program.h"
#endif
#if FEATURE_ATI_fragment_shader
#include "atifragshader.h"
#endif
#include "math/m_matrix.h"
#include "math/m_xform.h"
#include "dispatch.h"
/**
* Flush vertices.
*
* \param ctx GL context.
*
* Checks if dd_function_table::SaveNeedFlush is marked to flush
* stored (save) vertices, and calls
* dd_function_table::SaveFlushVertices if so.
*/
#define SAVE_FLUSH_VERTICES(ctx) \
do { \
if (ctx->Driver.SaveNeedFlush) \
ctx->Driver.SaveFlushVertices(ctx); \
} while (0)
/**
* Macro to assert that the API call was made outside the
* glBegin()/glEnd() pair, with return value.
*
* \param ctx GL context.
* \param retval value to return value in case the assertion fails.
*/
#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval) \
do { \
if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
return retval; \
} \
} while (0)
/**
* Macro to assert that the API call was made outside the
* glBegin()/glEnd() pair.
*
* \param ctx GL context.
*/
#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \
do { \
if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \
ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \
return; \
} \
} while (0)
/**
* Macro to assert that the API call was made outside the
* glBegin()/glEnd() pair and flush the vertices.
*
* \param ctx GL context.
*/
#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \
do { \
ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \
SAVE_FLUSH_VERTICES(ctx); \
} while (0)
/**
* Macro to assert that the API call was made outside the
* glBegin()/glEnd() pair and flush the vertices, with return value.
*
* \param ctx GL context.
* \param retval value to return value in case the assertion fails.
*/
#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\
do { \
ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \
SAVE_FLUSH_VERTICES(ctx); \
} while (0)
/**
* Display list opcodes.
*
* The fact that these identifiers are assigned consecutive
* integer values starting at 0 is very important, see InstSize array usage)
*/
typedef enum {
OPCODE_INVALID = -1, /* Force signed enum */
OPCODE_ACCUM,
OPCODE_ALPHA_FUNC,
OPCODE_BIND_TEXTURE,
OPCODE_BITMAP,
OPCODE_BLEND_COLOR,
OPCODE_BLEND_EQUATION,
OPCODE_BLEND_EQUATION_SEPARATE,
OPCODE_BLEND_FUNC_SEPARATE,
OPCODE_CALL_LIST,
OPCODE_CALL_LIST_OFFSET,
OPCODE_CLEAR,
OPCODE_CLEAR_ACCUM,
OPCODE_CLEAR_COLOR,
OPCODE_CLEAR_DEPTH,
OPCODE_CLEAR_INDEX,
OPCODE_CLEAR_STENCIL,
OPCODE_CLIP_PLANE,
OPCODE_COLOR_MASK,
OPCODE_COLOR_MATERIAL,
OPCODE_COLOR_TABLE,
OPCODE_COLOR_TABLE_PARAMETER_FV,
OPCODE_COLOR_TABLE_PARAMETER_IV,
OPCODE_COLOR_SUB_TABLE,
OPCODE_CONVOLUTION_FILTER_1D,
OPCODE_CONVOLUTION_FILTER_2D,
OPCODE_CONVOLUTION_PARAMETER_I,
OPCODE_CONVOLUTION_PARAMETER_IV,
OPCODE_CONVOLUTION_PARAMETER_F,
OPCODE_CONVOLUTION_PARAMETER_FV,
OPCODE_COPY_COLOR_SUB_TABLE,
OPCODE_COPY_COLOR_TABLE,
OPCODE_COPY_PIXELS,
OPCODE_COPY_TEX_IMAGE1D,
OPCODE_COPY_TEX_IMAGE2D,
OPCODE_COPY_TEX_SUB_IMAGE1D,
OPCODE_COPY_TEX_SUB_IMAGE2D,
OPCODE_COPY_TEX_SUB_IMAGE3D,
OPCODE_CULL_FACE,
OPCODE_DEPTH_FUNC,
OPCODE_DEPTH_MASK,
OPCODE_DEPTH_RANGE,
OPCODE_DISABLE,
OPCODE_DRAW_BUFFER,
OPCODE_DRAW_PIXELS,
OPCODE_ENABLE,
OPCODE_EVALMESH1,
OPCODE_EVALMESH2,
OPCODE_FOG,
OPCODE_FRONT_FACE,
OPCODE_FRUSTUM,
OPCODE_HINT,
OPCODE_HISTOGRAM,
OPCODE_INDEX_MASK,
OPCODE_INIT_NAMES,
OPCODE_LIGHT,
OPCODE_LIGHT_MODEL,
OPCODE_LINE_STIPPLE,
OPCODE_LINE_WIDTH,
OPCODE_LIST_BASE,
OPCODE_LOAD_IDENTITY,
OPCODE_LOAD_MATRIX,
OPCODE_LOAD_NAME,
OPCODE_LOGIC_OP,
OPCODE_MAP1,
OPCODE_MAP2,
OPCODE_MAPGRID1,
OPCODE_MAPGRID2,
OPCODE_MATRIX_MODE,
OPCODE_MIN_MAX,
OPCODE_MULT_MATRIX,
OPCODE_ORTHO,
OPCODE_PASSTHROUGH,
OPCODE_PIXEL_MAP,
OPCODE_PIXEL_TRANSFER,
OPCODE_PIXEL_ZOOM,
OPCODE_POINT_SIZE,
OPCODE_POINT_PARAMETERS,
OPCODE_POLYGON_MODE,
OPCODE_POLYGON_STIPPLE,
OPCODE_POLYGON_OFFSET,
OPCODE_POP_ATTRIB,
OPCODE_POP_MATRIX,
OPCODE_POP_NAME,
OPCODE_PRIORITIZE_TEXTURE,
OPCODE_PUSH_ATTRIB,
OPCODE_PUSH_MATRIX,
OPCODE_PUSH_NAME,
OPCODE_RASTER_POS,
OPCODE_READ_BUFFER,
OPCODE_RESET_HISTOGRAM,
OPCODE_RESET_MIN_MAX,
OPCODE_ROTATE,
OPCODE_SCALE,
OPCODE_SCISSOR,
OPCODE_SELECT_TEXTURE_SGIS,
OPCODE_SELECT_TEXTURE_COORD_SET,
OPCODE_SHADE_MODEL,
OPCODE_STENCIL_FUNC,
OPCODE_STENCIL_MASK,
OPCODE_STENCIL_OP,
OPCODE_TEXENV,
OPCODE_TEXGEN,
OPCODE_TEXPARAMETER,
OPCODE_TEX_IMAGE1D,
OPCODE_TEX_IMAGE2D,
OPCODE_TEX_IMAGE3D,
OPCODE_TEX_SUB_IMAGE1D,
OPCODE_TEX_SUB_IMAGE2D,
OPCODE_TEX_SUB_IMAGE3D,
OPCODE_TRANSLATE,
OPCODE_VIEWPORT,
OPCODE_WINDOW_POS,
/* GL_ARB_multitexture */
OPCODE_ACTIVE_TEXTURE,
/* GL_SGIX/SGIS_pixel_texture */
OPCODE_PIXEL_TEXGEN_SGIX,
OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS,
/* GL_ARB_texture_compression */
OPCODE_COMPRESSED_TEX_IMAGE_1D,
OPCODE_COMPRESSED_TEX_IMAGE_2D,
OPCODE_COMPRESSED_TEX_IMAGE_3D,
OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
/* GL_ARB_multisample */
OPCODE_SAMPLE_COVERAGE,
/* GL_ARB_window_pos */
OPCODE_WINDOW_POS_ARB,
/* GL_NV_vertex_program */
OPCODE_BIND_PROGRAM_NV,
OPCODE_EXECUTE_PROGRAM_NV,
OPCODE_REQUEST_RESIDENT_PROGRAMS_NV,
OPCODE_LOAD_PROGRAM_NV,
OPCODE_PROGRAM_PARAMETER4F_NV,
OPCODE_TRACK_MATRIX_NV,
/* GL_NV_fragment_program */
OPCODE_PROGRAM_LOCAL_PARAMETER_ARB,
OPCODE_PROGRAM_NAMED_PARAMETER_NV,
/* GL_EXT_stencil_two_side */
OPCODE_ACTIVE_STENCIL_FACE_EXT,
/* GL_EXT_depth_bounds_test */
OPCODE_DEPTH_BOUNDS_EXT,
/* GL_ARB_vertex/fragment_program */
OPCODE_PROGRAM_STRING_ARB,
OPCODE_PROGRAM_ENV_PARAMETER_ARB,
/* GL_ARB_occlusion_query */
OPCODE_BEGIN_QUERY_ARB,
OPCODE_END_QUERY_ARB,
/* GL_ARB_draw_buffers */
OPCODE_DRAW_BUFFERS_ARB,
/* GL_ATI_fragment_shader */
OPCODE_BIND_FRAGMENT_SHADER_ATI,
OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI,
/* OpenGL 2.0 */
OPCODE_STENCIL_FUNC_SEPARATE,
OPCODE_STENCIL_OP_SEPARATE,
OPCODE_STENCIL_MASK_SEPARATE,
/* Vertex attributes -- fallback for when optimized display
* list build isn't active.
*/
OPCODE_ATTR_1F_NV,
OPCODE_ATTR_2F_NV,
OPCODE_ATTR_3F_NV,
OPCODE_ATTR_4F_NV,
OPCODE_ATTR_1F_ARB,
OPCODE_ATTR_2F_ARB,
OPCODE_ATTR_3F_ARB,
OPCODE_ATTR_4F_ARB,
OPCODE_MATERIAL,
OPCODE_INDEX,
OPCODE_EDGEFLAG,
OPCODE_BEGIN,
OPCODE_END,
OPCODE_RECTF,
OPCODE_EVAL_C1,
OPCODE_EVAL_C2,
OPCODE_EVAL_P1,
OPCODE_EVAL_P2,
/* The following three are meta instructions */
OPCODE_ERROR, /* raise compiled-in error */
OPCODE_CONTINUE,
OPCODE_END_OF_LIST,
OPCODE_EXT_0
} OpCode;
/**
* Display list node.
*
* Display list instructions are stored as sequences of "nodes". Nodes
* are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks
* are linked together with a pointer.
*
* Each instruction in the display list is stored as a sequence of
* contiguous nodes in memory.
* Each node is the union of a variety of data types.
*/
union node {
OpCode opcode;
GLboolean b;
GLbitfield bf;
GLubyte ub;
GLshort s;
GLushort us;
GLint i;
GLuint ui;
GLenum e;
GLfloat f;
GLvoid *data;
void *next; /* If prev node's opcode==OPCODE_CONTINUE */
};
/**
* How many nodes to allocate at a time.
*
* \note Reduced now that we hold vertices etc. elsewhere.
*/
#define BLOCK_SIZE 256
/**
* Number of nodes of storage needed for each instruction.
* Sizes for dynamically allocated opcodes are stored in the context struct.
*/
static GLuint InstSize[ OPCODE_END_OF_LIST+1 ];
void mesa_print_display_list( GLuint list );
/**********************************************************************/
/***** Private *****/
/**********************************************************************/
/*
* Make an empty display list. This is used by glGenLists() to
* reserver display list IDs.
*/
static struct mesa_display_list *make_list( GLuint list, GLuint count )
{
struct mesa_display_list *dlist = CALLOC_STRUCT( mesa_display_list );
dlist->id = list;
dlist->node = (Node *) MALLOC( sizeof(Node) * count );
dlist->node[0].opcode = OPCODE_END_OF_LIST;
return dlist;
}
/*
* Destroy all nodes in a display list.
* \param list - display list number
*/
void _mesa_destroy_list( GLcontext *ctx, GLuint list )
{
struct mesa_display_list *dlist;
Node *n, *block;
GLboolean done;
if (list==0)
return;
dlist = (struct mesa_display_list *) _mesa_HashLookup(ctx->Shared->DisplayList, list);
if (!dlist)
return;
n = block = dlist->node;
done = block ? GL_FALSE : GL_TRUE;
while (!done) {
/* check for extension opcodes first */
GLint i = (GLint) n[0].opcode - (GLint) OPCODE_EXT_0;
if (i >= 0 && i < (GLint) ctx->ListExt.NumOpcodes) {
ctx->ListExt.Opcode[i].Destroy(ctx, &n[1]);
n += ctx->ListExt.Opcode[i].Size;
}
else {
switch (n[0].opcode) {
/* for some commands, we need to free malloc'd memory */
case OPCODE_MAP1:
FREE(n[6].data);
n += InstSize[n[0].opcode];
break;
case OPCODE_MAP2:
FREE(n[10].data);
n += InstSize[n[0].opcode];
break;
case OPCODE_DRAW_PIXELS:
FREE( n[5].data );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -