📄 t_save_api.c
字号:
{
GET_CURRENT_CONTEXT( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLint i = tnl->save.prim_count - 1;
ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
tnl->save.prim[i].mode |= PRIM_END;
tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) -
tnl->save.prim[i].start);
if (i == (GLint) tnl->save.prim_max - 1) {
_save_compile_vertex_list( ctx );
assert(tnl->save.copied.nr == 0);
}
/* Swap out this vertex format while outside begin/end. Any color,
* etc. received between here and the next begin will be compiled
* as opcodes.
*/
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
/* These are all errors as this vtxfmt is only installed inside
* begin/end pairs.
*/
static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
(void) mode; (void) count; (void) type; (void) indices;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
}
static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
(void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
}
static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
GET_CURRENT_CONTEXT(ctx);
(void) mode; (void) start; (void) count;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" );
}
static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
GET_CURRENT_CONTEXT(ctx);
(void) x1; (void) y1; (void) x2; (void) y2;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" );
}
static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
{
GET_CURRENT_CONTEXT(ctx);
(void) mode; (void) i1; (void) i2;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" );
}
static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2,
GLint j1, GLint j2 )
{
GET_CURRENT_CONTEXT(ctx);
(void) mode; (void) i1; (void) i2; (void) j1; (void) j2;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" );
}
static void GLAPIENTRY _save_Begin( GLenum mode )
{
GET_CURRENT_CONTEXT( ctx );
(void) mode;
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "Recursive glBegin" );
}
/* Unlike the functions above, these are to be hooked into the vtxfmt
* maintained in ctx->ListState, active when the list is known or
* suspected to be outside any begin/end primitive.
*/
static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
{
GET_CURRENT_CONTEXT(ctx);
_save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK );
CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 ));
CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 ));
CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 ));
CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 ));
CALL_End(GET_DISPATCH(), ());
}
static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
GET_CURRENT_CONTEXT(ctx);
GLint i;
if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
return;
_save_NotifyBegin( ctx, mode | PRIM_WEAK );
for (i = 0; i < count; i++)
CALL_ArrayElement(GET_DISPATCH(), (start + i));
CALL_End(GET_DISPATCH(), ());
}
static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
GLint i;
if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
return;
_save_NotifyBegin( ctx, mode | PRIM_WEAK );
switch (type) {
case GL_UNSIGNED_BYTE:
for (i = 0 ; i < count ; i++)
CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] ));
break;
case GL_UNSIGNED_SHORT:
for (i = 0 ; i < count ; i++)
CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] ));
break;
case GL_UNSIGNED_INT:
for (i = 0 ; i < count ; i++)
CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] ));
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
break;
}
CALL_End(GET_DISPATCH(), ());
}
static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
if (_mesa_validate_DrawRangeElements( ctx, mode,
start, end,
count, type, indices ))
_save_OBE_DrawElements( mode, count, type, indices );
}
static void _save_vtxfmt_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLvertexformat *vfmt = &tnl->save_vtxfmt;
vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */
vfmt->Begin = _save_Begin;
vfmt->Color3f = _save_Color3f;
vfmt->Color3fv = _save_Color3fv;
vfmt->Color4f = _save_Color4f;
vfmt->Color4fv = _save_Color4fv;
vfmt->EdgeFlag = _save_EdgeFlag;
vfmt->EdgeFlagv = _save_EdgeFlagv;
vfmt->End = _save_End;
vfmt->FogCoordfEXT = _save_FogCoordfEXT;
vfmt->FogCoordfvEXT = _save_FogCoordfvEXT;
vfmt->Indexf = _save_Indexf;
vfmt->Indexfv = _save_Indexfv;
vfmt->Materialfv = _save_Materialfv;
vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f;
vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv;
vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f;
vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv;
vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f;
vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv;
vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f;
vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv;
vfmt->Normal3f = _save_Normal3f;
vfmt->Normal3fv = _save_Normal3fv;
vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT;
vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT;
vfmt->TexCoord1f = _save_TexCoord1f;
vfmt->TexCoord1fv = _save_TexCoord1fv;
vfmt->TexCoord2f = _save_TexCoord2f;
vfmt->TexCoord2fv = _save_TexCoord2fv;
vfmt->TexCoord3f = _save_TexCoord3f;
vfmt->TexCoord3fv = _save_TexCoord3fv;
vfmt->TexCoord4f = _save_TexCoord4f;
vfmt->TexCoord4fv = _save_TexCoord4fv;
vfmt->Vertex2f = _save_Vertex2f;
vfmt->Vertex2fv = _save_Vertex2fv;
vfmt->Vertex3f = _save_Vertex3f;
vfmt->Vertex3fv = _save_Vertex3fv;
vfmt->Vertex4f = _save_Vertex4f;
vfmt->Vertex4fv = _save_Vertex4fv;
vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV;
vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV;
vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV;
vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV;
vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV;
vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV;
vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV;
vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV;
vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB;
vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB;
vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB;
vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB;
vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB;
vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB;
vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB;
vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB;
/* This will all require us to fallback to saving the list as opcodes:
*/
vfmt->CallList = _save_CallList; /* inside begin/end */
vfmt->CallLists = _save_CallLists; /* inside begin/end */
vfmt->EvalCoord1f = _save_EvalCoord1f;
vfmt->EvalCoord1fv = _save_EvalCoord1fv;
vfmt->EvalCoord2f = _save_EvalCoord2f;
vfmt->EvalCoord2fv = _save_EvalCoord2fv;
vfmt->EvalPoint1 = _save_EvalPoint1;
vfmt->EvalPoint2 = _save_EvalPoint2;
/* These are all errors as we at least know we are in some sort of
* begin/end pair:
*/
vfmt->EvalMesh1 = _save_EvalMesh1;
vfmt->EvalMesh2 = _save_EvalMesh2;
vfmt->Begin = _save_Begin;
vfmt->Rectf = _save_Rectf;
vfmt->DrawArrays = _save_DrawArrays;
vfmt->DrawElements = _save_DrawElements;
vfmt->DrawRangeElements = _save_DrawRangeElements;
}
void _tnl_SaveFlushVertices( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
/* Noop when we are actually active:
*/
if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
return;
if (tnl->save.initial_counter != tnl->save.counter ||
tnl->save.prim_count)
_save_compile_vertex_list( ctx );
_save_copy_to_current( ctx );
_save_reset_vertex( ctx );
ctx->Driver.SaveNeedFlush = 0;
}
void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
(void) list; (void) mode;
if (!tnl->save.prim_store)
tnl->save.prim_store = alloc_prim_store( ctx );
if (!tnl->save.vertex_store) {
tnl->save.vertex_store = alloc_vertex_store( ctx );
tnl->save.vbptr = tnl->save.vertex_store->buffer;
}
_save_reset_vertex( ctx );
ctx->Driver.SaveNeedFlush = 0;
}
void _tnl_EndList( GLcontext *ctx )
{
(void) ctx;
assert(TNL_CONTEXT(ctx)->save.vertex_size == 0);
}
void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->save.replay_flags |= dlist->flags;
tnl->save.replay_flags |= tnl->LoopbackDListCassettes;
}
void _tnl_EndCallList( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
if (ctx->ListState.CallDepth == 1)
tnl->save.replay_flags = 0;
}
static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data )
{
struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
(void) ctx;
if ( --node->vertex_store->refcount == 0 )
FREE( node->vertex_store );
if ( --node->prim_store->refcount == 0 )
FREE( node->prim_store );
if ( node->normal_lengths )
FREE( node->normal_lengths );
}
static void _tnl_print_vertex_list( GLcontext *ctx, void *data )
{
struct tnl_vertex_list *node = (struct tnl_vertex_list *)data;
GLuint i;
(void) ctx;
_mesa_debug(NULL, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
node->count,
node->prim_count,
node->vertex_size);
for (i = 0 ; i < node->prim_count ; i++) {
struct tnl_prim *prim = &node->prim[i];
_mesa_debug(NULL, " prim %d: %s %d..%d %s %s\n",
i,
_mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK),
prim->start,
prim->start + prim->count,
(prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)",
(prim->mode & PRIM_END) ? "END" : "(wrap)");
}
}
static void _save_current_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
GLint i;
for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) {
ASSERT(i < VERT_ATTRIB_MAX);
tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i];
tnl->save.current[i] = ctx->ListState.CurrentAttrib[i];
}
for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
const GLuint j = i - _TNL_ATTRIB_MAT_FRONT_AMBIENT;
ASSERT(j < MAT_ATTRIB_MAX);
tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
tnl->save.current[i] = ctx->ListState.CurrentMaterial[j];
}
tnl->save.currentsz[_TNL_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex;
tnl->save.current[_TNL_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex;
tnl->save.currentsz[_TNL_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag;
tnl->save.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->save.CurrentFloatEdgeFlag;
}
/**
* Initialize the display list compiler
*/
void _tnl_save_init( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
GLuint i;
for (i = 0; i < _TNL_ATTRIB_MAX; i++)
_mesa_vector4f_init( &tmp->Attribs[i], 0, NULL);
tnl->save.opcode_vertex_list =
_mesa_alloc_opcode( ctx,
sizeof(struct tnl_vertex_list),
_tnl_playback_vertex_list,
_tnl_destroy_vertex_list,
_tnl_print_vertex_list );
ctx->Driver.NotifySaveBegin = _save_NotifyBegin;
_save_vtxfmt_init( ctx );
_save_current_init( ctx );
/* Hook our array functions into the outside-begin-end vtxfmt in
* ctx->ListState.
*/
ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
/**
* Deallocate the immediate-mode buffer for the given context, if
* its reference count goes to zero.
*/
void _tnl_save_destroy( GLcontext *ctx )
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
/* Decrement the refcounts. References may still be held by
* display lists yet to be destroyed, so it may not yet be time to
* free these items.
*/
if (tnl->save.prim_store &&
--tnl->save.prim_store->refcount == 0 )
FREE( tnl->save.prim_store );
if (tnl->save.vertex_store &&
--tnl->save.vertex_store->refcount == 0 )
FREE( tnl->save.vertex_store );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -