summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2009-09-18 17:13:20 +0800
committerChia-I Wu <olvaffe@gmail.com>2009-09-18 18:36:14 +0800
commit6059e6a8f25e15e934a268d1f022044736f8ba33 (patch)
tree2eb0a37925672d3ec8932efeafa75aee21011f09
parent3c718c0e95583c3c080bb0e7020b39066a265fa1 (diff)
egl_android: Add untested support for EGLImage.
-rw-r--r--src/egl/drivers/android/droid.h11
-rw-r--r--src/egl/drivers/android/droid_intel.c73
-rw-r--r--src/egl/drivers/android/droid_loader.c77
-rw-r--r--src/egl/drivers/android/egl_android.c103
4 files changed, 257 insertions, 7 deletions
diff --git a/src/egl/drivers/android/droid.h b/src/egl/drivers/android/droid.h
index bed5e8cd75..1793f6a78c 100644
--- a/src/egl/drivers/android/droid.h
+++ b/src/egl/drivers/android/droid.h
@@ -40,6 +40,7 @@
struct droid_loader;
struct droid_context;
struct droid_drawable;
+struct droid_image;
struct droid_surface;
struct droid_backend {
@@ -61,6 +62,9 @@ struct droid_backend {
struct droid_surface *(*create_window_surface)(struct droid_backend *backend,
_EGLSurface *surf,
NativeWindowType win);
+ struct droid_surface *(*create_image_surface)(struct droid_backend *backend,
+ NativePixmapType pix,
+ int *depth);
void (*destroy_surface)(struct droid_backend *backend, struct droid_surface *surf);
void (*swap_native_buffers)(struct droid_backend *backend,
struct droid_surface *surf);
@@ -75,6 +79,9 @@ struct droid_screen {
const __DRIconfig **dri_configs;
int num_dri_configs;
+
+#define DROID_MAX_IMAGE_DEPTH 32
+ const __DRIconfig *image_configs[DROID_MAX_IMAGE_DEPTH + 1];
};
struct droid_backend *
@@ -107,6 +114,10 @@ droid_screen_create_drawable(struct droid_screen *screen,
const __DRIconfig *conf,
struct droid_surface *surf);
+void *
+droid_screen_get_drawable_data(struct droid_screen *screen,
+ struct droid_drawable *drawable);
+
void
droid_screen_destroy_drawable(struct droid_screen *screen,
struct droid_drawable *drawable);
diff --git a/src/egl/drivers/android/droid_intel.c b/src/egl/drivers/android/droid_intel.c
index 2f1b26c53f..d9ff0d59d6 100644
--- a/src/egl/drivers/android/droid_intel.c
+++ b/src/egl/drivers/android/droid_intel.c
@@ -46,6 +46,7 @@
enum {
INTEL_SURFACE_TYPE_WINDOW,
+ INTEL_SURFACE_TYPE_IMAGE,
};
struct droid_backend_intel {
@@ -58,6 +59,7 @@ struct droid_surface_intel {
int type;
union {
NativeWindowType win;
+ NativePixmapType pix;
} native;
__DRIbuffer native_buffer;
unsigned int native_width, native_height;
@@ -219,11 +221,20 @@ intel_get_surface_buffers(struct droid_backend *backend,
}
else {
buffers[num].attachment = att;
- handles[num] = create_buffer(intel->fd,
- isurf->native_width,
- isurf->native_height,
- cpp,
- &buffers[num]);
+
+ if (isurf->type == INTEL_SURFACE_TYPE_IMAGE &&
+ att == __DRI_BUFFER_FRONT_LEFT) {
+ buffers[num] = isurf->native_buffer;
+ buffers[num].attachment = att;
+ handles[num] = 0;
+ } else {
+ buffers[num].attachment = att;
+ handles[num] = create_buffer(intel->fd,
+ isurf->native_width,
+ isurf->native_height,
+ cpp,
+ &buffers[num]);
+ }
}
num++;
}
@@ -258,6 +269,13 @@ update_native_buffer(struct droid_surface *surf)
width = isurf->native.win->width;
height = isurf->native.win->height;
break;
+ case INTEL_SURFACE_TYPE_IMAGE:
+ name = isurf->native.pix->reserved;
+ cpp = ui_bytes_per_pixel(isurf->native.pix->format);
+ pitch = isurf->native.pix->stride * cpp;
+ width = isurf->native.pix->width;
+ height = isurf->native.pix->height;
+ break;
default:
name = cpp = pitch = width = height = 0;
break;
@@ -316,6 +334,50 @@ intel_create_window_surface(struct droid_backend *backend,
return (struct droid_surface *) isurf;
}
+static struct droid_surface *
+intel_create_image_surface(struct droid_backend *backend,
+ NativePixmapType pix, int *depth)
+{
+ struct droid_surface_intel *isurf;
+ int cpp;
+
+ if (!pix) {
+ LOGE("invalid native pixmap");
+ _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage");
+ return NULL;
+ }
+
+ /* TODO lift this limitation */
+ if (!pix->reserved) {
+ LOGE("TODO support for non-gem based pixmap");
+ _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage");
+ return NULL;
+ }
+
+ cpp = ui_bytes_per_pixel(pix->format);
+ if (cpp * 8 > DROID_MAX_IMAGE_DEPTH) {
+ LOGE("pixmap of depth %d is not supported", cpp * 8);
+ _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCreateImage");
+ return NULL;
+ }
+
+ isurf = calloc(1, sizeof(*isurf));
+ if (!isurf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ return NULL;
+ }
+
+ isurf->type = INTEL_SURFACE_TYPE_IMAGE;
+ isurf->native.pix = pix;
+
+ update_native_buffer((struct droid_surface *) isurf);
+
+ if (depth)
+ *depth = cpp * 8;
+
+ return (struct droid_surface *) isurf;
+}
+
static void
intel_destroy_surface(struct droid_backend *backend, struct droid_surface *surf)
{
@@ -400,6 +462,7 @@ droid_backend_create_intel(const char *dev)
intel->base.get_surface_buffers = intel_get_surface_buffers;
intel->base.create_window_surface = intel_create_window_surface;
+ intel->base.create_image_surface = intel_create_image_surface;
intel->base.destroy_surface = intel_destroy_surface;
intel->base.swap_native_buffers = intel_swap_native_buffers;
diff --git a/src/egl/drivers/android/droid_loader.c b/src/egl/drivers/android/droid_loader.c
index 1d02b49322..67e8e9f2b1 100644
--- a/src/egl/drivers/android/droid_loader.c
+++ b/src/egl/drivers/android/droid_loader.c
@@ -33,6 +33,7 @@
#include <assert.h>
#include "droid.h"
+#include "EGL/internal/eglimage_dri.h"
#ifndef DROID_DRIVER_PATH
#define DROID_DRIVER_PATH "/system/lib"
@@ -57,6 +58,8 @@ struct droid_drawable {
struct droid_surface *surface;
__DRIdrawable *dri_drawable;
+ const __DRIconfig *dri_config;
+ __DRIEGLImage *dri_image;
};
static __DRIbuffer *
@@ -206,6 +209,48 @@ droid_backend_destroy(struct droid_backend *backend)
backend->destroy(backend);
}
+static void
+screen_find_image_configs(struct droid_screen *screen)
+{
+ struct droid_loader *loader = screen->loader;
+ int depth, i;
+
+ for (depth = 0; depth < DROID_MAX_IMAGE_DEPTH + 1; depth++) {
+ for (i = 0; i < screen->num_dri_configs; i++) {
+ const __DRIconfig *conf = screen->dri_configs[i];
+ _EGLConfig egl_conf;
+ EGLint rgba, val;
+
+ droid_screen_convert_config(screen, conf, &egl_conf);
+
+ val = GET_CONFIG_ATTRIB(&egl_conf, EGL_CONFIG_CAVEAT);
+ if (val == EGL_SLOW_CONFIG)
+ continue;
+
+ rgba = GET_CONFIG_ATTRIB(&egl_conf, EGL_RED_SIZE);
+ rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_GREEN_SIZE);
+ rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_BLUE_SIZE);
+ rgba += GET_CONFIG_ATTRIB(&egl_conf, EGL_ALPHA_SIZE);
+ if (depth != rgba)
+ continue;
+
+ if (depth == 32) {
+ val = GET_CONFIG_ATTRIB(&egl_conf, EGL_BIND_TO_TEXTURE_RGBA);
+ if (val) {
+ screen->image_configs[depth] = conf;
+ break;
+ }
+ }
+
+ val = GET_CONFIG_ATTRIB(&egl_conf, EGL_BIND_TO_TEXTURE_RGB);
+ if (val) {
+ screen->image_configs[depth] = conf;
+ break;
+ }
+ }
+ }
+}
+
struct droid_screen *
droid_screen_create(struct droid_backend *backend)
{
@@ -268,6 +313,8 @@ droid_screen_create(struct droid_backend *backend)
;
screen->num_dri_configs = i;
+ screen_find_image_configs(screen);
+
return screen;
fail:
@@ -400,6 +447,7 @@ droid_screen_create_drawable(struct droid_screen *screen,
/* needed in GetBuffers */
drawable->loader = loader;
drawable->surface = surf;
+ drawable->dri_config = conf;
drawable->dri_drawable =
loader->dri2->createNewDrawable(screen->dri_screen,
@@ -413,11 +461,40 @@ droid_screen_create_drawable(struct droid_screen *screen,
return drawable;
}
+void *
+droid_screen_get_drawable_data(struct droid_screen *screen,
+ struct droid_drawable *drawable)
+{
+ struct droid_loader *loader = screen->loader;
+ __DRIEGLImage *img = drawable->dri_image;
+
+ if (!img) {
+ unsigned int val;
+
+ img = calloc(1, sizeof(__DRIEGLImage));
+ if (!img)
+ return NULL;
+
+ img->magic = __DRI_EGL_IMAGE_MAGIC;
+ img->drawable = drawable->dri_drawable;
+ img->level = 0;
+ if (loader->core->getConfigAttrib(drawable->dri_config,
+ EGL_BIND_TO_TEXTURE_RGBA, &val))
+ img->texture_format_rgba = val;
+
+ drawable->dri_image = img;
+ }
+
+ return (void *) img;
+}
+
void
droid_screen_destroy_drawable(struct droid_screen *screen,
struct droid_drawable *drawable)
{
struct droid_loader *loader = screen->loader;
+ if (drawable->dri_image)
+ free(drawable->dri_image);
loader->core->destroyDrawable(drawable->dri_drawable);
free(drawable);
}
diff --git a/src/egl/drivers/android/egl_android.c b/src/egl/drivers/android/egl_android.c
index 10c0aea3ab..e9e0114683 100644
--- a/src/egl/drivers/android/egl_android.c
+++ b/src/egl/drivers/android/egl_android.c
@@ -32,8 +32,6 @@
#include "eglsurface.h"
#include "eglimage.h"
-#include "EGL/internal/eglimage_dri.h"
-
#include "droid.h"
#ifndef DROID_DEVICE_PATH
@@ -73,6 +71,12 @@ struct droid_egl_surface {
struct droid_surface *surface;
};
+struct droid_egl_image {
+ _EGLImage base;
+ struct droid_drawable *drawable;
+ struct droid_surface *surface;
+};
+
struct droid_egl_config {
_EGLConfig base;
const __DRIconfig *config;
@@ -102,6 +106,12 @@ lookup_surface(_EGLSurface *surface)
return (struct droid_egl_surface *) surface;
}
+static INLINE struct droid_egl_image *
+lookup_image(_EGLImage *image)
+{
+ return (struct droid_egl_image *) image;
+}
+
static INLINE struct droid_egl_config *
lookup_config(_EGLConfig *conf)
{
@@ -184,6 +194,14 @@ droid_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
droid_create_configs(dpy, droid_dpy, droid_dpy->screen->dri_configs,
droid_dpy->screen->num_dri_configs);
+#if EGL_KHR_image_base
+ if (droid_dpy->backend->create_image_surface) {
+ dpy->Extensions.KHR_image = EGL_TRUE;
+ dpy->Extensions.KHR_image_base = EGL_TRUE;
+ dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+ }
+#endif
+
droid_drv->default_display = droid_dpy;
}
@@ -380,6 +398,83 @@ droid_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
return EGL_TRUE;
}
+#if EGL_KHR_image_base
+
+static _EGLImage *
+droid_eglCreateImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
+ EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ struct droid_egl_display *droid_dpy = lookup_display(dpy);
+ struct droid_egl_image *droid_img;
+ const __DRIconfig *dri_conf;
+ int depth;
+
+ if (target != EGL_NATIVE_PIXMAP_KHR || ctx) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateImageKHR");
+ return NULL;
+ }
+
+ droid_img = calloc(1, sizeof(*droid_img));
+ if (!droid_img) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateImageKHR");
+ return NULL;
+ }
+
+ if (!_eglInitImage(drv, &droid_img->base, attr_list)) {
+ free(droid_img);
+ return NULL;
+ }
+
+ droid_img->surface =
+ droid_dpy->backend->create_image_surface(droid_dpy->backend,
+ (NativePixmapType) buffer,
+ &depth);
+ if (!droid_img->surface) {
+ free(droid_img);
+ return NULL;
+ }
+
+ dri_conf = droid_dpy->screen->image_configs[depth];
+ if (!dri_conf) {
+ droid_dpy->backend->destroy_surface(droid_dpy->backend,
+ droid_img->surface);
+ free(droid_img);
+ return NULL;
+ }
+
+ droid_img->drawable =
+ droid_screen_create_drawable(droid_dpy->screen, dri_conf,
+ droid_img->surface);
+
+ if (!droid_img->drawable) {
+ droid_dpy->backend->destroy_surface(droid_dpy->backend,
+ droid_img->surface);
+ free(droid_img);
+ return NULL;
+ }
+
+ droid_img->base.ClientData =
+ droid_screen_get_drawable_data(droid_dpy->screen, droid_img->drawable);
+
+ return &droid_img->base;
+}
+
+
+static EGLBoolean
+droid_eglDestroyImageKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
+{
+ struct droid_egl_display *droid_dpy = lookup_display(dpy);
+ struct droid_egl_image *droid_img = lookup_image(img);
+
+ droid_screen_destroy_drawable(droid_dpy->screen, droid_img->drawable);
+ droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_img->surface);
+ free(droid_img);
+
+ return EGL_TRUE;
+}
+
+#endif /* EGL_KHR_image_base */
+
static EGLBoolean
droid_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy)
{
@@ -446,6 +541,10 @@ _eglMain(const char *args)
droid_drv->base.API.CreateWindowSurface = droid_eglCreateWindowSurface;
droid_drv->base.API.DestroySurface = droid_eglDestroySurface;
droid_drv->base.API.SwapBuffers = droid_eglSwapBuffers;
+#if EGL_KHR_image_base
+ droid_drv->base.API.CreateImageKHR = droid_eglCreateImageKHR;
+ droid_drv->base.API.DestroyImageKHR = droid_eglDestroyImageKHR;
+#endif /* EGL_KHR_image_base */
droid_drv->base.API.WaitClient = droid_eglWaitClient;
droid_drv->base.API.WaitNative = droid_eglWaitNative;