egl_dri2: Implement EGL_KHR_gl_renderbuffer_image
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 0c2dfe6..d775b5e 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -103,12 +103,6 @@
 {
    _EGLImage   base;
    __DRIimage *dri_image;
-   int         width;
-   int         height;
-   int         name;
-   int         pitch;
-   int         cpp;
-   int         format;
 };
 
 /* standard typecasts */
@@ -694,6 +688,7 @@
    disp->ClientAPIsMask = EGL_OPENGL_BIT;
    disp->Extensions.KHR_image_base = EGL_TRUE;
    disp->Extensions.KHR_image_pixmap = EGL_TRUE;
+   disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
 
    /* we're supporting EGL 1.4 */
    *major = 1;
@@ -1107,9 +1102,8 @@
 }
 
 static _EGLImage *
-dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
-		      _EGLContext *ctx, EGLenum target,
-		      EGLClientBuffer buffer, const EGLint *attr_list)
+dri2_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
+			     EGLClientBuffer buffer, const EGLint *attr_list)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
@@ -1122,6 +1116,92 @@
    xcb_get_geometry_cookie_t geometry_cookie;
    xcb_get_geometry_reply_t *geometry_reply;
    xcb_generic_error_t *error;
+   int stride, format;
+
+   drawable = (xcb_drawable_t) buffer;
+   xcb_dri2_create_drawable (dri2_dpy->conn, drawable);
+   attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT;
+   buffers_cookie =
+      xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
+				      drawable, 1, 1, attachments);
+   geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable);
+   buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn,
+					       buffers_cookie, NULL);
+   buffers = xcb_dri2_get_buffers_buffers (buffers_reply);
+   if (buffers == NULL) {
+      return NULL;
+   }
+
+   geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn,
+					    geometry_cookie, &error);
+   if (geometry_reply == NULL || error != NULL) {
+      _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
+      free(error);
+      free(buffers_reply);
+   }
+
+   switch (geometry_reply->depth) {
+   case 16:
+      format = __DRI_IMAGE_FORMAT_RGB565;
+      break;
+   case 24:
+      format = __DRI_IMAGE_FORMAT_XRGB8888;
+      break;
+   case 32:
+      format = __DRI_IMAGE_FORMAT_ARGB8888;
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER,
+		"dri2_create_image_khr: unsupported pixmap depth");
+      free(buffers_reply);
+      free(geometry_reply);
+      return NULL;
+   }
+
+   dri2_img = malloc(sizeof *dri2_img);
+   if (!dri2_img) {
+      free(buffers_reply);
+      free(geometry_reply);
+      _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   if (!_eglInitImage(&dri2_img->base, disp, attr_list)) {
+      free(buffers_reply);
+      free(geometry_reply);
+      return EGL_NO_IMAGE_KHR;
+   }
+
+   stride = buffers[0].pitch / buffers[0].cpp;
+   dri2_img->dri_image =
+      dri2_dpy->image->createImageFromName(dri2_ctx->dri_context,
+					   buffers_reply->width,
+					   buffers_reply->height,
+					   format,
+					   buffers[0].name,
+					   stride,
+					   dri2_img);
+
+   free(buffers_reply);
+   free(geometry_reply);
+
+   return &dri2_img->base;
+}
+
+static _EGLImage *
+dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
+				   EGLClientBuffer buffer,
+				   const EGLint *attr_list)
+{
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+   struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+   struct dri2_egl_image *dri2_img;
+   GLuint renderbuffer = (GLuint) buffer;
+
+   if (renderbuffer == 0) {
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
 
    dri2_img = malloc(sizeof *dri2_img);
    if (!dri2_img) {
@@ -1132,70 +1212,30 @@
    if (!_eglInitImage(&dri2_img->base, disp, attr_list))
       return EGL_NO_IMAGE_KHR;
 
-   switch (target) {
-   case EGL_NATIVE_PIXMAP_KHR:
-      drawable = (xcb_drawable_t) buffer;
-      xcb_dri2_create_drawable (dri2_dpy->conn, drawable);
-      attachments[0] = XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT;
-      buffers_cookie =
-	 xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
-					 drawable, 1, 1, attachments);
-      geometry_cookie = xcb_get_geometry (dri2_dpy->conn, drawable);
-      buffers_reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn,
-						  buffers_cookie, NULL);
-      buffers = xcb_dri2_get_buffers_buffers (buffers_reply);
-      if (buffers == NULL) {
-	 free(dri2_img);
-	 return NULL;
-      }
-
-      geometry_reply = xcb_get_geometry_reply (dri2_dpy->conn,
-					       geometry_cookie, &error);
-      if (geometry_reply == NULL || error != NULL) {
-	 _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
-	 free(error);
-	 free(dri2_img);
-	 free(buffers_reply);
-      }
-
-      dri2_img->width = buffers_reply->width;
-      dri2_img->height = buffers_reply->height;
-      dri2_img->name = buffers[0].name;
-      dri2_img->pitch = buffers[0].pitch / buffers[0].cpp;
-      dri2_img->cpp = buffers[0].cpp;
-      switch (geometry_reply->depth) {
-      case 16:
-	 dri2_img->format = __DRI_IMAGE_FORMAT_RGB565;
-	 break;
-      case 24:
-	 dri2_img->format = __DRI_IMAGE_FORMAT_XRGB8888;
-	 break;
-      case 32:
-	 dri2_img->format = __DRI_IMAGE_FORMAT_ARGB8888;
-	 break;
-      }
-      free(buffers_reply);
-      free(geometry_reply);
-      break;
-
-   default:
-      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
-      free(dri2_img);
-      return EGL_NO_IMAGE_KHR;
-   }
-
-   dri2_img->dri_image =
-      dri2_dpy->image->createImageFromName(dri2_ctx->dri_context,
-					   dri2_img->width,
-					   dri2_img->height,
-					   dri2_img->format,
-					   dri2_img->name,
-					   dri2_img->pitch,
-					   dri2_img);
+   dri2_img->dri_image = 
+      dri2_dpy->image->createImageFromRenderbuffer(dri2_ctx->dri_context,
+						   renderbuffer,
+						   dri2_img);
 
    return &dri2_img->base;
 }
 
+static _EGLImage *
+dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+		      _EGLContext *ctx, EGLenum target,
+		      EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   switch (target) {
+   case EGL_NATIVE_PIXMAP_KHR:
+      return dri2_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+   case EGL_GL_RENDERBUFFER_KHR:
+      return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
+   default:
+      _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+}
+
 static EGLBoolean
 dri2_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
 {