vl: handle DRI2GetBuffers reply with multiple buffers
authorChristian König <deathsimple@vodafone.de>
Thu, 8 Mar 2012 13:10:40 +0000 (14:10 +0100)
committerChristian König <deathsimple@vodafone.de>
Fri, 9 Mar 2012 11:45:09 +0000 (12:45 +0100)
This fixes a crash in XBMC, but we still doesn't see a picture.

Signed-off-by: Christian König <deathsimple@vodafone.de>
src/gallium/winsys/g3dvl/dri/dri_winsys.c

index c65c82c8b05659c7954534c724d519bc3e965524..afaabaaa680b40777342c5230df110f270bb9c70 100644 (file)
@@ -171,11 +171,13 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
 {
    struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
 
-   struct winsys_handle dri2_front_handle;
+   struct winsys_handle dri2_handle;
    struct pipe_resource template, *tex;
 
    xcb_dri2_get_buffers_reply_t *reply;
-   xcb_dri2_dri2_buffer_t *buffers;
+   xcb_dri2_dri2_buffer_t *buffers, *back_left;
+
+   unsigned i;
 
    assert(scrn);
 
@@ -189,28 +191,39 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
    if (!reply)
       return NULL;
 
-   assert(reply->count == 1);
    buffers = xcb_dri2_get_buffers_buffers(reply);
    if (!buffers)  {
       free(reply);
       return NULL;
    }
 
+   for (i = 0; i < reply->count; ++i) {
+      if (buffers[i].attachment == XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT) {
+         back_left = &buffers[i];
+         break;
+      }
+   }
+
+   if (i == reply->count) {
+      free(reply);
+      return NULL;
+   }
+
    if (reply->width != scrn->width || reply->height != scrn->height) {
       vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
       vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
       scrn->width = reply->width;
       scrn->height = reply->height;
 
-   } else if (buffers[0].name != scrn->buffer_names[scrn->current_buffer]) {
+   } else if (back_left->name != scrn->buffer_names[scrn->current_buffer]) {
       vl_compositor_reset_dirty_area(&scrn->dirty_areas[scrn->current_buffer]);
-      scrn->buffer_names[scrn->current_buffer] = buffers[0].name;
+      scrn->buffer_names[scrn->current_buffer] = back_left->name;
    }
 
-   memset(&dri2_front_handle, 0, sizeof(dri2_front_handle));
-   dri2_front_handle.type = DRM_API_HANDLE_TYPE_SHARED;
-   dri2_front_handle.handle = buffers[0].name;
-   dri2_front_handle.stride = buffers[0].pitch;
+   memset(&dri2_handle, 0, sizeof(dri2_handle));
+   dri2_handle.type = DRM_API_HANDLE_TYPE_SHARED;
+   dri2_handle.handle = back_left->name;
+   dri2_handle.stride = back_left->pitch;
 
    memset(&template, 0, sizeof(template));
    template.target = PIPE_TEXTURE_2D;
@@ -224,7 +237,7 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
    template.bind = PIPE_BIND_RENDER_TARGET;
    template.flags = 0;
 
-   tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_front_handle);
+   tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_handle);
    free(reply);
 
    return tex;