summaryrefslogtreecommitdiffstats
path: root/src/mesa/tnl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/tnl')
-rw-r--r--src/mesa/tnl/t_save_loopback.c125
-rw-r--r--src/mesa/tnl/t_save_playback.c9
2 files changed, 88 insertions, 46 deletions
diff --git a/src/mesa/tnl/t_save_loopback.c b/src/mesa/tnl/t_save_loopback.c
index 0798203c4bf..b496a784c35 100644
--- a/src/mesa/tnl/t_save_loopback.c
+++ b/src/mesa/tnl/t_save_loopback.c
@@ -41,6 +41,9 @@
* glVertex()
* ... lots of vertices ...
* glEnd()
+ *
+ * or:
+ * glDrawArrays(...)
*
* and then tries to execute it like this:
*
@@ -58,7 +61,7 @@
* usage.
*
* Further, replaying degenerately-called lists in this fashion is
- * probably no worse than the replay using opcodes.
+ * probably still faster than the replay using opcodes.
*/
typedef void (*attr_func)( GLcontext *ctx, GLint target, const GLfloat * );
@@ -174,6 +177,82 @@ struct loopback_attr {
attr_func func;
};
+/* Don't emit ends and begins on wrapped primitives. Don't replay
+ * wrapped vertices. If we get here, it's probably because the the
+ * precalculated wrapping is wrong.
+ */
+static void loopback_prim( GLcontext *ctx,
+ struct tnl_vertex_list *list, GLuint i,
+ struct loopback_attr *la, GLuint nr )
+{
+ struct tnl_prim *prim = &list->prim[i];
+ GLint begin = prim->start;
+ GLint end = begin + prim->count;
+ GLfloat *data;
+ GLint j, k;
+
+ if (prim->mode & PRIM_BEGIN) {
+ glBegin( prim->mode & PRIM_MODE_MASK );
+ } else {
+ assert(i == 0);
+ assert(begin == 0);
+ begin += list->wrap_count;
+ }
+
+ data = list->buffer + begin * list->vertex_size;
+
+ for (j = begin ; j < end ; j++) {
+ GLfloat *tmp = data + la[0].sz;
+
+ for (k = 1 ; k < nr ; k++) {
+ la[k].func( ctx, la[k].target, tmp );
+ tmp += la[k].sz;
+ }
+
+ /* Fire the vertex
+ */
+ la[0].func( ctx, VERT_ATTRIB_POS, data );
+ data = tmp;
+ }
+
+ if (prim->mode & PRIM_END) {
+ glEnd();
+ }
+ else {
+ assert (i == list->prim_count-1);
+ }
+}
+
+/* Primitives generated by DrawArrays/DrawElements/Rectf may be
+ * caught here. If there is no primitive in progress, execute them
+ * normally, otherwise need to track and discard the generated
+ * primitives.
+ */
+static void loopback_weak_prim( GLcontext *ctx,
+ struct tnl_vertex_list *list, GLuint i,
+ struct loopback_attr *la, GLuint nr )
+{
+ if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
+ loopback_prim( ctx, list, i, la, nr );
+ else {
+ struct tnl_prim *prim = &list->prim[i];
+
+ /* Use the prim_weak flag to ensure that if this primitive
+ * wraps, we don't mistake future vertex_lists for part of the
+ * surrounding primitive.
+ *
+ * While this flag is set, we are simply disposing of data
+ * generated by an operation now known to be a noop.
+ */
+ if (prim->mode & PRIM_BEGIN)
+ ctx->Driver.CurrentExecPrimitive |= PRIM_WEAK;
+ if (prim->mode & PRIM_END)
+ ctx->Driver.CurrentExecPrimitive &= ~PRIM_WEAK;
+ }
+}
+
+
+
void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
{
struct loopback_attr la[_TNL_ATTRIB_MAX];
@@ -213,46 +292,10 @@ void _tnl_loopback_vertex_list( GLcontext *ctx, struct tnl_vertex_list *list )
nr++;
}
- /* Don't emit ends and begins on wrapped primitives. Don't replay
- * wrapped vertices. If we get here, it's probably because the the
- * precalculated wrapping is wrong.
- */
for (i = 0 ; i < list->prim_count ; i++) {
- struct tnl_prim *prim = &list->prim[i];
- GLint begin = prim->start;
- GLint end = begin + prim->count;
- GLfloat *data;
- GLint j, k;
-
- if (prim->mode & PRIM_BEGIN) {
- glBegin( prim->mode & PRIM_MODE_MASK );
- } else {
- assert(i == 0);
- assert(begin == 0);
- begin += list->wrap_count;
- }
-
- data = list->buffer + begin * list->vertex_size;
-
- for (j = begin ; j < end ; j++) {
- GLfloat *tmp = data + la[0].sz;
-
- for (k = 1 ; k < nr ; k++) {
- la[k].func( ctx, la[k].target, tmp );
- tmp += la[k].sz;
- }
-
- /* Fire the vertex
- */
- la[0].func( ctx, VERT_ATTRIB_POS, data );
- data = tmp;
- }
-
- if (prim->mode & PRIM_END) {
- glEnd();
- }
- else {
- assert (i == list->prim_count-1);
- }
+ if (list->prim[i].mode & PRIM_WEAK)
+ loopback_weak_prim( ctx, list, i, la, nr );
+ else
+ loopback_prim( ctx, list, i, la, nr );
}
}
diff --git a/src/mesa/tnl/t_save_playback.c b/src/mesa/tnl/t_save_playback.c
index 34225807db2..78e6c661598 100644
--- a/src/mesa/tnl/t_save_playback.c
+++ b/src/mesa/tnl/t_save_playback.c
@@ -65,9 +65,6 @@ static void _tnl_bind_vertex_list( GLcontext *ctx,
VB->PrimitiveCount = node->prim_count;
VB->Elts = NULL;
VB->NormalLengthPtr = NULL;
- VB->ColorPtr[1] = NULL;
- VB->SecondaryColorPtr[1] = NULL;
- VB->IndexPtr[1] = NULL;
for (attr = 0; attr <= _TNL_ATTRIB_INDEX; attr++) {
if (node->attrsz[attr]) {
@@ -108,8 +105,11 @@ static void _tnl_bind_vertex_list( GLcontext *ctx,
VB->ObjPtr = VB->AttribPtr[_TNL_ATTRIB_POS];
VB->NormalPtr = VB->AttribPtr[_TNL_ATTRIB_NORMAL];
VB->ColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR0];
+ VB->ColorPtr[1] = 0;
VB->IndexPtr[0] = VB->AttribPtr[_TNL_ATTRIB_INDEX];
+ VB->IndexPtr[1] = 0;
VB->SecondaryColorPtr[0] = VB->AttribPtr[_TNL_ATTRIB_COLOR1];
+ VB->SecondaryColorPtr[1] = 0;
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
@@ -179,8 +179,7 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
* includes operations such as glBegin or glDrawArrays.
*/
_mesa_error( ctx, GL_INVALID_OPERATION, "displaylist recursive begin");
- if (!(node->prim[0].mode & PRIM_WEAK))
- _tnl_loopback_vertex_list( ctx, data );
+ _tnl_loopback_vertex_list( ctx, data );
return;
}
else if (node->dangling_attr_ref) {