From 9de863603d8092243df502365a75d65982223f0e Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Tue, 5 Nov 2013 22:36:38 -0800 Subject: [PATCH] mesa: Initialize all the viewports v2: Use MAX_VIEWPORTS instead of ctx->Const.MaxViewports because the driver may not set ctx->Const.MaxViewports yet. v3: Handle all viewport entries in update_viewport_matrix and _mesa_copy_context too. This was previously in an earlier patch. Having the code in the earlier patch could cause _mesa_copy_context to access a matrix that hadn't been constructed. Signed-off-by: Ian Romanick Reviewed-by: Kenneth Graunke [v2] --- src/mesa/main/context.c | 29 ++++++++++++++++++++--------- src/mesa/main/state.c | 13 ++++++++----- src/mesa/main/viewport.c | 33 +++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 91fcbd284a6..1cd006416e1 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1357,14 +1357,17 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, } if (mask & GL_VIEWPORT_BIT) { /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */ - dst->ViewportArray[0].X = src->ViewportArray[0].X; - dst->ViewportArray[0].Y = src->ViewportArray[0].Y; - dst->ViewportArray[0].Width = src->ViewportArray[0].Width; - dst->ViewportArray[0].Height = src->ViewportArray[0].Height; - dst->ViewportArray[0].Near = src->ViewportArray[0].Near; - dst->ViewportArray[0].Far = src->ViewportArray[0].Far; - _math_matrix_copy(&dst->ViewportArray[0]._WindowMap, - &src->ViewportArray[0]._WindowMap); + unsigned i; + for (i = 0; i < src->Const.MaxViewports; i++) { + dst->ViewportArray[i].X = src->ViewportArray[i].X; + dst->ViewportArray[i].Y = src->ViewportArray[i].Y; + dst->ViewportArray[i].Width = src->ViewportArray[i].Width; + dst->ViewportArray[i].Height = src->ViewportArray[i].Height; + dst->ViewportArray[i].Near = src->ViewportArray[i].Near; + dst->ViewportArray[i].Far = src->ViewportArray[i].Far; + _math_matrix_copy(&dst->ViewportArray[i]._WindowMap, + &src->ViewportArray[i]._WindowMap); + } } /* XXX FIXME: Call callbacks? @@ -1433,11 +1436,19 @@ void _mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) { if (!ctx->ViewportInitialized && width > 0 && height > 0) { + unsigned i; + /* Note: set flag here, before calling _mesa_set_viewport(), to prevent * potential infinite recursion. */ ctx->ViewportInitialized = GL_TRUE; - _mesa_set_viewport(ctx, 0, 0, 0, width, height); + + /* Note: ctx->Const.MaxViewports may not have been set by the driver + * yet, so just initialize all of them. + */ + for (i = 0; i < MAX_VIEWPORTS; i++) { + _mesa_set_viewport(ctx, i, 0, 0, width, height); + } _mesa_set_scissor(ctx, 0, 0, 0, width, height); } } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index acb2f2073d2..87f6553a5f9 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -269,6 +269,7 @@ static void update_viewport_matrix(struct gl_context *ctx) { const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; + unsigned i; ASSERT(depthMax > 0); @@ -276,11 +277,13 @@ update_viewport_matrix(struct gl_context *ctx) * and should be maintained elsewhere if at all. * NOTE: RasterPos uses this. */ - _math_matrix_viewport(&ctx->ViewportArray[0]._WindowMap, - ctx->ViewportArray[0].X, ctx->ViewportArray[0].Y, - ctx->ViewportArray[0].Width, ctx->ViewportArray[0].Height, - ctx->ViewportArray[0].Near, ctx->ViewportArray[0].Far, - depthMax); + for (i = 0; i < ctx->Const.MaxViewports; i++) { + _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, + ctx->ViewportArray[i].X, ctx->ViewportArray[i].Y, + ctx->ViewportArray[i].Width, ctx->ViewportArray[i].Height, + ctx->ViewportArray[i].Near, ctx->ViewportArray[i].Far, + depthMax); + } } diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index ac891c84710..cc031b00a41 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -197,18 +197,24 @@ _mesa_DepthRangef(GLclampf nearval, GLclampf farval) void _mesa_init_viewport(struct gl_context *ctx) { GLfloat depthMax = 65535.0F; /* sorf of arbitrary */ + unsigned i; - /* Viewport group */ - ctx->ViewportArray[0].X = 0; - ctx->ViewportArray[0].Y = 0; - ctx->ViewportArray[0].Width = 0; - ctx->ViewportArray[0].Height = 0; - ctx->ViewportArray[0].Near = 0.0; - ctx->ViewportArray[0].Far = 1.0; - _math_matrix_ctr(&ctx->ViewportArray[0]._WindowMap); - - _math_matrix_viewport(&ctx->ViewportArray[0]._WindowMap, 0, 0, 0, 0, - 0.0F, 1.0F, depthMax); + /* Note: ctx->Const.MaxViewports may not have been set by the driver yet, + * so just initialize all of them. + */ + for (i = 0; i < MAX_VIEWPORTS; i++) { + /* Viewport group */ + ctx->ViewportArray[i].X = 0; + ctx->ViewportArray[i].Y = 0; + ctx->ViewportArray[i].Width = 0; + ctx->ViewportArray[i].Height = 0; + ctx->ViewportArray[i].Near = 0.0; + ctx->ViewportArray[i].Far = 1.0; + _math_matrix_ctr(&ctx->ViewportArray[i]._WindowMap); + + _math_matrix_viewport(&ctx->ViewportArray[i]._WindowMap, 0, 0, 0, 0, + 0.0F, 1.0F, depthMax); + } } @@ -218,6 +224,9 @@ void _mesa_init_viewport(struct gl_context *ctx) */ void _mesa_free_viewport_data(struct gl_context *ctx) { - _math_matrix_dtr(&ctx->ViewportArray[0]._WindowMap); + unsigned i; + + for (i = 0; i < MAX_VIEWPORTS; i++) + _math_matrix_dtr(&ctx->ViewportArray[i]._WindowMap); } -- 2.30.2