mesa/st: Create front renderbuffer on the fly when supplied with a surface
authorNicolai Hähnle <nhaehnle@gmail.com>
Sat, 12 Sep 2009 14:49:31 +0000 (16:49 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Sun, 20 Sep 2009 14:58:53 +0000 (16:58 +0200)
Normally, the mesa/st would create a fake front buffer out of a
client-allocated surface.

In the DRI setting, however, st/dri provides a front buffer surface which is
created and maintained by the X server. Prefer to use this surface instead,
so that front buffer rendering and reading works correctly.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
src/mesa/state_tracker/st_framebuffer.c

index ca32b2e573c98cbd3c7e7906b9eaf3ce4e384c41..5c0d335d62d14af55fd9a6750ece0d0304e3f062 100644 (file)
@@ -66,7 +66,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
       else {
          /* Only allocate front buffer right now if we're single buffered.
           * If double-buffered, allocate front buffer on demand later.
-          * See check_create_front_buffers().
+          * See check_create_front_buffers() and st_set_framebuffer_surface().
           */
          struct gl_renderbuffer *rb
             = st_new_renderbuffer_fb(colorFormat, samples, FALSE);
@@ -170,8 +170,20 @@ st_set_framebuffer_surface(struct st_framebuffer *stfb,
 
    strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
 
-   /* fail */
-   if (!strb) return;
+   if (!strb) {
+      if (surfIndex == ST_SURFACE_FRONT_LEFT) {
+         /* Delayed creation when the window system supplies a fake front buffer */
+         struct st_renderbuffer *strb_back
+            = st_renderbuffer(stfb->Base.Attachment[ST_SURFACE_BACK_LEFT].Renderbuffer);
+         struct gl_renderbuffer *rb
+            = st_new_renderbuffer_fb(surf->format, strb_back->Base.NumSamples, FALSE);
+         _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
+         strb = st_renderbuffer(rb);
+      } else {
+         /* fail */
+         return;
+      }
+   }
 
    /* replace the renderbuffer's surface/texture pointers */
    pipe_surface_reference( &strb->surface, surf );