mesa: rework viewport/scissor initialization code

The first time a context is bound to a drawable, the viewport and scissor
bounds are initialized to the buffer's size.  This is actually a bit tricky.

A new _mesa_check_init_viewport() function is called in several places
to check if the viewport has been initialized.  We also use a new
ctx->ViewportInitialized flag instead of the overloaded
ctx->FirstTimeCurrent flag.
This commit is contained in:
Brian Paul
2009-06-17 08:35:55 -06:00
parent d18c57aaea
commit 3f856c6b6b
5 changed files with 38 additions and 34 deletions

View File

@@ -1255,6 +1255,24 @@ initialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb)
} }
/**
* Check if the viewport/scissor size has not yet been initialized.
* Initialize the size if the given width and height are non-zero.
*/
void
_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height)
{
if (!ctx->ViewportInitialized && width > 0 && height > 0) {
/* Note: set flag here, before calling _mesa_set_viewport(), to prevent
* potential infinite recursion.
*/
ctx->ViewportInitialized = GL_TRUE;
_mesa_set_viewport(ctx, 0, 0, width, height);
_mesa_set_scissor(ctx, 0, 0, width, height);
}
}
/** /**
* Bind the given context to the given drawBuffer and readBuffer and * Bind the given context to the given drawBuffer and readBuffer and
* make it the current context for the calling thread. * make it the current context for the calling thread.
@@ -1372,25 +1390,24 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
ASSERT(drawBuffer->Height > 0); ASSERT(drawBuffer->Height > 0);
#endif #endif
if (newCtx->FirstTimeCurrent) { if (drawBuffer) {
/* set initial viewport and scissor size now */ _mesa_check_init_viewport(newCtx,
_mesa_set_viewport(newCtx, 0, 0, drawBuffer->Width, drawBuffer->Height);
drawBuffer->Width, drawBuffer->Height);
_mesa_set_scissor(newCtx, 0, 0,
drawBuffer->Width, drawBuffer->Height );
check_context_limits(newCtx);
} }
} }
/* We can use this to help debug user's problems. Tell them to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (newCtx->FirstTimeCurrent) { if (newCtx->FirstTimeCurrent) {
check_context_limits(newCtx);
/* We can use this to help debug user's problems. Tell them to set
* the MESA_INFO env variable before running their app. Then the
* first time each context is made current we'll print some useful
* information.
*/
if (_mesa_getenv("MESA_INFO")) { if (_mesa_getenv("MESA_INFO")) {
_mesa_print_info(); _mesa_print_info();
} }
newCtx->FirstTimeCurrent = GL_FALSE; newCtx->FirstTimeCurrent = GL_FALSE;
} }
} }

View File

@@ -130,6 +130,9 @@ extern void
_mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask); _mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
extern void
_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height);
extern GLboolean extern GLboolean
_mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer, _mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer ); GLframebuffer *readBuffer );

View File

@@ -2947,6 +2947,8 @@ struct __GLcontextRec
GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */ GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
GLbitfield NewState; /**< bitwise-or of _NEW_* flags */ GLbitfield NewState; /**< bitwise-or of _NEW_* flags */
GLboolean ViewportInitialized; /**< has viewport size been initialized? */
GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */ GLbitfield varying_vp_inputs; /**< mask of VERT_BIT_* flags */
/** \name Derived state */ /** \name Derived state */

View File

@@ -274,20 +274,11 @@ st_make_current(struct st_context *st,
_glapi_check_multithread(); _glapi_check_multithread();
if (st) { if (st) {
GLboolean firstTime = st->ctx->FirstTimeCurrent; if (!_mesa_make_current(st->ctx, &draw->Base, &read->Base))
if(!_mesa_make_current(st->ctx, &draw->Base, &read->Base))
return GL_FALSE; return GL_FALSE;
/* Need to initialize viewport here since draw->Base->Width/Height
* will still be zero at this point.
* This could be improved, but would require rather extensive work
* elsewhere (allocate rb surface storage sooner)
*/
if (firstTime) {
GLuint w = draw->InitWidth, h = draw->InitHeight;
_mesa_set_viewport(st->ctx, 0, 0, w, h);
_mesa_set_scissor(st->ctx, 0, 0, w, h);
} _mesa_check_init_viewport(st->ctx, draw->InitWidth, draw->InitHeight);
return GL_TRUE; return GL_TRUE;
} }
else { else {

View File

@@ -134,16 +134,7 @@ void st_resize_framebuffer( struct st_framebuffer *stfb,
if (stfb->Base.Width != width || stfb->Base.Height != height) { if (stfb->Base.Width != width || stfb->Base.Height != height) {
GET_CURRENT_CONTEXT(ctx); GET_CURRENT_CONTEXT(ctx);
if (ctx) { if (ctx) {
if (stfb->InitWidth == 0 && stfb->InitHeight == 0) { _mesa_check_init_viewport(ctx, width, height);
/* didn't have a valid size until now */
stfb->InitWidth = width;
stfb->InitHeight = height;
if (ctx->Viewport.Width <= 1) {
/* set context's initial viewport/scissor size */
_mesa_set_viewport(ctx, 0, 0, width, height);
_mesa_set_scissor(ctx, 0, 0, width, height);
}
}
_mesa_resize_framebuffer(ctx, &stfb->Base, width, height); _mesa_resize_framebuffer(ctx, &stfb->Base, width, height);