egl_dri2: Implement EGL_KHR_gl_renderbuffer_image

This commit is contained in:
Kristian Høgsberg 2010-02-26 14:51:11 -05:00
parent d7322c9d42
commit 557c20b309
1 changed files with 109 additions and 69 deletions

View File

@ -103,12 +103,6 @@ struct dri2_egl_image
{
_EGLImage base;
__DRIimage *dri_image;
int width;
int height;
int name;
int pitch;
int cpp;
int format;
};
/* standard typecasts */
@ -694,6 +688,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
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 @@ dri2_release_tex_image(_EGLDriver *drv,
}
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 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
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 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
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)
{