📄 dlist.c
字号:
case OPCODE_COMPRESSED_TEX_IMAGE_1D: _mesa_free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_2D: _mesa_free(n[8].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_IMAGE_3D: _mesa_free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: _mesa_free(n[7].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: _mesa_free(n[9].data); n += InstSize[n[0].opcode]; break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: _mesa_free(n[11].data); n += InstSize[n[0].opcode]; break;#if FEATURE_NV_vertex_program case OPCODE_LOAD_PROGRAM_NV: _mesa_free(n[4].data); /* program string */ n += InstSize[n[0].opcode]; break; case OPCODE_REQUEST_RESIDENT_PROGRAMS_NV: _mesa_free(n[2].data); /* array of program ids */ n += InstSize[n[0].opcode]; break;#endif#if FEATURE_NV_fragment_program case OPCODE_PROGRAM_NAMED_PARAMETER_NV: _mesa_free(n[3].data); /* parameter name */ n += InstSize[n[0].opcode]; break;#endif#if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program case OPCODE_PROGRAM_STRING_ARB: _mesa_free(n[4].data); /* program string */ n += InstSize[n[0].opcode]; break;#endif case OPCODE_CONTINUE: n = (Node *) n[1].next; _mesa_free(block); block = n; break; case OPCODE_END_OF_LIST: _mesa_free(block); done = GL_TRUE; break; default: /* Most frequent case */ n += InstSize[n[0].opcode]; break; } } } _mesa_free(dlist); _mesa_HashRemove(ctx->Shared->DisplayList, list);}/* * Translate the nth element of list from type to GLuint. */static GLuinttranslate_id(GLsizei n, GLenum type, const GLvoid * list){ GLbyte *bptr; GLubyte *ubptr; GLshort *sptr; GLushort *usptr; GLint *iptr; GLuint *uiptr; GLfloat *fptr; switch (type) { case GL_BYTE: bptr = (GLbyte *) list; return (GLuint) *(bptr + n); case GL_UNSIGNED_BYTE: ubptr = (GLubyte *) list; return (GLuint) *(ubptr + n); case GL_SHORT: sptr = (GLshort *) list; return (GLuint) *(sptr + n); case GL_UNSIGNED_SHORT: usptr = (GLushort *) list; return (GLuint) *(usptr + n); case GL_INT: iptr = (GLint *) list; return (GLuint) *(iptr + n); case GL_UNSIGNED_INT: uiptr = (GLuint *) list; return (GLuint) *(uiptr + n); case GL_FLOAT: fptr = (GLfloat *) list; return (GLuint) *(fptr + n); case GL_2_BYTES: ubptr = ((GLubyte *) list) + 2 * n; return (GLuint) *ubptr * 256 + (GLuint) * (ubptr + 1); case GL_3_BYTES: ubptr = ((GLubyte *) list) + 3 * n; return (GLuint) * ubptr * 65536 + (GLuint) *(ubptr + 1) * 256 + (GLuint) * (ubptr + 2); case GL_4_BYTES: ubptr = ((GLubyte *) list) + 4 * n; return (GLuint) *ubptr * 16777216 + (GLuint) *(ubptr + 1) * 65536 + (GLuint) *(ubptr + 2) * 256 + (GLuint) * (ubptr + 3); default: return 0; }}/**********************************************************************//***** Public *****//**********************************************************************//** * Wrapper for _mesa_unpack_image() that handles pixel buffer objects. * \todo This won't suffice when the PBO is really in VRAM/GPU memory. */static GLvoid *unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels, const struct gl_pixelstore_attrib *unpack){ if (unpack->BufferObj->Name == 0) { /* no PBO */ return _mesa_unpack_image(dimensions, width, height, depth, format, type, pixels, unpack); } else if (_mesa_validate_pbo_access (dimensions, unpack, width, height, depth, format, type, pixels)) { const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels); return _mesa_unpack_image(dimensions, width, height, depth, format, type, src, unpack); } /* bad access! */ return NULL;}/** * Allocate space for a display list instruction. * \param opcode the instruction opcode (OPCODE_* value) * \param size instruction size in bytes, not counting opcode. * \return pointer to the usable data area (not including the internal * opcode). */void *_mesa_alloc_instruction(GLcontext *ctx, GLuint opcode, GLuint bytes){ const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); Node *n; if (opcode < (GLuint) OPCODE_EXT_0) { if (InstSize[opcode] == 0) { /* save instruction size now */ InstSize[opcode] = numNodes; } else { /* make sure instruction size agrees */ ASSERT(numNodes == InstSize[opcode]); } } if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; n[0].opcode = OPCODE_CONTINUE; newblock = (Node *) _mesa_malloc(sizeof(Node) * BLOCK_SIZE); if (!newblock) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list"); return NULL; } n[1].next = (Node *) newblock; ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; } n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; ctx->ListState.CurrentPos += numNodes; n[0].opcode = (OpCode) opcode; return (void *) (n + 1); /* return ptr to node following opcode */}/** * This function allows modules and drivers to get their own opcodes * for extending display list functionality. * \param ctx the rendering context * \param size number of bytes for storing the new display list command * \param execute function to execute the new display list command * \param destroy function to destroy the new display list command * \param print function to print the new display list command * \return the new opcode number or -1 if error */GLint_mesa_alloc_opcode(GLcontext *ctx, GLuint size, void (*execute) (GLcontext *, void *), void (*destroy) (GLcontext *, void *), void (*print) (GLcontext *, void *)){ if (ctx->ListExt.NumOpcodes < MAX_DLIST_EXT_OPCODES) { const GLuint i = ctx->ListExt.NumOpcodes++; ctx->ListExt.Opcode[i].Size = 1 + (size + sizeof(Node) - 1) / sizeof(Node); ctx->ListExt.Opcode[i].Execute = execute; ctx->ListExt.Opcode[i].Destroy = destroy; ctx->ListExt.Opcode[i].Print = print; return i + OPCODE_EXT_0; } return -1;}/** * Allocate display list instruction. Returns Node ptr to where the opcode * is stored. * - nParams is the number of function parameters * - return value a pointer to sizeof(Node) before the actual * usable data area. */#define ALLOC_INSTRUCTION(CTX, OPCODE, NPARAMS) \ ((Node *)_mesa_alloc_instruction(CTX, OPCODE, (NPARAMS)*sizeof(Node)) - 1)/* * Display List compilation functions */static void GLAPIENTRYsave_Accum(GLenum op, GLfloat value){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_ACCUM, 2); if (n) { n[1].e = op; n[2].f = value; } if (ctx->ExecuteFlag) { CALL_Accum(ctx->Exec, (op, value)); }}static void GLAPIENTRYsave_AlphaFunc(GLenum func, GLclampf ref){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_ALPHA_FUNC, 2); if (n) { n[1].e = func; n[2].f = (GLfloat) ref; } if (ctx->ExecuteFlag) { CALL_AlphaFunc(ctx->Exec, (func, ref)); }}static void GLAPIENTRYsave_BindTexture(GLenum target, GLuint texture){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BIND_TEXTURE, 2); if (n) { n[1].e = target; n[2].ui = texture; } if (ctx->ExecuteFlag) { CALL_BindTexture(ctx->Exec, (target, texture)); }}static void GLAPIENTRYsave_Bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * pixels){ GET_CURRENT_CONTEXT(ctx); GLvoid *image = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BITMAP, 7); if (n) { n[1].i = (GLint) width; n[2].i = (GLint) height; n[3].f = xorig; n[4].f = yorig; n[5].f = xmove; n[6].f = ymove; n[7].data = image; } else if (image) { _mesa_free(image); } if (ctx->ExecuteFlag) { CALL_Bitmap(ctx->Exec, (width, height, xorig, yorig, xmove, ymove, pixels)); }}static void GLAPIENTRYsave_BlendEquation(GLenum mode){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_EQUATION, 1); if (n) { n[1].e = mode; } if (ctx->ExecuteFlag) { CALL_BlendEquation(ctx->Exec, (mode)); }}static void GLAPIENTRYsave_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_EQUATION_SEPARATE, 2); if (n) { n[1].e = modeRGB; n[2].e = modeA; } if (ctx->ExecuteFlag) { CALL_BlendEquationSeparateEXT(ctx->Exec, (modeRGB, modeA)); }}static void GLAPIENTRYsave_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_FUNC_SEPARATE, 4); if (n) { n[1].e = sfactorRGB; n[2].e = dfactorRGB; n[3].e = sfactorA; n[4].e = dfactorA; } if (ctx->ExecuteFlag) { CALL_BlendFuncSeparateEXT(ctx->Exec, (sfactorRGB, dfactorRGB, sfactorA, dfactorA)); }}static void GLAPIENTRYsave_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_BLEND_COLOR, 4); if (n) { n[1].f = red; n[2].f = green; n[3].f = blue; n[4].f = alpha; } if (ctx->ExecuteFlag) { CALL_BlendColor(ctx->Exec, (red, green, blue, alpha)); }}void GLAPIENTRY_mesa_save_CallList(GLuint list){ GET_CURRENT_CONTEXT(ctx); Node *n; SAVE_FLUSH_VERTICES(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST, 1); if (n) { n[1].ui = list; } /* After this, we don't know what begin/end state we're in: */ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; if (ctx->ExecuteFlag) { CALL_CallList(ctx->Exec, (list)); }}void GLAPIENTRY_mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists){ GET_CURRENT_CONTEXT(ctx); GLint i; GLboolean typeErrorFlag; SAVE_FLUSH_VERTICES(ctx); switch (type) { case GL_BYTE: case GL_UNSIGNED_BYTE: case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: case GL_2_BYTES: case GL_3_BYTES: case GL_4_BYTES: typeErrorFlag = GL_FALSE; break; default: typeErrorFlag = GL_TRUE; } for (i = 0; i < n; i++) { GLuint list = translate_id(i, type, lists); Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2); if (n) { n[1].ui = list; n[2].b = typeErrorFlag; } } /* After this, we don't know what begin/end state we're in: */ ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; if (ctx->ExecuteFlag) { CALL_CallLists(ctx->Exec, (n, type, lists)); }}static void GLAPIENTRYsave_Clear(GLbitfield mask){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR, 1); if (n) { n[1].bf = mask; } if (ctx->ExecuteFlag) { CALL_Clear(ctx->Exec, (mask)); }}static void GLAPIENTRYsave_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_ACCUM, 4); if (n) { n[1].f = red; n[2].f = green; n[3].f = blue; n[4].f = alpha; } if (ctx->ExecuteFlag) { CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha)); }}static void GLAPIENTRYsave_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha){ GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); n = ALLOC_INSTRUCTION(ctx, OPCODE_CLEAR_COLOR, 4); if (n) { n[1].f = red; n[2].f = green; n[3].f = blue; n[4].f = alpha; } if (ctx->ExecuteFlag) { CALL_ClearColor(ctx->Exec, (red, green, blue, alpha)); }}static void GLAPIENTRYsave_ClearDepth(GLclampd depth)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -