CHROMIUM: egl/surfaceless: Use double-buffered pbuffer configuration

Using a double-buffered pbuffer makes an additional 74
dEQP tests pass on the surfaceless platform.

Change-Id: I5075fbd96d0f6089c5f73003e1af18dcdec90694
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 83273ca..b1c6638 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -294,6 +294,7 @@
 
 #if defined(HAVE_SURFACELESS_PLATFORM)
       __DRIimage           *front;
+      __DRIimage           *back;
       unsigned int         format;
 #endif
 
diff --git a/src/egl/drivers/dri2/platform_surfaceless.c b/src/egl/drivers/dri2/platform_surfaceless.c
index e4b791e..e2934c2 100644
--- a/src/egl/drivers/dri2/platform_surfaceless.c
+++ b/src/egl/drivers/dri2/platform_surfaceless.c
@@ -23,6 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -41,17 +42,17 @@
 surfaceless_alloc_image(struct dri2_egl_display *dri2_dpy,
                      struct dri2_egl_surface *dri2_surf)
 {
-      __DRIimage *img = NULL;
+   __DRIimage *img = NULL;
 
-      img = dri2_dpy->image->createImage(
-               dri2_dpy->dri_screen,
-               dri2_surf->base.Width,
-               dri2_surf->base.Height,
-               dri2_surf->format,
-               0,
-               NULL);
+   img = dri2_dpy->image->createImage(
+            dri2_dpy->dri_screen,
+            dri2_surf->base.Width,
+            dri2_surf->base.Height,
+            dri2_surf->format,
+            0,
+            NULL);
 
-      return img;
+   return img;
 }
 
 static void
@@ -64,6 +65,20 @@
       dri2_dpy->image->destroyImage(dri2_surf->front);
       dri2_surf->front = NULL;
    }
+   if(dri2_surf->back) {
+      dri2_dpy->image->destroyImage(dri2_surf->back);
+      dri2_surf->back = NULL;
+   }
+}
+
+static EGLBoolean
+surfaceless_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+   struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+    __DRIimage *temp = dri2_surf->back;
+
+   dri2_surf->back = dri2_surf->front;
+   dri2_surf->front = temp;
 }
 
 static int
@@ -89,6 +104,14 @@
       buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
       buffers->front = dri2_surf->front;
    }
+   if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+      if (!dri2_surf->back)
+         dri2_surf->back =
+            surfaceless_alloc_image(dri2_dpy, dri2_surf);
+
+      buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+      buffers->back = dri2_surf->back;
+   }
 
    return 1;
 }
@@ -102,9 +125,11 @@
    struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
    struct dri2_egl_surface *dri2_surf;
    const __DRIconfig *config;
+   bool srgb;
 
-   // Make sure to calloc so front _DRIimage
-   // is originally NULL.
+   /* Make sure to calloc so all pointers
+    * are originally NULL.
+    */
    dri2_surf = calloc(1, sizeof *dri2_surf);
 
    if(!dri2_surf)
@@ -113,8 +138,14 @@
    if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list))
       goto cleanup_surface;
 
-   config = dri2_get_dri_config(dri2_conf, type,
-                                dri2_surf->base.GLColorspace);
+   /* Only double buffered configurations exist at this point (single buffered
+    * configs were filtered out in surfaceless_add_configs_for_visuals).
+    */
+   srgb = (dri2_surf->base.GLColorspace == EGL_GL_COLORSPACE_SRGB_KHR);
+   config = dri2_conf->dri_double_config[srgb];
+
+   if (!config)
+      goto cleanup_surface;
 
    dri2_surf->dri_drawable =
       (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
@@ -182,6 +213,15 @@
       for (j = 0; dri2_dpy->driver_configs[j]; j++) {
          const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
          struct dri2_egl_config *dri2_conf;
+         unsigned int double_buffered = 0;
+
+         dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[j],
+            __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered);
+
+         /* support only double buffered configs */
+         if (!double_buffered)
+            continue;
+
          dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j],
                count + 1, surface_type, NULL, visuals[i]);
          if (dri2_conf)
@@ -200,6 +240,7 @@
    .create_pbuffer_surface = dri2_surfaceless_create_pbuffer_surface,
    .destroy_surface = surfaceless_destroy_surface,
    .create_image = dri2_create_image_khr,
+   .swap_buffers = surfaceless_swap_buffers,
    .swap_interval = dri2_fallback_swap_interval,
    .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
    .swap_buffers_region = dri2_fallback_swap_buffers_region,