OSDN Git Service

android: Add new classic EGL driver for Android.
authorChia-I Wu <olv@lunarg.com>
Mon, 11 Oct 2010 09:58:10 +0000 (17:58 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 10 Dec 2010 01:01:35 +0000 (20:01 -0500)
src/egl/drivers/android/droid.c [new file with mode: 0644]
src/egl/drivers/android/droid.h [new file with mode: 0644]
src/egl/drivers/android/droid_core.c [new file with mode: 0644]
src/egl/drivers/android/droid_image.c [new file with mode: 0644]
src/egl/drivers/android/egl_android.c [new file with mode: 0644]

diff --git a/src/egl/drivers/android/droid.c b/src/egl/drivers/android/droid.c
new file mode 100644 (file)
index 0000000..60c100b
--- /dev/null
@@ -0,0 +1,649 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#define LOG_TAG "MESA-EGL"
+
+#include <cutils/log.h>
+
+#include "glapi/glapi.h"
+#include "droid.h"
+
+static const __DRIuseInvalidateExtension use_invalidate = {
+   { __DRI_USE_INVALIDATE, 1 }
+};
+
+static __DRIimage *
+droid_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
+{
+   _EGLDisplay *disp = data;
+   struct droid_egl_image *dimg;
+   _EGLImage *img;
+
+   (void) screen;
+
+   img = _eglLookupImage(image, disp);
+   if (img == NULL) {
+      _eglError(EGL_BAD_PARAMETER, "droid_lookup_egl_image");
+      return NULL;
+   }
+
+   dimg = droid_egl_image(image);
+
+   return dimg->dri_image;
+}
+
+static const __DRIimageLookupExtension image_lookup_extension = {
+   { __DRI_IMAGE_LOOKUP, 1 },
+   droid_lookup_egl_image
+};
+
+static int
+get_format_bpp(int native)
+{
+   int bpp;
+
+   /* see libpixelflinger/format.cpp */
+   switch (native) {
+   case GGL_PIXEL_FORMAT_RGBA_8888:
+   case GGL_PIXEL_FORMAT_RGBX_8888:
+   case GGL_PIXEL_FORMAT_BGRA_8888:
+      bpp = 4;
+      break;
+   case GGL_PIXEL_FORMAT_RGB_888:
+      bpp = 3;
+      break;
+   case GGL_PIXEL_FORMAT_RGB_565:
+   case GGL_PIXEL_FORMAT_RGBA_5551:
+   case GGL_PIXEL_FORMAT_RGBA_4444:
+   case GGL_PIXEL_FORMAT_LA_88:
+      bpp = 2;
+      break;
+   case GGL_PIXEL_FORMAT_RGB_332:
+   case GGL_PIXEL_FORMAT_A_8:
+   case GGL_PIXEL_FORMAT_L_8:
+      bpp = 1;
+      break;
+   default:
+      bpp = 0;
+      break;
+   }
+
+   return bpp;
+}
+
+#include <gralloc_gem.h>
+int
+get_native_buffer_name(struct android_native_buffer_t *buf)
+{
+   struct drm_bo_t *bo;
+
+   bo = drm_gem_get(buf->handle);
+
+   return (bo) ? bo->name : 0;
+}
+
+EGLBoolean
+droid_dequeue_buffer(struct droid_egl_surface *dsurf)
+{
+   __DRIbuffer *buf = &dsurf->dri_buffer;
+
+   if (dsurf->window->dequeueBuffer(dsurf->window, &dsurf->buffer))
+      return EGL_FALSE;
+
+   dsurf->buffer->common.incRef(&dsurf->buffer->common);
+   dsurf->window->lockBuffer(dsurf->window, dsurf->buffer);
+
+   buf->attachment = __DRI_BUFFER_FAKE_FRONT_LEFT;
+   buf->name = get_native_buffer_name(dsurf->buffer);
+   buf->cpp = get_format_bpp(dsurf->buffer->format);
+   buf->pitch = dsurf->buffer->stride * buf->cpp;
+   buf->flags = 0;
+
+   return EGL_TRUE;
+}
+
+EGLBoolean
+droid_enqueue_buffer(struct droid_egl_surface *dsurf)
+{
+   dsurf->window->queueBuffer(dsurf->window, dsurf->buffer);
+
+   dsurf->buffer->common.decRef(&dsurf->buffer->common);
+   dsurf->buffer = NULL;
+
+   return EGL_TRUE;
+}
+
+static void
+droid_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
+{
+}
+
+static __DRIbuffer *
+droid_get_buffers_with_format(__DRIdrawable * driDrawable,
+                            int *width, int *height,
+                            unsigned int *attachments, int count,
+                            int *out_count, void *loaderPrivate)
+{
+   struct droid_egl_surface *dsurf = loaderPrivate;
+   struct droid_egl_display *ddpy =
+      droid_egl_display(dsurf->base.Resource.Display);
+
+   if (!dsurf->buffer) {
+      if (!droid_dequeue_buffer(dsurf))
+         return NULL;
+   }
+
+   if (width)
+      *width = dsurf->buffer->width;
+   if (height)
+      *height = dsurf->buffer->height;
+
+   *out_count = 1;
+
+   return &dsurf->dri_buffer;
+}
+
+static const EGLint droid_to_egl_attribute_map[] = {
+   0,
+   EGL_BUFFER_SIZE,            /* __DRI_ATTRIB_BUFFER_SIZE */
+   EGL_LEVEL,                  /* __DRI_ATTRIB_LEVEL */
+   EGL_RED_SIZE,               /* __DRI_ATTRIB_RED_SIZE */
+   EGL_GREEN_SIZE,             /* __DRI_ATTRIB_GREEN_SIZE */
+   EGL_BLUE_SIZE,              /* __DRI_ATTRIB_BLUE_SIZE */
+   EGL_LUMINANCE_SIZE,         /* __DRI_ATTRIB_LUMINANCE_SIZE */
+   EGL_ALPHA_SIZE,             /* __DRI_ATTRIB_ALPHA_SIZE */
+   0,                          /* __DRI_ATTRIB_ALPHA_MASK_SIZE */
+   EGL_DEPTH_SIZE,             /* __DRI_ATTRIB_DEPTH_SIZE */
+   EGL_STENCIL_SIZE,           /* __DRI_ATTRIB_STENCIL_SIZE */
+   0,                          /* __DRI_ATTRIB_ACCUM_RED_SIZE */
+   0,                          /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */
+   0,                          /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */
+   0,                          /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */
+   EGL_SAMPLE_BUFFERS,         /* __DRI_ATTRIB_SAMPLE_BUFFERS */
+   EGL_SAMPLES,                        /* __DRI_ATTRIB_SAMPLES */
+   0,                          /* __DRI_ATTRIB_RENDER_TYPE, */
+   0,                          /* __DRI_ATTRIB_CONFIG_CAVEAT */
+   0,                          /* __DRI_ATTRIB_CONFORMANT */
+   0,                          /* __DRI_ATTRIB_DOUBLE_BUFFER */
+   0,                          /* __DRI_ATTRIB_STEREO */
+   0,                          /* __DRI_ATTRIB_AUX_BUFFERS */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_TYPE */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */
+   0,                          /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */
+   0,                          /* __DRI_ATTRIB_FLOAT_MODE */
+   0,                          /* __DRI_ATTRIB_RED_MASK */
+   0,                          /* __DRI_ATTRIB_GREEN_MASK */
+   0,                          /* __DRI_ATTRIB_BLUE_MASK */
+   0,                          /* __DRI_ATTRIB_ALPHA_MASK */
+   EGL_MAX_PBUFFER_WIDTH,      /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */
+   EGL_MAX_PBUFFER_HEIGHT,     /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */
+   EGL_MAX_PBUFFER_PIXELS,     /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */
+   0,                          /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */
+   0,                          /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */
+   0,                          /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */
+   0,                          /* __DRI_ATTRIB_SWAP_METHOD */
+   EGL_MAX_SWAP_INTERVAL,      /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */
+   EGL_MIN_SWAP_INTERVAL,      /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */
+   0,                          /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */
+   0,                          /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
+   0,                          /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
+   0,                          /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
+   EGL_Y_INVERTED_NOK,         /* __DRI_ATTRIB_YINVERTED */
+};
+
+static struct droid_egl_config *
+droid_add_config(_EGLDisplay *dpy, const __DRIconfig *dri_config, int id,
+               int depth, EGLint surface_type, int rgba_masks[4])
+{
+   struct droid_egl_config *conf;
+   struct droid_egl_display *ddpy;
+   _EGLConfig base;
+   unsigned int attrib, value, double_buffer;
+   EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
+   int dri_masks[4] = { 0, 0, 0, 0 };
+   int i;
+
+   ddpy = dpy->DriverData;
+   _eglInitConfig(&base, dpy, id);
+   
+   i = 0;
+   double_buffer = 0;
+   bind_to_texture_rgb = 0;
+   bind_to_texture_rgba = 0;
+
+   while (ddpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
+      switch (attrib) {
+      case __DRI_ATTRIB_RENDER_TYPE:
+        if (value & __DRI_ATTRIB_RGBA_BIT)
+           value = EGL_RGB_BUFFER;
+        else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
+           value = EGL_LUMINANCE_BUFFER;
+        else
+           assert(0);
+        _eglSetConfigKey(&base, EGL_COLOR_BUFFER_TYPE, value);
+        break;  
+
+      case __DRI_ATTRIB_CONFIG_CAVEAT:
+         if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+            value = EGL_NON_CONFORMANT_CONFIG;
+         else if (value & __DRI_ATTRIB_SLOW_BIT)
+            value = EGL_SLOW_CONFIG;
+        else
+           value = EGL_NONE;
+        _eglSetConfigKey(&base, EGL_CONFIG_CAVEAT, value);
+         break;
+
+      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
+        bind_to_texture_rgb = value;
+        break;
+
+      case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
+        bind_to_texture_rgba = value;
+        break;
+
+      case __DRI_ATTRIB_DOUBLE_BUFFER:
+        double_buffer = value;
+        break;
+
+      case __DRI_ATTRIB_RED_MASK:
+         dri_masks[0] = value;
+         break;
+
+      case __DRI_ATTRIB_GREEN_MASK:
+         dri_masks[1] = value;
+         break;
+
+      case __DRI_ATTRIB_BLUE_MASK:
+         dri_masks[2] = value;
+         break;
+
+      case __DRI_ATTRIB_ALPHA_MASK:
+         dri_masks[3] = value;
+         break;
+
+      default:
+        key = droid_to_egl_attribute_map[attrib];
+        if (key != 0)
+           _eglSetConfigKey(&base, key, value);
+        break;
+      }
+   }
+
+   /* In EGL, double buffer or not isn't a config attribute.  Pixmaps
+    * surfaces are always single buffered, pbuffer surfaces are always
+    * back buffers and windows can be either, selected by passing an
+    * attribute at window surface construction time.  To support this
+    * we ignore all double buffer configs and manipulate the buffer we
+    * return in the getBuffer callback to get the behaviour we want. */
+
+   if (double_buffer)
+      return NULL;
+
+   if (depth > 0 && depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE))
+      return NULL;
+
+   if (memcmp(dri_masks, rgba_masks, sizeof(rgba_masks)))
+      return NULL;
+
+   _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE);
+
+   _eglSetConfigKey(&base, EGL_SURFACE_TYPE, surface_type);
+   if (surface_type & (EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)) {
+      _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
+      if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0)
+        _eglSetConfigKey(&base,
+                         EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);
+   }
+
+   _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, dpy->ClientAPIsMask);
+   _eglSetConfigKey(&base, EGL_CONFORMANT, dpy->ClientAPIsMask);
+
+   if (!_eglValidateConfig(&base, EGL_FALSE)) {
+      _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
+      return NULL;
+   }
+
+   conf = calloc(1, sizeof(*conf));
+   if (conf != NULL) {
+      memcpy(&conf->base, &base, sizeof(base));
+      conf->dri_config = dri_config;
+      _eglLinkConfig(&conf->base);
+   }
+
+   return conf;
+}
+
+static EGLBoolean
+droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(dpy);
+   const struct {
+      int format;
+      int size;
+      int rgba_masks[4];
+   } visuals[] = {
+      { GGL_PIXEL_FORMAT_RGBA_8888, 32, { 0xff, 0xff00, 0xff0000, 0xff000000 } },
+      { GGL_PIXEL_FORMAT_RGBX_8888, 32, { 0xff, 0xff00, 0xff0000, 0x0 } },
+      { GGL_PIXEL_FORMAT_RGB_888,   24, { 0xff, 0xff00, 0xff0000, 0x0 } },
+      { GGL_PIXEL_FORMAT_RGB_565,   16, { 0xf800, 0x7e0, 0x1f, 0x0 } },
+      { GGL_PIXEL_FORMAT_BGRA_8888, 32, { 0xff0000, 0xff00, 0xff, 0xff000000 } },
+      { GGL_PIXEL_FORMAT_A_8,        8, { 0xf800, 0x7e0, 0x1f, 0x0 } },
+      { 0, 0, { 0, 0, 0, 0 } }
+   };
+   int count, i, j;
+
+   count = 0;
+   for (i = 0; visuals[i].format; i++) {
+      int format_count = 0;
+
+      for (j = 0; ddpy->dri_configs[j]; j++) {
+         struct droid_egl_config *dconf;
+
+         dconf = droid_add_config(dpy, ddpy->dri_configs[j], count + 1,
+               visuals[i].size, EGL_WINDOW_BIT, visuals[i].rgba_masks);
+         if (dconf) {
+            _eglSetConfigKey(&dconf->base,
+                  EGL_NATIVE_VISUAL_TYPE, visuals[i].format);
+            count++;
+            format_count++;
+         }
+      }
+
+      if (!format_count) {
+         _eglLog(_EGL_DEBUG, "No DRI config supports native format 0x%x",
+               visuals[i].format);
+      }
+   }
+
+   return (count != 0);
+}
+
+struct droid_extension_match {
+   const char *name;
+   int version;
+   int offset;
+};
+
+static struct droid_extension_match droid_driver_extensions[] = {
+   { __DRI_CORE, 1, offsetof(struct droid_egl_display, core) },
+   { __DRI_DRI2, 1, offsetof(struct droid_egl_display, dri2) },
+   { NULL, 0, 0 }
+};
+
+static struct droid_extension_match droid_core_extensions[] = {
+   { __DRI2_FLUSH, 1, offsetof(struct droid_egl_display, flush) },
+   { __DRI_IMAGE, 1, offsetof(struct droid_egl_display, image) },
+   { NULL, 0, 0 }
+};
+
+extern const __DRIextension *__driDriverExtensions[];
+
+static EGLBoolean
+droid_bind_extensions(struct droid_egl_display *ddpy,
+                    struct droid_extension_match *matches,
+                    const __DRIextension **extensions)
+{
+   int i, j, ret = EGL_TRUE;
+   void *field;
+
+   for (i = 0; extensions[i]; i++) {
+      _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name);
+      for (j = 0; matches[j].name; j++) {
+        if (strcmp(extensions[i]->name, matches[j].name) == 0 &&
+            extensions[i]->version >= matches[j].version) {
+           field = ((char *) ddpy + matches[j].offset);
+           *(const __DRIextension **) field = extensions[i];
+           _eglLog(_EGL_INFO, "DRI2: found extension %s version %d",
+                   extensions[i]->name, extensions[i]->version);
+        }
+      }
+   }
+   
+   for (j = 0; matches[j].name; j++) {
+      field = ((char *) ddpy + matches[j].offset);
+      if (*(const __DRIextension **) field == NULL) {
+        _eglLog(_EGL_FATAL, "DRI2: did not find extension %s version %d",
+                matches[j].name, matches[j].version);
+        ret = EGL_FALSE;
+      }
+   }
+
+   return ret;
+}
+
+static EGLBoolean
+droid_create_screen(_EGLDisplay *dpy)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(dpy);
+   const __DRIextension **extensions;
+   unsigned int api_mask;
+
+   ddpy->dri_screen =
+      ddpy->dri2->createNewScreen(0, ddpy->fd, ddpy->extensions,
+                                     &ddpy->dri_configs, dpy);
+   if (ddpy->dri_screen == NULL) {
+      _eglLog(_EGL_WARNING, "failed to create dri screen");
+      return EGL_FALSE;
+   }
+
+   extensions = ddpy->core->getExtensions(ddpy->dri_screen);
+   if (!droid_bind_extensions(ddpy, droid_core_extensions, extensions)) {
+      ddpy->core->destroyScreen(ddpy->dri_screen);
+      return EGL_FALSE;
+   }
+
+   if (ddpy->dri2->base.version >= 2)
+      api_mask = ddpy->dri2->getAPIMask(ddpy->dri_screen);
+   else
+      api_mask = __DRI_API_OPENGL;
+
+   dpy->ClientAPIsMask = 0;
+   if (api_mask & (1 <<__DRI_API_OPENGL))
+      dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
+   if (api_mask & (1 <<__DRI_API_GLES))
+      dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
+   if (api_mask & (1 << __DRI_API_GLES2))
+      dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
+
+   if (ddpy->dri2->base.version >= 2) {
+      dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
+      dpy->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
+      dpy->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
+   }
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_load_driver(_EGLDisplay *disp)
+{
+   struct droid_egl_display *ddpy = disp->DriverData;
+   const __DRIextension **extensions;
+
+   extensions = __driDriverExtensions;
+
+   if (!droid_bind_extensions(ddpy, droid_driver_extensions, extensions))
+      return EGL_FALSE;
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy,
+                       EGLint *major, EGLint *minor)
+{
+   struct droid_egl_display *ddpy;
+   int fd = -1, err, i;
+   const hw_module_t *mod;
+
+   err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+   if (!err) {
+      const gralloc_module_t *gr = (gralloc_module_t *) mod;
+
+      err = -EINVAL;
+      if (gr->perform)
+         err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
+   }
+   if (err || fd < 0) {
+      _eglLog(_EGL_WARNING, "fail to get drm fd");
+      return EGL_FALSE;
+   }
+
+   ddpy = calloc(1, sizeof(*ddpy));
+   if (!ddpy)
+      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+   dpy->DriverData = (void *) ddpy;
+
+   ddpy->fd = fd;
+   if (!droid_load_driver(dpy))
+      return EGL_FALSE;
+
+   ddpy->loader_extension.base.name = __DRI_DRI2_LOADER;
+   ddpy->loader_extension.base.version = 3;
+   ddpy->loader_extension.getBuffers = NULL;
+   ddpy->loader_extension.flushFrontBuffer = droid_flush_front_buffer;
+   ddpy->loader_extension.getBuffersWithFormat =
+      droid_get_buffers_with_format;
+
+   ddpy->extensions[0] = &ddpy->loader_extension.base;
+   ddpy->extensions[1] = &image_lookup_extension.base;
+   ddpy->extensions[2] = &use_invalidate.base;
+   ddpy->extensions[3] = NULL;
+
+   if (!droid_create_screen(dpy)) {
+      free(ddpy);
+      return EGL_FALSE;
+   }
+
+   if (!droid_add_configs_for_visuals(drv, dpy)) {
+      ddpy->core->destroyScreen(ddpy->dri_screen);
+      free(ddpy);
+   }
+
+   dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
+   dpy->Extensions.KHR_image_base = EGL_TRUE;
+
+   /* we're supporting EGL 1.4 */
+   *major = 1;
+   *minor = 4;
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(dpy);
+
+   _eglReleaseDisplayResources(drv, dpy);
+   _eglCleanupDisplay(dpy);
+
+   ddpy->core->destroyScreen(ddpy->dri_screen);
+   free(ddpy);
+   dpy->DriverData = NULL;
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
+                EGLint *major, EGLint *minor)
+{
+   switch (dpy->Platform) {
+   case _EGL_PLATFORM_ANDROID:
+      return droid_initialize_android(drv, dpy, major, minor);
+   default:
+      return EGL_FALSE;
+   }
+}
+
+static _EGLProc
+droid_get_proc_address(_EGLDriver *drv, const char *procname)
+{
+   return (_EGLProc) _glapi_get_proc_address(procname);
+}
+
+
+static void
+droid_unload(_EGLDriver *drv)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+
+   free(ddrv);
+}
+
+static void
+droid_log(EGLint level, const char *msg)
+{
+   switch (level) {
+   case _EGL_DEBUG:
+      LOGD(msg);
+      break;
+   case _EGL_INFO:
+      LOGI(msg);
+      break;
+   case _EGL_WARNING:
+      LOGW(msg);
+      break;
+   case _EGL_FATAL:
+      LOG_FATAL(msg);
+      break;
+   default:
+      break;
+   }
+}
+
+_EGLDriver *
+droid_create_driver(void)
+{
+   struct droid_egl_driver *ddrv;
+
+   ddrv = calloc(1, sizeof(*ddrv));
+   if (!ddrv)
+      return NULL;
+
+   _eglSetLogProc(droid_log);
+
+   ddrv->base.Name = "Droid";
+   ddrv->base.Unload = droid_unload;
+
+   _eglInitDriverFallbacks(&ddrv->base);
+   ddrv->base.API.Initialize = droid_initialize;
+   ddrv->base.API.Terminate = droid_terminate;
+   ddrv->base.API.GetProcAddress = droid_get_proc_address;
+
+   ddrv->glFlush =
+      (void (*)(void)) droid_get_proc_address(&ddrv->base, "glFlush");
+   ddrv->glFinish =
+      (void (*)(void)) droid_get_proc_address(&ddrv->base, "glFinish");
+
+   return &ddrv->base;
+}
diff --git a/src/egl/drivers/android/droid.h b/src/egl/drivers/android/droid.h
new file mode 100644 (file)
index 0000000..20e32a6
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#ifndef  _DROID_H_
+#define  _DROID_H_
+
+#include <errno.h>
+
+#include <ui/egl/android_natives.h>
+#include <ui/android_native_buffer.h>
+#include <pixelflinger/format.h>
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+
+#include "egldriver.h"
+#include "egldisplay.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+#include "eglconfig.h"
+#include "eglimage.h"
+#include "eglcurrent.h"
+#include "egllog.h"
+
+struct droid_egl_driver
+{
+   _EGLDriver base;
+
+   void (*glFlush)(void);
+   void (*glFinish)(void);
+};
+
+struct droid_egl_display
+{
+   int fd;
+
+   __DRIscreen *dri_screen;
+   const __DRIconfig **dri_configs;
+   __DRIcoreExtension *core;
+   __DRIdri2Extension *dri2;
+   __DRI2flushExtension *flush;
+   __DRIimageExtension *image;
+
+   __DRIdri2LoaderExtension loader_extension;
+   const __DRIextension *extensions[8];
+};
+
+struct droid_egl_context
+{
+   _EGLContext base;
+
+   __DRIcontext *dri_context;
+};
+
+struct droid_egl_surface
+{
+   _EGLSurface base;
+
+   __DRIdrawable *dri_drawable;
+   __DRIbuffer dri_buffer;
+
+   android_native_window_t *window;
+   android_native_buffer_t *buffer;
+};
+
+struct droid_egl_config
+{
+   _EGLConfig base;
+
+   const __DRIconfig *dri_config;
+};
+
+struct droid_egl_image
+{
+   _EGLImage base;
+
+   __DRIimage *dri_image;
+};
+
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(droid_egl)
+_EGL_DRIVER_TYPECAST(droid_egl_image, _EGLImage, obj)
+
+_EGLDriver *
+droid_create_driver(void);
+
+void
+droid_init_core_functions(_EGLDriver *drv);
+
+void
+droid_init_image_functions(_EGLDriver *drv);
+
+EGLBoolean
+droid_dequeue_buffer(struct droid_egl_surface *dsurf);
+
+EGLBoolean
+droid_enqueue_buffer(struct droid_egl_surface *dsurf);
+
+int
+get_native_buffer_name(struct android_native_buffer_t *buf);
+
+#endif /* _DROID_H_ */
diff --git a/src/egl/drivers/android/droid_core.c b/src/egl/drivers/android/droid_core.c
new file mode 100644 (file)
index 0000000..82c21d4
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#include "droid.h"
+
+static _EGLContext *
+droid_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
+                   _EGLContext *share_list, const EGLint *attrib_list)
+{
+   struct droid_egl_context *dctx;
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_context *dctx_shared = droid_egl_context(share_list);
+   struct droid_egl_config *dconf = droid_egl_config(conf);
+   const __DRIconfig *dri_config;
+   int api;
+
+   (void) drv;
+
+   dctx = calloc(1, sizeof *dctx);
+   if (!dctx) {
+      _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+      return NULL;
+   }
+
+   if (!_eglInitContext(&dctx->base, disp, conf, attrib_list))
+      goto cleanup;
+
+   switch (dctx->base.ClientAPI) {
+   case EGL_OPENGL_ES_API:
+      switch (dctx->base.ClientVersion) {
+      case 1:
+         api = __DRI_API_GLES;
+         break;
+      case 2:
+         api = __DRI_API_GLES2;
+         break;
+      default:
+        _eglError(EGL_BAD_PARAMETER, "eglCreateContext");
+        return NULL;
+      }
+      break;
+   case EGL_OPENGL_API:
+      api = __DRI_API_OPENGL;
+      break;
+   default:
+      _eglError(EGL_BAD_PARAMETER, "eglCreateContext");
+      return NULL;
+   }
+
+   if (conf != NULL)
+      dri_config = dconf->dri_config;
+   else
+      dri_config = NULL;
+
+   if (ddpy->dri2->base.version >= 2) {
+      dctx->dri_context =
+        ddpy->dri2->createNewContextForAPI(ddpy->dri_screen,
+                                               api,
+                                               dri_config,
+                                               dctx_shared ? 
+                                               dctx_shared->dri_context : NULL,
+                                               dctx);
+   } else if (api == __DRI_API_OPENGL) {
+      dctx->dri_context =
+        ddpy->dri2->createNewContext(ddpy->dri_screen,
+                                         dconf->dri_config,
+                                         dctx_shared ? 
+                                         dctx_shared->dri_context : NULL,
+                                         dctx);
+   } else {
+      /* fail */
+   }
+
+   if (!dctx->dri_context)
+      goto cleanup;
+
+   return &dctx->base;
+
+ cleanup:
+   free(dctx);
+   return NULL;
+}
+
+static _EGLSurface *
+droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
+                   _EGLConfig *conf, EGLNativeWindowType window,
+                   const EGLint *attrib_list)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_config *dconf = droid_egl_config(conf);
+   struct droid_egl_surface *dsurf;
+   int format, vis_type;
+
+   (void) drv;
+
+   if (!window || window->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+      _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
+      return NULL;
+   }
+   if (window->query(window, NATIVE_WINDOW_FORMAT, &format)) {
+      _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface");
+      return NULL;
+   }
+
+   vis_type = _eglGetConfigKey(&dconf->base, EGL_NATIVE_VISUAL_TYPE);
+   if (format != vis_type) {
+      _eglLog(_EGL_WARNING, "Native format mismatch: 0x%x != 0x%x",
+            format, vis_type);
+   }
+
+   dsurf = calloc(1, sizeof *dsurf);
+   if (!dsurf) {
+      _eglError(EGL_BAD_ALLOC, "droid_create_surface");
+      return NULL;
+   }
+
+   if (!_eglInitSurface(&dsurf->base, disp, type, conf, attrib_list))
+      goto cleanup_surf;
+
+   dsurf->dri_drawable =
+      (*ddpy->dri2->createNewDrawable) (ddpy->dri_screen,
+                                           dconf->dri_config, dsurf);
+   if (dsurf->dri_drawable == NULL) {
+      _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
+      goto cleanup_pixmap;
+   }
+
+   window->common.incRef(&window->common);
+   window->query(window, NATIVE_WINDOW_WIDTH, &dsurf->base.Width);
+   window->query(window, NATIVE_WINDOW_HEIGHT, &dsurf->base.Height);
+
+   dsurf->window = window;
+
+   return &dsurf->base;
+
+ cleanup_dri_drawable:
+   ddpy->core->destroyDrawable(dsurf->dri_drawable);
+ cleanup_pixmap:
+ cleanup_surf:
+   free(dsurf);
+
+   return NULL;
+}
+
+static _EGLSurface *
+droid_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
+                          _EGLConfig *conf, EGLNativeWindowType window,
+                          const EGLint *attrib_list)
+{
+   return droid_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
+                             window, attrib_list);
+}
+
+static _EGLSurface *
+droid_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
+                          _EGLConfig *conf, EGLNativePixmapType pixmap,
+                          const EGLint *attrib_list)
+{
+   return NULL;
+}
+
+static _EGLSurface *
+droid_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
+                           _EGLConfig *conf, const EGLint *attrib_list)
+{
+   return NULL;
+}
+
+static EGLBoolean
+droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_surface *dsurf = droid_egl_surface(surf);
+
+   (void) drv;
+
+   if (!_eglPutSurface(surf))
+      return EGL_TRUE;
+
+   (*ddpy->core->destroyDrawable)(dsurf->dri_drawable);
+
+   droid_enqueue_buffer(dsurf);
+   dsurf->window->common.decRef(&dsurf->window->common);
+
+   free(surf);
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
+                 _EGLSurface *rsurf, _EGLContext *ctx)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_surface *droid_dsurf = droid_egl_surface(dsurf);
+   struct droid_egl_surface *droid_rsurf = droid_egl_surface(rsurf);
+   struct droid_egl_context *dctx = droid_egl_context(ctx);
+   _EGLContext *old_ctx;
+   _EGLSurface *old_dsurf, *old_rsurf;
+   __DRIdrawable *ddraw, *rdraw;
+   __DRIcontext *cctx;
+
+   /* make new bindings */
+   if (!_eglBindContext(ctx, dsurf, rsurf, &old_ctx, &old_dsurf, &old_rsurf))
+      return EGL_FALSE;
+
+   /* flush before context switch */
+   if (old_ctx && ddrv->glFlush)
+      ddrv->glFlush();
+
+   ddraw = (droid_dsurf) ? droid_dsurf->dri_drawable : NULL;
+   rdraw = (droid_rsurf) ? droid_rsurf->dri_drawable : NULL;
+   cctx = (dctx) ? dctx->dri_context : NULL;
+
+   if ((cctx == NULL && ddraw == NULL && rdraw == NULL) ||
+       ddpy->core->bindContext(cctx, ddraw, rdraw)) {
+      droid_destroy_surface(drv, disp, old_dsurf);
+      droid_destroy_surface(drv, disp, old_rsurf);
+      if (old_ctx) {
+         /* unbind the old context only when there is no new context bound */
+         if (!ctx) {
+            __DRIcontext *old_cctx = droid_egl_context(old_ctx)->dri_context;
+            ddpy->core->unbindContext(old_cctx);
+         }
+         /* no destroy? */
+         _eglPutContext(old_ctx);
+      }
+
+      return EGL_TRUE;
+   } else {
+      /* undo the previous _eglBindContext */
+      _eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf);
+      assert(&dctx->base == ctx &&
+             &droid_dsurf->base == dsurf &&
+             &droid_rsurf->base == rsurf);
+
+      _eglPutSurface(dsurf);
+      _eglPutSurface(rsurf);
+      _eglPutContext(ctx);
+
+      _eglPutSurface(old_dsurf);
+      _eglPutSurface(old_rsurf);
+      _eglPutContext(old_ctx);
+
+      return EGL_FALSE;
+   }
+}
+
+static EGLBoolean
+droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_surface *dsurf = droid_egl_surface(draw);
+   _EGLContext *ctx;
+
+   if (ddrv->glFlush) {
+      ctx = _eglGetCurrentContext();
+      if (ctx && ctx->DrawSurface == &dsurf->base)
+         ddrv->glFlush();
+   }
+
+   (*ddpy->flush->flush)(dsurf->dri_drawable);
+
+   if (dsurf->buffer)
+      droid_enqueue_buffer(dsurf);
+
+   (*ddpy->flush->invalidate)(dsurf->dri_drawable);
+
+   return EGL_TRUE;
+}
+
+static EGLBoolean
+droid_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_surface *dsurf = droid_egl_surface(ctx->DrawSurface);
+
+   if (ddrv->glFinish)
+      ddrv->glFinish();
+
+   if (dsurf)
+      (*ddpy->flush->flush)(dsurf->dri_drawable);
+
+   return EGL_TRUE;
+}
+
+void
+droid_init_core_functions(_EGLDriver *drv)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+
+   ddrv->base.API.CreateContext = droid_create_context;
+   ddrv->base.API.CreateWindowSurface = droid_create_window_surface;
+   ddrv->base.API.CreatePixmapSurface = droid_create_pixmap_surface;
+   ddrv->base.API.CreatePbufferSurface = droid_create_pbuffer_surface;
+   ddrv->base.API.DestroySurface = droid_destroy_surface;
+   ddrv->base.API.MakeCurrent = droid_make_current;
+   ddrv->base.API.SwapBuffers = droid_swap_buffers;
+   ddrv->base.API.WaitClient = droid_wait_client;
+}
diff --git a/src/egl/drivers/android/droid_image.c b/src/egl/drivers/android/droid_image.c
new file mode 100644 (file)
index 0000000..509335b
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#include "droid.h"
+
+static _EGLImage *
+droid_create_image_android_native_buffer(_EGLDisplay *disp,
+                                        EGLClientBuffer buffer)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct android_native_buffer_t *buf =
+      (struct android_native_buffer_t *) buffer;
+   struct droid_egl_image *dimg;
+   EGLint format, name;
+
+   if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
+       buf->common.version != sizeof(*buf)) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
+
+   name = get_native_buffer_name(buf);
+   if (!name) {
+      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+      return NULL;
+   }
+
+   switch (buf->format) {
+   case HAL_PIXEL_FORMAT_BGRA_8888:
+      format = __DRI_IMAGE_FORMAT_ARGB8888;
+      break;
+   case HAL_PIXEL_FORMAT_RGB_565:
+      format = __DRI_IMAGE_FORMAT_RGB565;
+      break;
+   case HAL_PIXEL_FORMAT_RGBA_8888:
+   case HAL_PIXEL_FORMAT_RGBX_8888:
+   case HAL_PIXEL_FORMAT_RGB_888:
+   case HAL_PIXEL_FORMAT_RGBA_5551:
+   case HAL_PIXEL_FORMAT_RGBA_4444:
+      /* unsupported */
+   default:
+      _eglLog(_EGL_WARNING, "unsupported native buffer format 0x%x", buf->format);
+      return NULL;
+      break;
+   }
+
+   dimg = calloc(1, sizeof(*dimg));
+   if (!dimg) {
+      _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+      return NULL;
+   }
+
+   if (!_eglInitImage(&dimg->base, disp)) {
+      free(dimg);
+      return NULL;
+   }
+
+   dimg->dri_image =
+      ddpy->image->createImageFromName(ddpy->dri_screen,
+                                          buf->width,
+                                          buf->height,
+                                          format,
+                                          name,
+                                          buf->stride,
+                                          dimg);
+   if (!dimg->dri_image) {
+      free(dimg);
+      _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+      return NULL;
+   }
+
+   return &dimg->base;
+}
+
+static _EGLImage *
+droid_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+                     _EGLContext *ctx, EGLenum target,
+                     EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   switch (target) {
+   case EGL_NATIVE_BUFFER_ANDROID:
+      return droid_create_image_android_native_buffer(disp, buffer);
+   default:
+      _eglError(EGL_BAD_PARAMETER, "droid_create_image_khr");
+      return EGL_NO_IMAGE_KHR;
+   }
+}
+
+static EGLBoolean
+droid_destroy_image_khr(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *image)
+{
+   struct droid_egl_display *ddpy = droid_egl_display(disp);
+   struct droid_egl_image *dimg = droid_egl_image(image);
+
+   ddpy->image->destroyImage(dimg->dri_image);
+   free(dimg);
+
+   return EGL_TRUE;
+}
+
+void
+droid_init_image_functions(_EGLDriver *drv)
+{
+   struct droid_egl_driver *ddrv = droid_egl_driver(drv);
+
+   ddrv->base.API.CreateImageKHR = droid_create_image_khr;
+   ddrv->base.API.DestroyImageKHR = droid_destroy_image_khr;
+}
diff --git a/src/egl/drivers/android/egl_android.c b/src/egl/drivers/android/egl_android.c
new file mode 100644 (file)
index 0000000..3f1cb36
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#include "droid.h"
+
+_EGLDriver *
+_eglMain(const char *args)
+{
+   _EGLDriver *drv;
+
+   drv = droid_create_driver();
+   if (drv) {
+      droid_init_core_functions(drv);
+      droid_init_image_functions(drv);
+   }
+
+   return drv;
+}