gallium: added new st_set_framebuffer_surface()
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 18 Jun 2008 16:20:13 +0000 (10:20 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 18 Jun 2008 16:20:13 +0000 (10:20 -0600)
This allows the winsys to explicitly specify gallium surfaces for a
framebuffer object.

src/mesa/state_tracker/st_framebuffer.c
src/mesa/state_tracker/st_public.h

index 7099d78..7e6db46 100644 (file)
@@ -38,6 +38,7 @@
 #include "st_cb_fbo.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
 
 
 struct st_framebuffer *
@@ -155,6 +156,61 @@ void st_unreference_framebuffer( struct st_framebuffer **stfb )
 
 
 /**
+ * Set/replace a framebuffer surface.
+ * The user of the state tracker can use this instead of
+ * st_resize_framebuffer() to provide new surfaces when a window is resized.
+ */
+void
+st_set_framebuffer_surface(struct st_framebuffer *stfb,
+                           uint surfIndex, struct pipe_surface *surf)
+{
+   static const GLuint invalid_size = 9999999;
+   struct st_renderbuffer *strb;
+   GLuint width, height, i;
+
+   assert(surfIndex < BUFFER_COUNT);
+
+   strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
+   assert(strb);
+
+   /* replace the renderbuffer's surface/texture pointers */
+   pipe_surface_reference( &strb->surface, surf );
+   pipe_texture_reference( &strb->texture, surf->texture );
+
+   /* update renderbuffer's width/height */
+   strb->Base.Width = surf->width;
+   strb->Base.Height = surf->height;
+
+   /* Try to update the framebuffer's width/height from the renderbuffer
+    * sizes.  Before we start drawing, all the rbs _should_ be the same size.
+    */
+   width = height = invalid_size;
+   for (i = 0; i < BUFFER_COUNT; i++) {
+      if (stfb->Base.Attachment[i].Renderbuffer) {
+         if (width == invalid_size) {
+            width = stfb->Base.Attachment[i].Renderbuffer->Width;
+            height = stfb->Base.Attachment[i].Renderbuffer->Height;
+         }
+         else if (width != stfb->Base.Attachment[i].Renderbuffer->Width ||
+                  height != stfb->Base.Attachment[i].Renderbuffer->Height) {
+            /* inconsistant renderbuffer sizes, bail out */
+            return;
+         }
+      }
+   }
+
+   if (width != invalid_size) {
+      /* OK, the renderbuffers are of a consistant size, so update the
+       * parent framebuffer's size.
+       */
+      stfb->Base.Width = width;
+      stfb->Base.Height = height;
+   }
+}
+
+
+
+/**
  * Return the pipe_surface for the given renderbuffer.
  */
 struct pipe_surface *
index a0dab33..b999842 100644 (file)
@@ -68,6 +68,9 @@ struct st_framebuffer *st_create_framebuffer( const __GLcontextModes *visual,
 void st_resize_framebuffer( struct st_framebuffer *stfb,
                             uint width, uint height );
 
+void st_set_framebuffer_surface(struct st_framebuffer *stfb,
+                                uint surfIndex, struct pipe_surface *surf);
+
 struct pipe_surface *st_get_framebuffer_surface(struct st_framebuffer *stfb,
                                                 uint surfIndex);