📄 dlist.c
字号:
/* * 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. *//** * \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_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, /* GL_EXT_framebuffer_blit */ OPCODE_BLIT_FRAMEBUFFER, /* 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 * reserve 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 *) _mesa_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: _mesa_free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_MAP2: _mesa_free(n[10].data); n += InstSize[n[0].opcode]; break; case OPCODE_DRAW_PIXELS: _mesa_free(n[5].data); n += InstSize[n[0].opcode]; break; case OPCODE_BITMAP: _mesa_free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COLOR_TABLE: _mesa_free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_COLOR_SUB_TABLE: _mesa_free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_CONVOLUTION_FILTER_1D: _mesa_free(n[6].data); n += InstSize[n[0].opcode]; break; case OPCODE_CONVOLUTION_FILTER_2D: _mesa_free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_POLYGON_STIPPLE: _mesa_free(n[1].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE1D: _mesa_free(n[8].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE2D: _mesa_free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_IMAGE3D: _mesa_free(n[10].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE1D: _mesa_free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE2D: _mesa_free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_TEX_SUB_IMAGE3D: _mesa_free(n[11].data); n += InstSize[n[0].opcode]; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -