summaryrefslogtreecommitdiffstats
path: root/src/egl
diff options
context:
space:
mode:
authorRobert Bragg <[email protected]>2012-01-10 22:16:26 +0000
committerKristian Høgsberg <[email protected]>2012-01-11 12:16:47 -0500
commit670f182a1f0401f34b1fb7ead50644589737f0d2 (patch)
tree5160c24346db79d47699271e374ddba55be3add5 /src/egl
parent765ed3a6a9317607311bac1dcb0edee13ebcee16 (diff)
egl_dri2/wayland: handle creating xrgb8888 images
When creating an EGLImage from a struct wl_buffer * this ensures that we create an XRGB8888 image if the wayland buffer doesn't have an alpha channel. To determine if a wl_buffer has a valid alpha channel this patch adds an internal wayland_drm_buffer_has_alpha() function. It's important to get the internal format for an EGLImage right so that if a GL texture is later created from the image then the GL driver will know if it should sample the alpha from the texture or flatten it to a constant of 1.0. This avoids needing fragment program workarounds in wayland compositors to manually ignore the alpha component of textures created from wayland buffers. krh: Edited to use wl_buffer_get_format() instead of wl_buffer_has_alpha(). Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/egl')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c125
-rw-r--r--src/egl/wayland/wayland-drm/wayland-drm.c8
-rw-r--r--src/egl/wayland/wayland-drm/wayland-drm.h3
3 files changed, 80 insertions, 56 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 47de978404d..a7ebf599974 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -993,40 +993,17 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
}
static _EGLImage *
-dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
- EGLClientBuffer buffer, const EGLint *attr_list)
+dri2_create_image_drm_name(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLint name,
+ const _EGLImageAttribs *attrs,
+ EGLint format,
+ EGLint pitch)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_image *dri2_img;
- EGLint format, name, pitch, err;
- _EGLImageAttribs attrs;
(void) ctx;
- name = (EGLint) (uintptr_t) buffer;
-
- err = _eglParseImageAttribList(&attrs, disp, attr_list);
- if (err != EGL_SUCCESS)
- return NULL;
-
- if (attrs.Width <= 0 || attrs.Height <= 0 ||
- attrs.DRMBufferStrideMESA <= 0) {
- _eglError(EGL_BAD_PARAMETER,
- "bad width, height or stride");
- return NULL;
- }
-
- switch (attrs.DRMBufferFormatMESA) {
- case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
- format = __DRI_IMAGE_FORMAT_ARGB8888;
- pitch = attrs.DRMBufferStrideMESA;
- break;
- default:
- _eglError(EGL_BAD_PARAMETER,
- "dri2_create_image_khr: unsupported pixmap depth");
- return NULL;
- }
-
dri2_img = malloc(sizeof *dri2_img);
if (!dri2_img) {
_eglError(EGL_BAD_ALLOC, "dri2_create_image_mesa_drm");
@@ -1040,8 +1017,8 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
dri2_img->dri_image =
dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
- attrs.Width,
- attrs.Height,
+ attrs->Width,
+ attrs->Height,
format,
name,
pitch,
@@ -1055,48 +1032,84 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return &dri2_img->base;
}
-#ifdef HAVE_WAYLAND_PLATFORM
static _EGLImage *
-dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx,
- __DRIimage *dri_image, EGLint width, EGLint height)
+dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer buffer, const EGLint *attr_list)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- EGLint attr_list[] = {
- EGL_WIDTH, 0,
- EGL_HEIGHT, 0,
- EGL_DRM_BUFFER_STRIDE_MESA, 0,
- EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
- EGL_NONE
- };
- EGLint name, stride;
-
- dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_NAME, &name);
- dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
+ EGLint format, name, pitch, err;
+ _EGLImageAttribs attrs;
+
+ name = (EGLint) (uintptr_t) buffer;
+
+ err = _eglParseImageAttribList(&attrs, disp, attr_list);
+ if (err != EGL_SUCCESS)
+ return NULL;
- attr_list[1] = width;
- attr_list[3] = height;
- attr_list[5] = stride / 4;
+ if (attrs.Width <= 0 || attrs.Height <= 0 ||
+ attrs.DRMBufferStrideMESA <= 0) {
+ _eglError(EGL_BAD_PARAMETER,
+ "bad width, height or stride");
+ return NULL;
+ }
- return dri2_create_image_mesa_drm_buffer(disp, ctx,
- (EGLClientBuffer)(intptr_t) name,
- attr_list);
+ switch (attrs.DRMBufferFormatMESA) {
+ case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ pitch = attrs.DRMBufferStrideMESA;
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER,
+ "dri2_create_image_khr: unsupported pixmap depth");
+ return NULL;
+ }
+
+ return dri2_create_image_drm_name (disp, ctx, name, &attrs, format, pitch);
}
+#ifdef HAVE_WAYLAND_PLATFORM
static _EGLImage *
dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer _buffer,
const EGLint *attr_list)
{
struct wl_buffer *buffer = (struct wl_buffer *) _buffer;
- (void) attr_list;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ __DRIimage *dri_image;
+ _EGLImageAttribs attrs;
+ EGLint format, name, stride, pitch, err;
if (!wayland_buffer_is_drm(buffer))
return NULL;
- return dri2_reference_drm_image(disp, ctx,
- wayland_drm_buffer_get_buffer(buffer),
- buffer->width,
- buffer->height);
+ dri_image = wayland_drm_buffer_get_buffer(buffer);
+
+ dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_NAME, &name);
+ dri2_dpy->image->queryImage(dri_image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
+
+ err = _eglParseImageAttribList(&attrs, disp, attr_list);
+ if (err != EGL_SUCCESS)
+ return NULL;
+
+ attrs.Width = buffer->width;
+ attrs.Height = buffer->height;
+
+ switch (wayland_drm_buffer_get_format(buffer)) {
+ case WL_DRM_FORMAT_ARGB32:
+ case WL_DRM_FORMAT_PREMULTIPLIED_ARGB32:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ case WL_DRM_FORMAT_XRGB32:
+ _eglError(EGL_BAD_PARAMETER,
+ "dri2_create_image_khr: unsupported wl_buffer format");
+ format = __DRI_IMAGE_FORMAT_XRGB8888;
+ break;
+ default:
+ return NULL;
+ }
+
+ pitch = stride / 4;
+
+ return dri2_create_image_drm_name(disp, ctx, name, &attrs, format, pitch);
}
#endif
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c
index 82ca6aa9017..43f91691046 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -205,6 +205,14 @@ wayland_buffer_is_drm(struct wl_buffer *buffer)
(void (**)(void)) &drm_buffer_interface;
}
+uint32_t
+wayland_drm_buffer_get_format(struct wl_buffer *buffer_base)
+{
+ struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) buffer_base;
+
+ return buffer->format;
+}
+
void *
wayland_drm_buffer_get_buffer(struct wl_buffer *buffer_base)
{
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h
index c9a90cad1ba..bec50a5539f 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.h
+++ b/src/egl/wayland/wayland-drm/wayland-drm.h
@@ -29,6 +29,9 @@ wayland_drm_uninit(struct wl_drm *drm);
int
wayland_buffer_is_drm(struct wl_buffer *buffer);
+uint32_t
+wayland_drm_buffer_get_format(struct wl_buffer *buffer_base);
+
void *
wayland_drm_buffer_get_buffer(struct wl_buffer *buffer);