Add winsys->surface_release() to complement winsys->surface_alloc().
authorBrian <brian.paul@tungstengraphics.com>
Wed, 7 Nov 2007 15:05:09 +0000 (08:05 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Wed, 7 Nov 2007 15:24:58 +0000 (08:24 -0700)
pipe_surface now has a pointer to the winsys which create/owns the surface.
This allows clean surface deallocation w/out a rendering context.

src/mesa/drivers/dri/intel_winsys/intel_winsys_pipe.c
src/mesa/pipe/p_inlines.h
src/mesa/pipe/p_state.h
src/mesa/pipe/p_winsys.h
src/mesa/pipe/xlib/xm_api.c
src/mesa/pipe/xlib/xm_buffer.c
src/mesa/pipe/xlib/xm_surface.c
src/mesa/pipe/xlib/xm_winsys.c
src/mesa/pipe/xlib/xmesaP.h
src/mesa/state_tracker/st_cb_fbo.c

index cc76a40a5a8119a846a55350d053495c646103d5..56a600aebe6bef1e51c9b171b75b06f7b5d60b57 100644 (file)
@@ -264,11 +264,27 @@ intel_i915_surface_alloc(struct pipe_winsys *winsys, unsigned format)
    if (surf) {
       surf->format = format;
       surf->refcount = 1;
+      surf->winsys = winsys;
    }
    return surf;
 }
 
 
+static void
+intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
+{
+   struct pipe_surface *surf = *s;
+   surf->refcount--;
+   if (surf->refcount == 0) {
+      if (surf->region)
+         winsys->region_release(winsys, &surf->region);
+      free(surf);
+   }
+   *s = NULL;
+}
+
+
+
 static void
 intel_printf( struct pipe_winsys *sws, const char *fmtString, ... )
 {
@@ -315,6 +331,7 @@ intel_create_pipe_winsys( struct intel_context *intel )
    iws->winsys.region_release = intel_i915_region_release;
 
    iws->winsys.surface_alloc = intel_i915_surface_alloc;
+   iws->winsys.surface_release = intel_i915_surface_release;
 
    return &iws->winsys;
 }
index ea666fa20aee114e1cf06b2daae6039b43c3a34c..2418d016e15fb45add31274960f2387eee114b7f 100644 (file)
@@ -29,7 +29,8 @@
 #define P_INLINES_H
 
 #include "p_context.h"
-//#include "p_util.h"
+#include "p_winsys.h"
+
 
 /**
  * Set 'ptr' to point to 'region' and update reference counting.
@@ -68,16 +69,9 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
 {
    assert(ptr);
    if (*ptr) {
-      /* unreference the old thing */
-      struct pipe_surface *oldSurf = *ptr;
-      assert(oldSurf->refcount > 0);
-      oldSurf->refcount--;
-      if (oldSurf->refcount == 0) {
-         /* free the old region */
-         pipe_region_reference(&oldSurf->region, NULL);
-         FREE( oldSurf );
-      }
-      *ptr = NULL;
+      struct pipe_winsys *winsys = (*ptr)->winsys;
+      winsys->surface_release(winsys, ptr);
+      assert(!*ptr);
    }
    if (surf) {
       /* reference the new thing */
index 0e1a038c2ea7666f6e547de689203729065a91e6..848c32701fec6cffba9e98bef5f047cdb92c26be 100644 (file)
@@ -60,6 +60,8 @@ struct pipe_surface;
 /* opaque type */
 struct pipe_buffer_handle;
 
+struct pipe_winsys;
+
 
 /***
  *** State objects
@@ -281,6 +283,7 @@ struct pipe_surface
    unsigned width, height;
    unsigned offset;              /**< offset from start of region, in bytes */
    unsigned refcount;
+   struct pipe_winsys *winsys;   /**< winsys which owns/created the surface */
 };
 
 
index 5bc6e6475aa0c8a15b06e17ea34bf2269c284c4c..e4c888ad33851dde24abed857cbd51bbd316db85 100644 (file)
@@ -86,6 +86,8 @@ struct pipe_winsys
    struct pipe_surface *(*surface_alloc)(struct pipe_winsys *ws,
                                          unsigned format);
 
+   void (*surface_release)(struct pipe_winsys *ws, struct pipe_surface **s);
+
    /**
     * The buffer manager is modeled after the dri_bufmgr interface, which 
     * in turn is modeled after the ARB_vertex_buffer_object extension,  
index 939dfe745bcb338a691d065b53c20c003252e1ce..ec889ca34fa675ebe7ec4d31fcbd65b7cdf72754 100644 (file)
@@ -301,6 +301,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
 {
    XMesaBuffer b;
    GLframebuffer *fb;
+   struct pipe_winsys *winsys = xmesa_get_pipe_winsys();
 
    ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
 
@@ -328,7 +329,7 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
    /*
     * Front renderbuffer
     */
-   b->frontxrb = xmesa_create_renderbuffer(NULL, 0, &vis->mesa_visual, GL_FALSE);
+   b->frontxrb = xmesa_create_renderbuffer(winsys, 0, &vis->mesa_visual, GL_FALSE);
    if (!b->frontxrb) {
       _mesa_free(b);
       return NULL;
@@ -337,18 +338,12 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type,
    b->frontxrb->drawable = d;
    b->frontxrb->pixmap = (XMesaPixmap) d;
    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &b->frontxrb->St.Base);
-#if 0 /* sketch... */
-   {
-      struct pipe_surface *front_surf;
-      front_surf = xmesa_create_front_surface(vis, d);
-   }
-#endif
 
    /*
     * Back renderbuffer
     */
    if (vis->mesa_visual.doubleBufferMode) {
-      b->backxrb = xmesa_create_renderbuffer(NULL, 0, &vis->mesa_visual, GL_TRUE);
+      b->backxrb = xmesa_create_renderbuffer(winsys, 0, &vis->mesa_visual, GL_TRUE);
       if (!b->backxrb) {
          /* XXX free front xrb too */
          _mesa_free(b);
index b4a05ac6855707aa4ffdb3092731d18a51c61358..7dc85bf2ebe5dd1710320f33575fe7cfc14e8411 100644 (file)
@@ -241,6 +241,12 @@ alloc_back_buffer(XMesaBuffer b, GLuint width, GLuint height)
 static void
 xmesa_delete_renderbuffer(struct gl_renderbuffer *rb)
 {
+   struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb);
+   if (xrb->St.surface) {
+      struct pipe_winsys *ws = xrb->St.surface->winsys;
+      ws->surface_release(ws, &xrb->St.surface);
+   }
+
    /* XXX Note: the ximage or Pixmap attached to this renderbuffer
     * should probably get freed here, but that's currently done in
     * XMesaDestroyBuffer().
@@ -289,11 +295,6 @@ xmesa_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
    if (!xrb->St.surface || !xrb->St.surface->region)
       finish_surface_init(ctx, xrb);
 
-#if 0
-   xmesa_set_renderbuffer_funcs(xrb, xmesa->pixelformat,
-                                xmesa->xm_visual->BitsPerPixel);
-#endif
-
    /* surface info */
    xms->surface.width = width;
    xms->surface.height = height;
@@ -353,11 +354,6 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
       xrb->origin4 = NULL;
    }
 
-#if 0
-   xmesa_set_renderbuffer_funcs(xrb, xmesa->pixelformat,
-                                xmesa->xm_visual->BitsPerPixel);
-#endif
-
    if (!xrb->St.surface || !xrb->St.surface->region)
       finish_surface_init(ctx, xrb);
 
@@ -381,11 +377,11 @@ xmesa_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
  * renderbuffers.
  */
 struct xmesa_renderbuffer *
-xmesa_create_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
+xmesa_create_renderbuffer(struct pipe_winsys *winsys,
+                          GLuint name, const GLvisual *visual,
                           GLboolean backBuffer)
 {
    struct xmesa_renderbuffer *xrb = CALLOC_STRUCT(xmesa_renderbuffer);
-   struct pipe_context *pipe = NULL;/*ctx->st->pipe;*/
    if (xrb) {
       GLuint name = 0;
       GLuint pipeFormat = 0;
@@ -416,11 +412,9 @@ xmesa_create_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
          xrb->St.Base.IndexBits = visual->indexBits;
       }
       /* only need to set Red/Green/EtcBits fields for user-created RBs */
-
-      xrb->St.surface = xmesa_new_color_surface(pipe, pipeFormat);
+      xrb->St.surface = xmesa_new_color_surface(winsys, pipeFormat);
       xms = (struct xmesa_surface *) xrb->St.surface;
       xms->xrb = xrb;
-
    }
    return xrb;
 }
index 9969cc728d7fc38a0295ccb66626f68759e16eab..43e505074769f44a3a470dc443b151c147527cd9 100644 (file)
@@ -609,7 +609,7 @@ clear_32bit_ximage_surface(struct pipe_context *pipe, struct pipe_surface *ps,
  * have special/unique quad read/write functions for X.
  */
 struct pipe_surface *
-xmesa_new_color_surface(struct pipe_context *pipe, GLuint pipeFormat)
+xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint pipeFormat)
 {
    struct xmesa_surface *xms = CALLOC_STRUCT(xmesa_surface);
 
@@ -617,15 +617,14 @@ xmesa_new_color_surface(struct pipe_context *pipe, GLuint pipeFormat)
 
    xms->surface.format = pipeFormat;
    xms->surface.refcount = 1;
+   xms->surface.winsys = winsys;
 
    /* Note, the region we allocate doesn't actually have any storage
     * since we're drawing into an XImage or Pixmap.
     * The region's size will get set in the xmesa_alloc_front/back_storage()
     * functions.
     */
-   if (pipe)
-      xms->surface.region = pipe->winsys->region_alloc(pipe->winsys,
-                                                       1, 0, 0, 0x0);
+   xms->surface.region = winsys->region_alloc(winsys, 1, 1, 1, 0x0);
 
    return &xms->surface;
 }
@@ -645,6 +644,7 @@ xmesa_surface_alloc(struct pipe_context *pipe, GLuint pipeFormat)
 
    xms->surface.format = pipeFormat;
    xms->surface.refcount = 1;
+   xms->surface.winsys = pipe->winsys;
 
    return &xms->surface;
 }
index f7e55ed8f78db08a19c583ca0627733df6c36d3a..b73fcab68d26244ee034c021d782d4e51b6231d9 100644 (file)
@@ -284,6 +284,7 @@ xm_surface_alloc(struct pipe_winsys *ws, GLuint pipeFormat)
 
    xms->surface.format = pipeFormat;
    xms->surface.refcount = 1;
+   xms->surface.winsys = ws;
 #if 0
    /*
     * This is really just a softpipe surface, not an XImage/Pixmap surface.
@@ -295,13 +296,24 @@ xm_surface_alloc(struct pipe_winsys *ws, GLuint pipeFormat)
 
 
 
+static void
+xm_surface_release(struct pipe_winsys *ws, struct pipe_surface **s)
+{
+   struct pipe_surface *surf = *s;
+   if (surf->region)
+      winsys->region_release(winsys, &surf->region);
+   free(surf);
+   *s = NULL;
+}
+
+
 
 /**
  * Return pointer to a pipe_winsys object.
  * For Xlib, this is a singleton object.
  * Nothing special for the Xlib driver so no subclassing or anything.
  */
-static struct pipe_winsys *
+struct pipe_winsys *
 xmesa_get_pipe_winsys(void)
 {
    static struct pipe_winsys *ws = NULL;
@@ -325,6 +337,7 @@ xmesa_get_pipe_winsys(void)
       ws->region_release = xm_region_release;
 
       ws->surface_alloc = xm_surface_alloc;
+      ws->surface_release = xm_surface_release;
 
       ws->flush_frontbuffer = xm_flush_frontbuffer;
       ws->wait_idle = xm_wait_idle;
index c70dc6760838a4505b1ab5fd0667584ee3cee15f..ba0ccdbcecbbf9f044b5d278555224d88ac94401 100644 (file)
@@ -51,10 +51,6 @@ typedef struct {
 } bgr_t;
 
 
-struct xmesa_renderbuffer;
-
-
-
 /** Framebuffer pixel formats */
 enum pixel_format {
    PF_Index,           /**< Color Index mode */
@@ -451,7 +447,8 @@ extern const int xmesa_kernel1[16];
  */
 
 extern struct xmesa_renderbuffer *
-xmesa_create_renderbuffer(GLcontext *ctx, GLuint name, const GLvisual *visual,
+xmesa_create_renderbuffer(struct pipe_winsys *winsys,
+                          GLuint name, const GLvisual *visual,
                           GLboolean backBuffer);
 
 extern void
@@ -545,8 +542,10 @@ extern struct pipe_surface *
 xmesa_surface_alloc(struct pipe_context *pipe, GLuint format);
 
 extern struct pipe_surface *
-xmesa_new_color_surface(struct pipe_context *pipe, GLuint format);
+xmesa_new_color_surface(struct pipe_winsys *winsys, GLuint format);
 
+extern struct pipe_winsys *
+xmesa_get_pipe_winsys(void);
 
 extern void
 xmesa_get_tile(struct pipe_context *pipe, struct pipe_surface *ps,
index 7c18f380cda8d856742c43bb77d59eb916a1f28d..0d23f7eec40bc28813f3b66a2d10c0157deef716 100644 (file)
@@ -129,19 +129,10 @@ static void
 st_renderbuffer_delete(struct gl_renderbuffer *rb)
 {
    struct st_renderbuffer *strb = st_renderbuffer(rb);
-   GET_CURRENT_CONTEXT(ctx);
-   if (ctx) {
-      struct pipe_context *pipe = ctx->st->pipe;
-      ASSERT(strb);
-      if (strb && strb->surface) {
-         if (strb->surface->region) {
-            pipe->winsys->region_release(pipe->winsys, &strb->surface->region);
-         }
-         free(strb->surface);
-      }
-   }
-   else {
-      _mesa_warning(NULL, "st_renderbuffer_delete() called, but no current context");
+   ASSERT(strb);
+   if (strb->surface) {
+      struct pipe_winsys *ws = strb->surface->winsys;
+      ws->surface_release(ws, &strb->surface);
    }
    free(strb);
 }