<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2012/12/14 Kristian Høgsberg <span dir="ltr"><<a href="mailto:krh@bitplanet.net" target="_blank">krh@bitplanet.net</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
We used to keep the color buffers in the dri_buffers array and<br>
swap __DRI_BUFFER_BACK_LEFT and __DRI_BUFFER_FRONT_LEFT around there<br>
and swap third_buffer in in case we needed to triple buffer.  That<br>
gets a little fidgety with all the swaps, so lets use the<br>
color_buffers pool like the gbm platform does.  We track the color buffers,<br>
their corresponding wl_buffer and locked status here and just plug<br>
a free one into dri2_surf->buffers when we need to.<br></blockquote><div><br></div><div>Doesn't this change the triple buffering behaviour? Before we would release the dri_buffer once the third buffer wasn't necessary. With this patch, we release the wl_buffer but keep the dri_buffer around.<br>
<br></div><div>Cheers,<br>Ander<br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This is a nice clean-up in itself, but it also sets us up to track<br>
buffer age in the color_buffers structs.<br>
---<br>
 src/egl/drivers/dri2/egl_dri2.h         |   23 +-<br>
 src/egl/drivers/dri2/platform_wayland.c |  367 +++++++++++--------------------<br>
 2 files changed, 135 insertions(+), 255 deletions(-)<br>
<br>
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h<br>
index eb8c06e..84ea2a6 100644<br>
--- a/src/egl/drivers/dri2/egl_dri2.h<br>
+++ b/src/egl/drivers/dri2/egl_dri2.h<br>
@@ -172,28 +172,29 @@ struct dri2_egl_surface<br>
<br>
 #ifdef HAVE_WAYLAND_PLATFORM<br>
    struct wl_egl_window  *wl_win;<br>
-   struct wl_egl_pixmap  *wl_pix;<br>
-   struct wl_buffer      *wl_drm_buffer[WL_BUFFER_COUNT];<br>
-   int                    wl_buffer_lock[WL_BUFFER_COUNT];<br>
    int                    dx;<br>
    int                    dy;<br>
-   __DRIbuffer           *dri_buffers[__DRI_BUFFER_COUNT];<br>
-   __DRIbuffer           *third_buffer;<br>
-   __DRIbuffer           *pending_buffer;<br>
    struct wl_callback    *frame_callback;<br>
    int                   format;<br>
 #endif<br>
<br>
 #ifdef HAVE_DRM_PLATFORM<br>
    struct gbm_dri_surface *gbm_surf;<br>
+#endif<br>
+<br>
+#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)<br>
+   __DRIbuffer           *dri_buffers[__DRI_BUFFER_COUNT];<br>
    struct {<br>
+#ifdef HAVE_WAYLAND_PLATFORM<br>
+      struct wl_buffer   *wl_buffer;<br>
+      __DRIbuffer        *dri_buffer;<br>
+#endif<br>
+#ifdef HAVE_DRM_PLATFORM<br>
       struct gbm_bo       *bo;<br>
-      int                  locked;<br>
-      int                  age;<br>
-   } color_buffers[3], *back, *current;<br>
-#ifndef HAVE_WAYLAND_PLATFORM<br>
-   __DRIbuffer           *dri_buffers[__DRI_BUFFER_COUNT];<br>
 #endif<br>
+      int                 locked;<br>
+      int                 age;<br>
+   } color_buffers[3], *back, *current;<br>
 #endif<br>
<br>
 #ifdef HAVE_ANDROID_PLATFORM<br>
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c<br>
index 260a80d..3c6bdd9 100644<br>
--- a/src/egl/drivers/dri2/platform_wayland.c<br>
+++ b/src/egl/drivers/dri2/platform_wayland.c<br>
@@ -1,5 +1,5 @@<br>
 /*<br>
- * Copyright © 2011 Intel Corporation<br>
+ * Copyright © 2011-2012 Intel Corporation<br>
  *<br>
  * Permission is hereby granted, free of charge, to any person obtaining a<br>
  * copy of this software and associated documentation files (the "Software"),<br>
@@ -79,18 +79,16 @@ wl_buffer_release(void *data, struct wl_buffer *buffer)<br>
    struct dri2_egl_surface *dri2_surf = data;<br>
    int i;<br>
<br>
-   for (i = 0; i < WL_BUFFER_COUNT; ++i)<br>
-      if (dri2_surf->wl_drm_buffer[i] == buffer)<br>
+   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); ++i)<br>
+      if (dri2_surf->color_buffers[i].wl_buffer == buffer)<br>
          break;<br>
<br>
-   assert(i <= WL_BUFFER_COUNT);<br>
-<br>
-   /* not found? */<br>
-   if (i == WL_BUFFER_COUNT)<br>
+   if (i == ARRAY_SIZE(dri2_surf->color_buffers)) {<br>
+      wl_buffer_destroy(buffer);<br>
       return;<br>
+   }<br>
<br>
-   dri2_surf->wl_buffer_lock[i] = 0;<br>
-<br>
+   dri2_surf->color_buffers[i].locked = 0;<br>
 }<br>
<br>
 static struct wl_buffer_listener wl_buffer_listener = {<br>
@@ -118,7 +116,6 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,<br>
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);<br>
    struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);<br>
    struct dri2_egl_surface *dri2_surf;<br>
-   int i;<br>
<br>
    (void) drv;<br>
<br>
@@ -128,21 +125,10 @@ dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,<br>
       return NULL;<br>
    }<br>
<br>
+   memset(dri2_surf, 0, sizeof *dri2_surf);<br>
    if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))<br>
       goto cleanup_surf;<br>
<br>
-   for (i = 0; i < WL_BUFFER_COUNT; ++i) {<br>
-      dri2_surf->wl_drm_buffer[i] = NULL;<br>
-      dri2_surf->wl_buffer_lock[i] = 0;<br>
-   }<br>
-<br>
-   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)<br>
-      dri2_surf->dri_buffers[i] = NULL;<br>
-<br>
-   dri2_surf->pending_buffer = NULL;<br>
-   dri2_surf->third_buffer = NULL;<br>
-   dri2_surf->frame_callback = NULL;<br>
-<br>
    if (conf->AlphaSize == 0)<br>
       dri2_surf->format = WL_DRM_FORMAT_XRGB8888;<br>
    else<br>
@@ -212,24 +198,23 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)<br>
<br>
    (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);<br>
<br>
-   for (i = 0; i < WL_BUFFER_COUNT; ++i)<br>
-      if (dri2_surf->wl_drm_buffer[i])<br>
-         wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);<br>
+   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {<br>
+      if (dri2_surf->color_buffers[i].wl_buffer)<br>
+         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);<br>
+      if (dri2_surf->color_buffers[i].dri_buffer)<br>
+         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
+                                       dri2_surf->color_buffers[i].dri_buffer);<br>
+   }<br>
<br>
-   for (i = 0; i < __DRI_BUFFER_COUNT; ++i)<br>
-      if (dri2_surf->dri_buffers[i])<br>
+   for (i = 0; i < __DRI_BUFFER_COUNT; i++)<br>
+      if (dri2_surf->dri_buffers[i] &&<br>
+          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)<br>
          dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
                                        dri2_surf->dri_buffers[i]);<br>
<br>
-   if (dri2_surf->third_buffer) {<br>
-      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
-                                    dri2_surf->third_buffer);<br>
-   }<br>
-<br>
    if (dri2_surf->frame_callback)<br>
       wl_callback_destroy(dri2_surf->frame_callback);<br>
<br>
-<br>
    if (dri2_surf->base.Type == EGL_WINDOW_BIT) {<br>
       dri2_surf->wl_win->private = NULL;<br>
       dri2_surf->wl_win->resize_callback = NULL;<br>
@@ -240,173 +225,90 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)<br>
    return EGL_TRUE;<br>
 }<br>
<br>
-static struct wl_buffer *<br>
-wayland_create_buffer(struct dri2_egl_surface *dri2_surf,<br>
-                      __DRIbuffer *buffer)<br>
-{<br>
-   struct dri2_egl_display *dri2_dpy =<br>
-      dri2_egl_display(dri2_surf->base.Resource.Display);<br>
-   struct wl_buffer *buf;<br>
-<br>
-   buf = wl_drm_create_buffer(dri2_dpy->wl_drm, buffer->name,<br>
-                              dri2_surf->base.Width, dri2_surf->base.Height,<br>
-                              buffer->pitch, dri2_surf->format);<br>
-   wl_buffer_add_listener(buf, &wl_buffer_listener, dri2_surf);<br>
-<br>
-   return buf;<br>
-}<br>
-<br>
 static void<br>
-dri2_process_back_buffer(struct dri2_egl_surface *dri2_surf, unsigned format)<br>
+dri2_release_buffers(struct dri2_egl_surface *dri2_surf)<br>
 {<br>
    struct dri2_egl_display *dri2_dpy =<br>
       dri2_egl_display(dri2_surf->base.Resource.Display);<br>
+   int i;<br>
<br>
-   (void) format;<br>
+   for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {<br>
+      if (dri2_surf->color_buffers[i].wl_buffer &&<br>
+          !dri2_surf->color_buffers[i].locked)<br>
+         wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);<br>
+      if (dri2_surf->color_buffers[i].dri_buffer)<br>
+         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
+                                       dri2_surf->color_buffers[i].dri_buffer);<br>
<br>
-   switch (dri2_surf->base.Type) {<br>
-   case EGL_WINDOW_BIT:<br>
-      /* allocate a front buffer for our double-buffered window*/<br>
-      if (dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] != NULL)<br>
-         break;<br>
-      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =<br>
-         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,<br>
-               __DRI_BUFFER_FRONT_LEFT, format,<br>
-               dri2_surf->base.Width, dri2_surf->base.Height);<br>
-      break;<br>
-   default:<br>
-      break;<br>
+      dri2_surf->color_buffers[i].wl_buffer = NULL;<br>
+      dri2_surf->color_buffers[i].dri_buffer = NULL;<br>
+      dri2_surf->color_buffers[i].locked = 0;<br>
    }<br>
-}<br>
-<br>
-static void<br>
-dri2_release_pending_buffer(void *data,<br>
-                           struct wl_callback *callback, uint32_t time)<br>
-{<br>
-   struct dri2_egl_surface *dri2_surf = data;<br>
-   struct dri2_egl_display *dri2_dpy =<br>
-      dri2_egl_display(dri2_surf->base.Resource.Display);<br>
-<br>
-   /* FIXME: print internal error */<br>
-   if (!dri2_surf->pending_buffer)<br>
-      return;<br>
-<br>
-   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
-                                 dri2_surf->pending_buffer);<br>
-   dri2_surf->pending_buffer = NULL;<br>
<br>
-   wl_callback_destroy(callback);<br>
+   for (i = 0; i < __DRI_BUFFER_COUNT; i++)<br>
+      if (dri2_surf->dri_buffers[i] &&<br>
+          dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)<br>
+         dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
+                                       dri2_surf->dri_buffers[i]);<br>
 }<br>
<br>
-static const struct wl_callback_listener release_buffer_listener = {<br>
-   dri2_release_pending_buffer<br>
-};<br>
-<br>
-static void<br>
-dri2_release_buffers(struct dri2_egl_surface *dri2_surf)<br>
+static int<br>
+get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)<br>
 {<br>
    struct dri2_egl_display *dri2_dpy =<br>
       dri2_egl_display(dri2_surf->base.Resource.Display);<br>
-   struct wl_callback *callback;<br>
    int i;<br>
<br>
-   if (dri2_surf->third_buffer) {<br>
-      dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
-                                    dri2_surf->third_buffer);<br>
-      dri2_surf->third_buffer = NULL;<br>
-   }<br>
+   /* There might be a buffer release already queued that wasn't processed */<br>
+   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);<br>
<br>
-   for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {<br>
-      if (dri2_surf->dri_buffers[i]) {<br>
-         switch (i) {<br>
-         case __DRI_BUFFER_FRONT_LEFT:<br>
-            if (dri2_surf->pending_buffer)<br>
-               roundtrip(dri2_dpy);<br>
-            dri2_surf->pending_buffer = dri2_surf->dri_buffers[i];<br>
-            callback = wl_display_sync(dri2_dpy->wl_dpy);<br>
-           wl_callback_add_listener(callback,<br>
-                                    &release_buffer_listener, dri2_surf);<br>
-            wl_proxy_set_queue((struct wl_proxy *) callback,<br>
-                               dri2_dpy->wl_queue);<br>
-            break;<br>
-         default:<br>
-            dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
-                                          dri2_surf->dri_buffers[i]);<br>
-            break;<br>
-         }<br>
-         dri2_surf->dri_buffers[i] = NULL;<br>
+   if (dri2_surf->back == NULL) {<br>
+      for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {<br>
+        if (!dri2_surf->color_buffers[i].locked) {<br>
+           dri2_surf->back = &dri2_surf->color_buffers[i];<br>
+           break;<br>
+        }<br>
       }<br>
    }<br>
-}<br>
<br>
-static inline void<br>
-pointer_swap(const void **p1, const void **p2)<br>
-{<br>
-   const void *tmp = *p1;<br>
-   *p1 = *p2;<br>
-   *p2 = tmp;<br>
-}<br>
-<br>
-static void<br>
-destroy_third_buffer(struct dri2_egl_surface *dri2_surf)<br>
-{<br>
-   struct dri2_egl_display *dri2_dpy =<br>
-      dri2_egl_display(dri2_surf->base.Resource.Display);<br>
-<br>
-   if (dri2_surf->third_buffer == NULL)<br>
-      return;<br>
-<br>
-   dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,<br>
-                                 dri2_surf->third_buffer);<br>
-   dri2_surf->third_buffer = NULL;<br>
-<br>
-   if (dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD])<br>
-      wl_buffer_destroy(dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD]);<br>
-   dri2_surf->wl_drm_buffer[WL_BUFFER_THIRD] = NULL;<br>
-   dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD] = 0;<br>
-}<br>
+   if (dri2_surf->back == NULL)<br>
+      return -1;<br>
+   if (dri2_surf->back->dri_buffer == NULL) {<br>
+      dri2_surf->back->dri_buffer =<br>
+         dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,<br>
+                                        __DRI_BUFFER_BACK_LEFT, 32,<br>
+                                        dri2_surf->base.Width,<br>
+                                        dri2_surf->base.Height);<br>
+   }<br>
+   if (dri2_surf->back->dri_buffer == NULL)<br>
+      return -1;<br>
<br>
-static void<br>
-swap_wl_buffers(struct dri2_egl_surface *dri2_surf,<br>
-                enum wayland_buffer_type a, enum wayland_buffer_type b)<br>
-{<br>
-   int tmp;<br>
+   memcpy(buffer, dri2_surf->back->dri_buffer, sizeof *buffer);<br>
<br>
-   tmp = dri2_surf->wl_buffer_lock[a];<br>
-   dri2_surf->wl_buffer_lock[a] = dri2_surf->wl_buffer_lock[b];<br>
-   dri2_surf->wl_buffer_lock[b] = tmp;<br>
-<br>
-   pointer_swap((const void **) &dri2_surf->wl_drm_buffer[a],<br>
-                (const void **) &dri2_surf->wl_drm_buffer[b]);<br>
+   return 0;<br>
 }<br>
<br>
-static void<br>
-swap_back_and_third(struct dri2_egl_surface *dri2_surf)<br>
+static int<br>
+get_aux_bo(struct dri2_egl_surface *dri2_surf,<br>
+          unsigned int attachment, unsigned int format, __DRIbuffer *buffer)<br>
 {<br>
-   if (dri2_surf->wl_buffer_lock[WL_BUFFER_THIRD])<br>
-      destroy_third_buffer(dri2_surf);<br>
-<br>
-   pointer_swap((const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT],<br>
-                (const void **) &dri2_surf->third_buffer);<br>
-<br>
-   swap_wl_buffers(dri2_surf, WL_BUFFER_BACK, WL_BUFFER_THIRD);<br>
-}<br>
+   struct dri2_egl_display *dri2_dpy =<br>
+      dri2_egl_display(dri2_surf->base.Resource.Display);<br>
+   __DRIbuffer *b = dri2_surf->dri_buffers[attachment];<br>
+<br>
+   if (b == NULL) {<br>
+      b = dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,<br>
+                                        attachment, format,<br>
+                                        dri2_surf->base.Width,<br>
+                                        dri2_surf->base.Height);<br>
+      dri2_surf->dri_buffers[attachment] = b;<br>
+   }<br>
+   if (b == NULL)<br>
+      return -1;<br>
<br>
-static void<br>
-dri2_prior_buffer_creation(struct dri2_egl_surface *dri2_surf,<br>
-                           unsigned int type)<br>
-{<br>
-   switch (type) {<br>
-   case __DRI_BUFFER_BACK_LEFT:<br>
-         if (dri2_surf->wl_buffer_lock[WL_BUFFER_BACK])<br>
-            swap_back_and_third(dri2_surf);<br>
-         else if (dri2_surf->third_buffer)<br>
-            destroy_third_buffer(dri2_surf);<br>
-         break;<br>
-   default:<br>
-         break;<br>
+   memcpy(buffer, b, sizeof *buffer);<br>
<br>
-   }<br>
+   return 0;<br>
 }<br>
<br>
 static __DRIbuffer *<br>
@@ -418,10 +320,7 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,<br>
    struct dri2_egl_surface *dri2_surf = loaderPrivate;<br>
    struct dri2_egl_display *dri2_dpy =<br>
       dri2_egl_display(dri2_surf->base.Resource.Display);<br>
-   int i;<br>
-<br>
-   /* There might be a buffer release already queued that wasn't processed */<br>
-   wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);<br>
+   int i, j;<br>
<br>
    if (dri2_surf->base.Type == EGL_WINDOW_BIT &&<br>
        (dri2_surf->base.Width != dri2_surf->wl_win->width ||<br>
@@ -433,47 +332,28 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,<br>
       dri2_surf->base.Height = dri2_surf->wl_win->height;<br>
       dri2_surf->dx = dri2_surf->wl_win->dx;<br>
       dri2_surf->dy = dri2_surf->wl_win->dy;<br>
-<br>
-      for (i = 0; i < WL_BUFFER_COUNT; ++i) {<br>
-         if (dri2_surf->wl_drm_buffer[i])<br>
-            wl_buffer_destroy(dri2_surf->wl_drm_buffer[i]);<br>
-         dri2_surf->wl_drm_buffer[i]  = NULL;<br>
-         dri2_surf->wl_buffer_lock[i] = 0;<br>
-      }<br>
    }<br>
<br>
-   dri2_surf->buffer_count = 0;<br>
-   for (i = 0; i < 2*count; i+=2) {<br>
-      assert(attachments[i] < __DRI_BUFFER_COUNT);<br>
-      assert(dri2_surf->buffer_count < 5);<br>
-<br>
-      dri2_prior_buffer_creation(dri2_surf, attachments[i]);<br>
-<br>
-      if (dri2_surf->dri_buffers[attachments[i]] == NULL) {<br>
-<br>
-         dri2_surf->dri_buffers[attachments[i]] =<br>
-            dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,<br>
-                  attachments[i], attachments[i+1],<br>
-                  dri2_surf->base.Width, dri2_surf->base.Height);<br>
-<br>
-         if (!dri2_surf->dri_buffers[attachments[i]])<br>
-            continue;<br>
-<br>
-         if (attachments[i] == __DRI_BUFFER_BACK_LEFT)<br>
-            dri2_process_back_buffer(dri2_surf, attachments[i+1]);<br>
+   for (i = 0, j = 0; i < 2 * count; i += 2, j++) {<br>
+      switch (attachments[i]) {<br>
+      case __DRI_BUFFER_BACK_LEFT:<br>
+        if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {<br>
+           _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");<br>
+           return NULL;<br>
+        }<br>
+        break;<br>
+      default:<br>
+        if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],<br>
+                       &dri2_surf->buffers[j]) < 0) {<br>
+           _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");<br>
+           return NULL;<br>
+        }<br>
+        break;<br>
       }<br>
-<br>
-      memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],<br>
-             dri2_surf->dri_buffers[attachments[i]],<br>
-             sizeof(__DRIbuffer));<br>
-<br>
-      dri2_surf->buffer_count++;<br>
    }<br>
<br>
-   assert(dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);<br>
-<br>
-   *out_count = dri2_surf->buffer_count;<br>
-   if (dri2_surf->buffer_count == 0)<br>
+   *out_count = j;<br>
+   if (j == 0)<br>
           return NULL;<br>
<br>
    *width = dri2_surf->base.Width;<br>
@@ -542,7 +422,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)<br>
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);<br>
    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);<br>
    struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);<br>
-   int ret = 0;<br>
+   int i, ret = 0;<br>
<br>
    while (dri2_surf->frame_callback && ret != -1)<br>
       ret = wl_display_dispatch_queue(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);<br>
@@ -555,39 +435,39 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)<br>
    wl_proxy_set_queue((struct wl_proxy *) dri2_surf->frame_callback,<br>
                       dri2_dpy->wl_queue);<br>
<br>
-   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {<br>
-      pointer_swap(<br>
-           (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT],<br>
-           (const void **) &dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);<br>
-<br>
-      dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]->attachment =<br>
-        __DRI_BUFFER_FRONT_LEFT;<br>
-      dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =<br>
-        __DRI_BUFFER_BACK_LEFT;<br>
-<br>
-      swap_wl_buffers(dri2_surf, WL_BUFFER_FRONT, WL_BUFFER_BACK);<br>
+   if (dri2_surf->back->wl_buffer == NULL) {<br>
+      dri2_surf->back->wl_buffer =<br>
+         wl_drm_create_buffer(dri2_dpy->wl_drm,<br>
+                              dri2_surf->back->dri_buffer->name,<br>
+                              dri2_surf->base.Width,<br>
+                              dri2_surf->base.Height,<br>
+                              dri2_surf->back->dri_buffer->pitch,<br>
+                              dri2_surf->format);<br>
+      wl_proxy_set_queue((struct wl_proxy *) dri2_surf->back->wl_buffer,<br>
+                         dri2_dpy->wl_queue);<br>
+      wl_buffer_add_listener(dri2_surf->back->wl_buffer,<br>
+                             &wl_buffer_listener, dri2_surf);<br>
+   }<br>
<br>
-      if (!dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT])<br>
-        dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT] =<br>
-           wayland_create_buffer(dri2_surf,<br>
-                 dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT]);<br>
+   dri2_surf->back->locked = 1;<br>
+   dri2_surf->current = dri2_surf->back;<br>
+   dri2_surf->current->age = 1;<br>
+   dri2_surf->back = NULL;<br>
<br>
-      wl_surface_attach(dri2_surf->wl_win->surface,<br>
-           dri2_surf->wl_drm_buffer[WL_BUFFER_FRONT],<br>
-           dri2_surf->dx, dri2_surf->dy);<br>
-      dri2_surf->wl_buffer_lock[WL_BUFFER_FRONT] = 1;<br>
+   wl_surface_attach(dri2_surf->wl_win->surface,<br>
+                     dri2_surf->current->wl_buffer,<br>
+                     dri2_surf->dx, dri2_surf->dy);<br>
<br>
-      dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;<br>
-      dri2_surf->wl_win->attached_height = dri2_surf->base.Height;<br>
-      /* reset resize growing parameters */<br>
-      dri2_surf->dx = 0;<br>
-      dri2_surf->dy = 0;<br>
+   dri2_surf->wl_win->attached_width  = dri2_surf->base.Width;<br>
+   dri2_surf->wl_win->attached_height = dri2_surf->base.Height;<br>
+   /* reset resize growing parameters */<br>
+   dri2_surf->dx = 0;<br>
+   dri2_surf->dy = 0;<br>
<br>
-      wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,<br>
-           dri2_surf->base.Width, dri2_surf->base.Height);<br>
+   wl_surface_damage(dri2_surf->wl_win->surface, 0, 0,<br>
+                     dri2_surf->base.Width, dri2_surf->base.Height);<br>
<br>
-      wl_surface_commit(dri2_surf->wl_win->surface);<br>
-   }<br>
+   wl_surface_commit(dri2_surf->wl_win->surface);<br>
<br>
    _EGLContext *ctx;<br>
    if (dri2_drv->glFlush) {<br>
@@ -595,7 +475,6 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)<br>
       if (ctx && ctx->DrawSurface == &dri2_surf->base)<br>
          dri2_drv->glFlush();<br>
    }<br>
-<br>
    (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);<br>
    (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.7.10.2<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>