st/egl_g3d: Do not reuse the pipe transfer in ximage.
authorChia-I Wu <olvaffe@gmail.com>
Wed, 20 Jan 2010 05:24:42 +0000 (13:24 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 20 Jan 2010 05:30:55 +0000 (13:30 +0800)
A pipe transfer is supposed to be temporary.  It should be created
before X*PutImage and destroyed afterwards.

src/gallium/state_trackers/egl_g3d/x11/native_ximage.c

index d76107c47f1c21df6fd569271874d0a570218966..dfa8df222340b702e207ba38d77ee4f1510d006d 100644 (file)
@@ -66,7 +66,6 @@ struct ximage_buffer {
    XImage *ximage;
 
    struct pipe_texture *texture;
-   struct pipe_transfer *transfer;
    XShmSegmentInfo *shm_info;
    boolean xshm_attached;
 };
@@ -115,12 +114,7 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
 {
    struct ximage_surface *xsurf = ximage_surface(nsurf);
    struct ximage_buffer *xbuf = &xsurf->buffers[which];
-   struct pipe_screen *screen = xsurf->xdpy->base.screen;
 
-   if (xbuf->transfer) {
-      screen->tex_transfer_destroy(xbuf->transfer);
-      xbuf->transfer = NULL;
-   }
    pipe_texture_reference(&xbuf->texture, NULL);
 
    if (xbuf->shm_info) {
@@ -193,13 +187,6 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
       xbuf->texture = screen->texture_create(screen, &templ);
    }
 
-   if (xbuf->texture) {
-      xbuf->transfer = screen->get_tex_transfer(screen, xbuf->texture,
-            0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
-      if (!xbuf->transfer)
-         pipe_texture_reference(&xbuf->texture, NULL);
-   }
-
    /* clean up the buffer if allocation failed */
    if (!xbuf->texture)
       ximage_surface_free_buffer(&xsurf->base, which);
@@ -214,13 +201,25 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
    struct ximage_surface *xsurf = ximage_surface(nsurf);
    struct ximage_buffer *xbuf = &xsurf->buffers[which];
    struct pipe_screen *screen = xsurf->xdpy->base.screen;
+   struct pipe_transfer *transfer;
 
    if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
       return TRUE;
 
    assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
 
-   xbuf->ximage->data = screen->transfer_map(screen, xbuf->transfer);
+   transfer = screen->get_tex_transfer(screen, xbuf->texture,
+         0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
+   if (!transfer)
+      return FALSE;
+
+   xbuf->ximage->bytes_per_line = transfer->stride;
+   xbuf->ximage->data = screen->transfer_map(screen, transfer);
+   if (!xbuf->ximage->data) {
+      screen->tex_transfer_destroy(transfer);
+      return FALSE;
+   }
+
 
    if (xbuf->shm_info)
       XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
@@ -230,7 +229,13 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
             xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
 
    xbuf->ximage->data = NULL;
-   screen->transfer_unmap(screen, xbuf->transfer);
+   screen->transfer_unmap(screen, transfer);
+
+   /*
+    * softpipe allows the pipe transfer to be re-used, but we don't want to
+    * rely on that behavior.
+    */
+   screen->tex_transfer_destroy(transfer);
 
    XSync(xsurf->xdpy->dpy, FALSE);
 
@@ -314,9 +319,8 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
          if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
             /* update ximage */
             if (xbuf->ximage) {
-               xbuf->ximage->width = xbuf->transfer->width;
-               xbuf->ximage->height = xbuf->transfer->height;
-               xbuf->ximage->bytes_per_line = xbuf->transfer->stride;
+               xbuf->ximage->width = xsurf->width;
+               xbuf->ximage->height = xsurf->height;
             }
          }
       }