mesa: rework viewport/scissor initialization code
authorBrian Paul <brianp@vmware.com>
Wed, 17 Jun 2009 14:35:55 +0000 (08:35 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 17 Jun 2009 14:38:38 +0000 (08:38 -0600)
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.

src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_framebuffer.c

index a947f69632f308b67fe05af42afb5ab0213b8bc4..0a4c9acdfe9f8dc84bcf47be2e63d36a81624c78 100644 (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
  * make it the current context for the calling thread.
@@ -1372,25 +1390,24 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
          ASSERT(drawBuffer->Height > 0);
 #endif
 
-         if (newCtx->FirstTimeCurrent) {
-            /* set initial viewport and scissor size now */
-            _mesa_set_viewport(newCtx, 0, 0,
-                               drawBuffer->Width, drawBuffer->Height);
-           _mesa_set_scissor(newCtx, 0, 0,
-                             drawBuffer->Width, drawBuffer->Height );
-            check_context_limits(newCtx);
+         if (drawBuffer) {
+            _mesa_check_init_viewport(newCtx,
+                                      drawBuffer->Width, drawBuffer->Height);
          }
       }
 
-      /* 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) {
+         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")) {
            _mesa_print_info();
         }
+
         newCtx->FirstTimeCurrent = GL_FALSE;
       }
    }
index 6b3e1b2b9737d904b662002ae48567e8c1665172..0531ae8ee860a60fcd26f0e293cae45d171b4a7e 100644 (file)
@@ -130,6 +130,9 @@ extern void
 _mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask);
 
 
+extern void
+_mesa_check_init_viewport(GLcontext *ctx, GLuint width, GLuint height);
+
 extern GLboolean
 _mesa_make_current( GLcontext *ctx, GLframebuffer *drawBuffer,
                     GLframebuffer *readBuffer );
index 50dc2def87f65ad1b2aaf26cb8453f7e8e5c899d..8872c8963f5492f0707be3088400c536b31c119b 100644 (file)
@@ -2947,6 +2947,8 @@ struct __GLcontextRec
    GLenum RenderMode;        /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
    GLbitfield NewState;      /**< bitwise-or of _NEW_* flags */
 
+   GLboolean ViewportInitialized;  /**< has viewport size been initialized? */
+
    GLbitfield varying_vp_inputs;  /**< mask of VERT_BIT_* flags */
 
    /** \name Derived state */
index 92ddffc0148de14462ad16533ab9583fd7d6e0f5..8514b6b3756bfd0ca5372594f2915741149216c9 100644 (file)
@@ -274,20 +274,11 @@ st_make_current(struct st_context *st,
    _glapi_check_multithread();
 
    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;
-      /* 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;
    }
    else {
index 331575660d300ad148d599327dd709aabfd1c0bd..33a90ea7db605edf23327e63d2ba4e696fd7b528 100644 (file)
@@ -134,16 +134,7 @@ void st_resize_framebuffer( struct st_framebuffer *stfb,
    if (stfb->Base.Width != width || stfb->Base.Height != height) {
       GET_CURRENT_CONTEXT(ctx);
       if (ctx) {
-         if (stfb->InitWidth == 0 && stfb->InitHeight == 0) {
-            /* 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_check_init_viewport(ctx, width, height);
 
          _mesa_resize_framebuffer(ctx, &stfb->Base, width, height);