Remove screenConfigs from __DRIscreen.
[mesa.git] / src / mesa / main / framebuffer.c
index 3136a950e08440e6cfc78afa0df71a4c4e5bf0d2..3e36197d884fbf990a77af87de4376d91a6ef17e 100644 (file)
 
 #include "glheader.h"
 #include "imports.h"
+#include "buffers.h"
 #include "context.h"
 #include "depthstencil.h"
 #include "mtypes.h"
 #include "fbobject.h"
 #include "framebuffer.h"
 #include "renderbuffer.h"
+#include "texobj.h"
 
 
 
@@ -65,43 +67,9 @@ compute_depth_max(struct gl_framebuffer *fb)
       fb->_DepthMax = 0xffffffff;
    }
    fb->_DepthMaxF = (GLfloat) fb->_DepthMax;
-   fb->_MRD = 1.0;  /* Minimum resolvable depth value, for polygon offset */
-}
-
 
-/**
- * Set the framebuffer's _DepthBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_depth_renderbuffer(struct gl_framebuffer *fb,
-                       struct gl_renderbuffer *rb)
-{
-   if (fb->_DepthBuffer) {
-      _mesa_unreference_renderbuffer(&fb->_DepthBuffer);
-   }
-   fb->_DepthBuffer = rb;
-   if (rb) {
-      rb->RefCount++;
-   }
-}
-
-
-/**
- * Set the framebuffer's _StencilBuffer field, taking care of
- * reference counts, etc.
- */
-static void
-set_stencil_renderbuffer(struct gl_framebuffer *fb,
-                         struct gl_renderbuffer *rb)
-{
-   if (fb->_StencilBuffer) {
-      _mesa_unreference_renderbuffer(&fb->_StencilBuffer);
-   }
-   fb->_StencilBuffer = rb;
-   if (rb) {
-      rb->RefCount++;
-   }
+   /* Minimum resolvable depth value, for polygon offset */
+   fb->_MRD = 1.0 / fb->_DepthMaxF;
 }
 
 
@@ -171,7 +139,7 @@ _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual)
    /* save the visual */
    fb->Visual = *visual;
 
-   /* Init glRead/DrawBuffer state */
+   /* Init read/draw renderbuffer state */
    if (visual->doubleBufferMode) {
       fb->ColorDrawBuffer[0] = GL_BACK;
       fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT;
@@ -223,25 +191,19 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb)
    for (i = 0; i < BUFFER_COUNT; i++) {
       struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
       if (att->Renderbuffer) {
-         _mesa_unreference_renderbuffer(&att->Renderbuffer);
+         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
       }
       if (att->Texture) {
-         /* render to texture */
-         att->Texture->RefCount--;
-         if (att->Texture->RefCount == 0) {
-            GET_CURRENT_CONTEXT(ctx);
-            if (ctx) {
-               ctx->Driver.DeleteTexture(ctx, att->Texture);
-            }
-         }
+         _mesa_reference_texobj(&att->Texture, NULL);
       }
+      ASSERT(!att->Renderbuffer);
+      ASSERT(!att->Texture);
       att->Type = GL_NONE;
-      att->Texture = NULL;
    }
 
-   /* unbind depth/stencil to decr ref counts */
-   set_depth_renderbuffer(fb, NULL);
-   set_stencil_renderbuffer(fb, NULL);
+   /* unbind _Depth/_StencilBuffer to decr ref counts */
+   _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
+   _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
 }
 
 
@@ -569,13 +531,13 @@ _mesa_update_depth_buffer(GLcontext *ctx,
          /* need to update wrapper */
          struct gl_renderbuffer *wrapper
             = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
-         set_depth_renderbuffer(fb, wrapper);
+         _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
          ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
       }
    }
    else {
       /* depthRb may be null */
-      set_depth_renderbuffer(fb, depthRb);
+      _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);
    }
 }
 
@@ -610,19 +572,19 @@ _mesa_update_stencil_buffer(GLcontext *ctx,
          /* need to update wrapper */
          struct gl_renderbuffer *wrapper
             = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);
-         set_stencil_renderbuffer(fb, wrapper);
+         _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);
          ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);
       }
    }
    else {
       /* stencilRb may be null */
-      set_stencil_renderbuffer(fb, stencilRb);
+      _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);
    }
 }
 
 
 /**
- * Update the list of color drawing renderbuffer pointers.
+ * Update the (derived) list of color drawing renderbuffer pointers.
  * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers
  * writing colors.
  */
@@ -647,7 +609,7 @@ update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
             const GLuint bufferBit = 1 << i;
             if (bufferBit & bufferMask) {
                struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;
-               if (rb) {
+               if (rb && rb->Width > 0 && rb->Height > 0) {
                   fb->_ColorDrawBuffers[output][count] = rb;
                   count++;
                }
@@ -666,14 +628,17 @@ update_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb)
 
 
 /**
- * Update the color read renderbuffer pointer.
+ * Update the (derived) color read renderbuffer pointer.
  * Unlike the DrawBuffer, we can only read from one (or zero) color buffers.
  */
 static void
 update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
    (void) ctx;
-   if (fb->_ColorReadBufferIndex == -1 || fb->DeletePending) {
+   if (fb->_ColorReadBufferIndex == -1 ||
+       fb->DeletePending ||
+       fb->Width == 0 ||
+       fb->Height == 0) {
       fb->_ColorReadBuffer = NULL; /* legal! */
    }
    else {
@@ -686,29 +651,50 @@ update_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
 
 
 /**
- * Update state related to the current draw/read framebuffers.
+ * Update a gl_framebuffer's derived state.
+ *
  * Specifically, update these framebuffer fields:
  *    _ColorDrawBuffers
  *    _NumColorDrawBuffers
  *    _ColorReadBuffer
  *    _DepthBuffer
  *    _StencilBuffer
- * If the current framebuffer is user-created, make sure it's complete.
- * The following functions can effect this state:  glReadBuffer,
- * glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
+ *
+ * If the framebuffer is user-created, make sure it's complete.
+ *
+ * The following functions (at least) can effect framebuffer state:
+ * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT,
  * glRenderbufferStorageEXT.
  */
-void
-_mesa_update_framebuffer(GLcontext *ctx)
+static void
+update_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-
-   /* Completeness only matters for user-created framebuffers */
-   if (fb->Name != 0) {
+   if (fb->Name == 0) {
+      /* This is a window-system framebuffer */
+      /* Need to update the FB's GL_DRAW_BUFFER state to match the
+       * context state (GL_READ_BUFFER too).
+       */
+      if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {
+         _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,
+                           ctx->Color.DrawBuffer, NULL);
+      }
+      if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) {
+         
+      }
+   }
+   else {
+      /* This is a user-created framebuffer.
+       * Completeness only matters for user-created framebuffers.
+       */
       _mesa_test_framebuffer_completeness(ctx, fb);
       _mesa_update_framebuffer_visual(fb);
    }
 
+   /* Strictly speaking, we don't need to update the draw-state
+    * if this FB is bound as ctx->ReadBuffer (and conversely, the
+    * read-state if this FB is bound as ctx->DrawBuffer), but no
+    * harm.
+    */
    update_color_draw_buffers(ctx, fb);
    update_color_read_buffer(ctx, fb);
    _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);
@@ -718,6 +704,21 @@ _mesa_update_framebuffer(GLcontext *ctx)
 }
 
 
+/**
+ * Update state related to the current draw/read framebuffers.
+ */
+void
+_mesa_update_framebuffer(GLcontext *ctx)
+{
+   struct gl_framebuffer *drawFb = ctx->DrawBuffer;
+   struct gl_framebuffer *readFb = ctx->ReadBuffer;
+
+   update_framebuffer(ctx, drawFb);
+   if (readFb != drawFb)
+      update_framebuffer(ctx, readFb);
+}
+
+
 /**
  * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
  * glCopyTex[Sub]Image, etc. exists.