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:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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 );
|
||||||
|
@@ -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 */
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user