diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/egl/Android.mk | 41 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid.h | 125 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_intel.c | 410 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_loader.c | 474 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_ui.cpp | 54 | ||||
| -rw-r--r-- | src/egl/drivers/android/droid_ui.h | 40 | ||||
| -rw-r--r-- | src/egl/drivers/android/egl_android.c | 462 | ||||
| -rw-r--r-- | src/egl/main/egldriver.c | 6 | ||||
| -rw-r--r-- | src/egl/main/egltypedefs.h | 56 | 
9 files changed, 1667 insertions, 1 deletions
| diff --git a/src/egl/Android.mk b/src/egl/Android.mk new file mode 100644 index 0000000000..2dd4df9c17 --- /dev/null +++ b/src/egl/Android.mk @@ -0,0 +1,41 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES :=			\ +	main/eglapi.c			\ +	main/eglclient.c		\ +	main/eglconfig.c		\ +	main/eglconfigutil.c		\ +	main/eglcontext.c		\ +	main/eglcurrent.c		\ +	main/egldisplay.c		\ +	main/egldriver.c		\ +	main/eglglobals.c		\ +	main/eglimage.c			\ +	main/egllog.c			\ +	main/eglmisc.c			\ +	main/eglmode.c			\ +	main/eglscreen.c		\ +	main/eglstring.c		\ +	main/eglsurface.c + +LOCAL_SRC_FILES +=			\ +	drivers/android/egl_android.c	\ +	drivers/android/droid_loader.c	\ +	drivers/android/droid_ui.cpp	\ +	drivers/android/droid_intel.c + +LOCAL_C_INCLUDES +=			\ +	$(LOCAL_PATH)/main		\ +	external/mesa/include		\ +	external/mesa/src/mesa		\ +	external/drm/shared-core + +LOCAL_CFLAGS +=	-DPTHREADS -D_EGL_PLATFORM_X=1 +LOCAL_SHARED_LIBRARIES := libdl libui libutils +LOCAL_STATIC_LIBRARIES := libes1api + +LOCAL_MODULE := libhgl + +include $(BUILD_SHARED_LIBRARY) diff --git a/src/egl/drivers/android/droid.h b/src/egl/drivers/android/droid.h new file mode 100644 index 0000000000..bed5e8cd75 --- /dev/null +++ b/src/egl/drivers/android/droid.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * This is based on the work of eagle, by + * Copyright © 2008, 2009 Kristian Høgsberg + * + * 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. + */ + +#ifndef _DROID_H_ +#define _DROID_H_ + +#include "GL/gl.h" +#include "GL/internal/dri_interface.h" + +#include "eglcurrent.h" +#include "egldisplay.h" +#include "eglcontext.h" +#include "eglsurface.h" +#include "eglconfig.h" + +/* opaque types */ +struct droid_loader; +struct droid_context; +struct droid_drawable; +struct droid_surface; + +struct droid_backend { +   /* these are usually used by a loader */ +   const char *driver_name; +   int (*initialize)(struct droid_backend *backend, int *fd, int *screen_number); +   void (*destroy)(struct droid_backend *backend); + +   __DRIbuffer *(*get_native_buffer)(struct droid_backend *backend, +                                     struct droid_surface *surf, +                                     int *width, int *height); +   __DRIbuffer *(*get_surface_buffers)(struct droid_backend *backend, +                                       struct droid_surface *surf, +                                       int *width, int *height, +                                       unsigned int *attachments, int count, +                                       int *out_count, int has_format); + +   /* public methods */ +   struct droid_surface *(*create_window_surface)(struct droid_backend *backend, +                                                  _EGLSurface *surf, +                                                  NativeWindowType win); +   void (*destroy_surface)(struct droid_backend *backend, struct droid_surface *surf); +   void (*swap_native_buffers)(struct droid_backend *backend, +                               struct droid_surface *surf); +}; + +struct droid_screen { +   struct droid_loader *loader; + +   __DRIscreen *dri_screen; +   __DRItexBufferExtension *tex_buffer; +   __DRIcopyBufferExtension *copy_buffer; + +   const __DRIconfig **dri_configs; +   int num_dri_configs; +}; + +struct droid_backend * +droid_backend_create_intel(const char *dev); + +void +droid_backend_destroy(struct droid_backend *backend); + +struct droid_screen * +droid_screen_create(struct droid_backend *backend); + +void +droid_screen_destroy(struct droid_screen *screen); + +void +droid_screen_convert_config(struct droid_screen *screen, +                            const __DRIconfig *conf, _EGLConfig *egl_conf); + +struct droid_context * +droid_screen_create_context(struct droid_screen *screen, +                            const __DRIconfig *conf, +                            struct droid_context *shared); + +void +droid_screen_destroy_context(struct droid_screen *screen, +                             struct droid_context *ctx); + +struct droid_drawable * +droid_screen_create_drawable(struct droid_screen *screen, +                             const __DRIconfig *conf, +                             struct droid_surface *surf); + +void +droid_screen_destroy_drawable(struct droid_screen *screen, +                              struct droid_drawable *drawable); + +int +droid_screen_bind_context(struct droid_screen *screen, +                          struct droid_drawable *draw, +                          struct droid_drawable *read, +                          struct droid_context *ctx); + +int +droid_screen_swap_buffers(struct droid_screen *screen, +                          struct droid_context *ctx, +                          struct droid_drawable *drawable); + +#endif /* _DROID_H_ */ diff --git a/src/egl/drivers/android/droid_intel.c b/src/egl/drivers/android/droid_intel.c new file mode 100644 index 0000000000..18fe3bfc95 --- /dev/null +++ b/src/egl/drivers/android/droid_intel.c @@ -0,0 +1,410 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * This is based on the work of eagle, by + * Copyright © 2008, 2009 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission.  The copyright holders make no representations + * about the suitability of this software for any purpose.  It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define LOG_TAG "DROID-INTEL" +#include <utils/Log.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <unistd.h> +#include <i915_drm.h> +#include <GL/gl.h> /* dri_interface.h uses some GL integer types... */ +#include <GL/internal/dri_interface.h> +#include <EGL/egl.h> + +#include "droid.h" +#include "droid_ui.h" + +#define INTEL_STRIDE_ALIGNMENT 64 + +enum { +   INTEL_SURFACE_TYPE_WINDOW, +}; + +struct droid_backend_intel { +   struct droid_backend base; +   int fd; +   int screen_number; +}; + +struct droid_surface_intel { +   int type; +   union { +      NativeWindowType win; +   } native; +   __DRIbuffer native_buffer; +   unsigned int native_width, native_height; +   int native_changed; + +   unsigned int attachments[20]; +   __DRIbuffer buffers[10]; +   uint32_t handles[10]; +   int num_buffers; +   int depth_idx; + +   _EGLSurface *surf; +}; + +static INLINE struct droid_backend_intel * +lookup_backend(struct droid_backend *backend) +{ +   return (struct droid_backend_intel *) backend; +} + +static INLINE struct droid_surface_intel * +lookup_surface(struct droid_surface *surface) +{ +   return (struct droid_surface_intel *) surface; +} + +static __DRIbuffer * +intel_get_native_buffer(struct droid_backend *backend, +                        struct droid_surface *surf, +                        int *width, int *height) +{ +   struct droid_surface_intel *isurf = lookup_surface(surf); + +   if (!isurf->native_buffer.name) +      return NULL; + +   if (width) +      *width = isurf->native_width; +   if (height) +      *height = isurf->native_height; + +   return &isurf->native_buffer; +} + +static inline uint32_t +align_to(uint32_t value, uint32_t align) +{ +   return (value + align - 1) & ~(align - 1); +} + +static int +create_buffer(int fd, GLint width, GLint height, GLint cpp, __DRIbuffer *buffer) +{ +   struct drm_i915_gem_create create; +   struct drm_gem_flink flink; +   uint32_t size; + +   buffer->pitch = align_to(width * cpp, INTEL_STRIDE_ALIGNMENT); +   size = buffer->pitch * height; +   create.size = size; +   if (ioctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create)) { +      LOGE("failed to create buffer"); +      return 0; +   } + +   flink.handle = create.handle; +   if (ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) { +      LOGE("failed to flink buffer"); +      return 0; +   } + +   buffer->name = flink.name; +   buffer->cpp = cpp; + +   return create.handle; +} + +static void +delete_buffers(struct droid_backend *backend, struct droid_surface *surf) +{ +   struct droid_backend_intel *intel = lookup_backend(backend); +   struct droid_surface_intel *isurf = lookup_surface(surf); +   int i; + +   for (i = 0; i < isurf->num_buffers; i++) { +      if (isurf->handles[i]) { +         struct drm_gem_close close; + +         close.handle = isurf->handles[i]; +         if (ioctl(intel->fd, DRM_IOCTL_GEM_CLOSE, &close) < 0) +            LOGE("failed to close bo %d", close.handle); +         isurf->handles[i] = 0; +      } +   } + +   isurf->num_buffers = 0; +} + +static __DRIbuffer * +intel_get_surface_buffers(struct droid_backend *backend, +                          struct droid_surface *surf, +                          int *width, int *height, +                          unsigned int *attachments, int count, +                          int *out_count, int has_format) +{ +   struct droid_backend_intel *intel = lookup_backend(backend); +   struct droid_surface_intel *isurf = lookup_surface(surf); +   unsigned int att_size; +   __DRIbuffer buffers[10]; +   uint32_t handles[10]; +   int num = 0; + +   if (count > 10) { +      LOGW("too many buffers requested"); +      count = 10; +   } + +   att_size = sizeof(attachments[0]) * count * ((has_format) ? 2 : 1); + +   if (isurf->native_changed) { +      delete_buffers(backend, surf); +      isurf->native_changed = 0; +   } + +   /* same buffers requested */ +   if (isurf->num_buffers == count && +       memcmp(isurf->attachments, attachments, att_size) == 0) { +      num = isurf->num_buffers; +      goto end; +   } +   memcpy(isurf->attachments, attachments, att_size); + +   while (count-- > 0) { +      unsigned int att = *attachments++; +      unsigned int format = (has_format) ? *attachments++ : 0; +      unsigned int cpp = (format) ? format / 8 : isurf->native_buffer.cpp; +      __DRIbuffer *buf = NULL; +      int reuse; + +      /* re-use buffer */ +      for (reuse = 0; reuse < isurf->num_buffers; reuse++) { +         if (isurf->buffers[reuse].attachment == att) { +            if (isurf->buffers[reuse].cpp == cpp && +                isurf->handles[reuse]) +               buf = &isurf->buffers[reuse]; +            break; +         } +      } + +      if (0) +         LOGD("%s buffer %d: att %d cpp %d", +               (buf) ? "reuse" : "create", num, att, cpp); + +      if (buf) { +         buffers[num] = isurf->buffers[reuse]; +         handles[num] = isurf->handles[reuse]; +         isurf->handles[reuse] = 0; +      } +      else { +         buffers[num].attachment = att; +         handles[num] = create_buffer(intel->fd, +                                          isurf->native_width, +                                          isurf->native_height, +                                          cpp, +                                          &buffers[num]); +      } +      num++; +   } + +   /* delete buffers that are not re-used */ +   delete_buffers(backend, surf); + +   memcpy(isurf->buffers, buffers, sizeof(buffers[0]) * num); +   memcpy(isurf->handles, handles, sizeof(handles[0]) * num); +   isurf->num_buffers = num; + +end: +   *out_count = num; +   *width = isurf->native_width; +   *height = isurf->native_height; + +   return isurf->buffers; +} + +static void +update_native_buffer(struct droid_surface *surf) +{ +   struct droid_surface_intel *isurf = lookup_surface(surf); +   unsigned int name, cpp, pitch, width, height; + +   switch (isurf->type) { +   case INTEL_SURFACE_TYPE_WINDOW: +      /* oem[0] always point to the buffer that a client is drawing to */ +      name = isurf->native.win->oem[0]; +      cpp = ui_bytes_per_pixel(isurf->native.win->format); +      pitch = isurf->native.win->stride * cpp; +      width = isurf->native.win->width; +      height = isurf->native.win->height; +      break; +   default: +      name = cpp = pitch = width = height = 0; +      break; +   } + +   isurf->native_buffer.attachment = __DRI_BUFFER_FRONT_LEFT; +   isurf->native_buffer.name = name; +   isurf->native_buffer.cpp = cpp; +   isurf->native_buffer.pitch = pitch; +   isurf->native_buffer.flags = 0; + +   isurf->native_width = width; +   isurf->native_height = height; + +   isurf->native_changed = 1; +} + +static struct droid_surface * +intel_create_window_surface(struct droid_backend *backend, +                            _EGLSurface *surf, +                            NativeWindowType win) +{ +   struct droid_surface_intel *isurf; +   uint32_t pitch, cpp; + +   if (!win) { +      LOGE("invalid native window"); +      _eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface"); +      return NULL; +   } + +   /* TODO lift this limitation */ +   if (!win->oem[0]) { +      LOGE("TODO support for non-gem based window"); +      _eglError(EGL_BAD_NATIVE_WINDOW, "eglCreateWindowSurface"); +      return NULL; +   } + +   cpp = ui_bytes_per_pixel(win->format); +   pitch = win->stride * cpp; + +   isurf = calloc(1, sizeof(*isurf)); +   if (!isurf) { +      _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); +      return NULL; +   } + +   isurf->type = INTEL_SURFACE_TYPE_WINDOW; +   isurf->native.win = win; + +   surf->Width = win->width; +   surf->Height = win->height; +   /* always back buffer */ +   surf->RenderBuffer = EGL_BACK_BUFFER; + +   isurf->surf = surf; + +   update_native_buffer((struct droid_surface *) isurf); + +   return (struct droid_surface *) isurf; +} + +static void +intel_destroy_surface(struct droid_backend *backend, struct droid_surface *surf) +{ +   struct droid_surface_intel *isurf = lookup_surface(surf); +   delete_buffers(backend, surf); +   free(isurf); +} + +static void +intel_swap_native_buffers(struct droid_backend *backend, +                          struct droid_surface *surf) +{ +   struct droid_surface_intel *isurf = lookup_surface(surf); + +   if (isurf->type == INTEL_SURFACE_TYPE_WINDOW) { +      uint32_t flags; + +      flags = isurf->native.win->swapBuffers(isurf->native.win); +      if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) { +         update_native_buffer(surf); +      } else { +         /* oem[0] is changed after buffer swap */ +         isurf->native_buffer.name = isurf->native.win->oem[0]; +      } +   } +} + +static int +intel_initialize(struct droid_backend *backend, int *fd, int *screen_number) +{ +   struct droid_backend_intel *intel = lookup_backend(backend); +   drm_auth_t auth; +   int err; + +   err = ioctl(intel->fd, DRM_IOCTL_GET_MAGIC, &auth); +   if (!err) +      err = ui_auth_gpu(auth.magic); + +   if (err) { +      LOGE("failed to authenticate"); +      return 0; +   } + +   if (fd) +      *fd = intel->fd; +   if (screen_number) +      *screen_number = intel->screen_number; + +   return 1; +} + +static void +intel_destroy(struct droid_backend *backend) +{ +   struct droid_backend_intel *intel = lookup_backend(backend); +   close(intel->fd); +   free(intel); +} + +struct droid_backend * +droid_backend_create_intel(const char *dev) +{ +   struct droid_backend_intel *intel; + +   intel = calloc(1, sizeof(*intel)); +   if (!intel) +      return NULL; + +   intel->fd = open(dev, O_RDWR); +   if (intel->fd < 0) { +      LOGE("failed to open %s", dev); +      free(intel); +      return NULL; +   } + +   intel->screen_number = 0; +   intel->base.driver_name = "i915"; +   intel->base.initialize = intel_initialize; +   intel->base.destroy = intel_destroy; + +   intel->base.get_native_buffer = intel_get_native_buffer; +   intel->base.get_surface_buffers = intel_get_surface_buffers; + +   intel->base.create_window_surface = intel_create_window_surface; +   intel->base.destroy_surface = intel_destroy_surface; +   intel->base.swap_native_buffers = intel_swap_native_buffers; + +   return &intel->base; +} diff --git a/src/egl/drivers/android/droid_loader.c b/src/egl/drivers/android/droid_loader.c new file mode 100644 index 0000000000..1d02b49322 --- /dev/null +++ b/src/egl/drivers/android/droid_loader.c @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * This is based on the work of eagle, by + * Copyright © 2008, 2009 Kristian Høgsberg + * + * 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. + */ + +#define LOG_TAG "DROID-LOADER" +#include <utils/Log.h> + +#include <string.h> +#include <errno.h> +#include <dlfcn.h> +#include <assert.h> + +#include "droid.h" + +#ifndef DROID_DRIVER_PATH +#define DROID_DRIVER_PATH "/system/lib" +#endif + +struct droid_loader { +   struct droid_backend *backend; + +   char *filename; +   void *handle; + +   __DRIcoreExtension *core; +   __DRIdri2Extension *dri2; +}; + +struct droid_context { +   __DRIcontext *dri_context; +}; + +struct droid_drawable { +   struct droid_loader *loader; +   struct droid_surface *surface; + +   __DRIdrawable *dri_drawable; +}; + +static __DRIbuffer * +loader_ext_get_buffers_with_format(__DRIdrawable *driDrawable, +                                   int *width, int *height, +                                   unsigned int *attachments, int count, +                                   int *out_count, void *loaderPrivate) +{ +   struct droid_drawable *drawable = (struct droid_drawable *) loaderPrivate; +   struct droid_loader *loader = drawable->loader; +   __DRIbuffer *buffers; + +   buffers = loader->backend->get_surface_buffers(loader->backend, +                                                  drawable->surface, +                                                  width, height, +                                                  attachments, count, +                                                  out_count, 1); + +   return buffers; +} + +static const __DRIdri2LoaderExtension loader_ext_dri2_loader = { +   { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION }, +   NULL, +   NULL, +   loader_ext_get_buffers_with_format, +}; + +static int +loader_ext_get_ust(int64_t *ust) +{ +   struct timeval tv; + +   if (ust == NULL) +      return -EFAULT; + +   if (gettimeofday(&tv, NULL) == 0) { +      ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; +      return 0; +   } else { +      return -errno; +   } +} + +static const __DRIsystemTimeExtension loader_ext_system_time = { +   { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, +   loader_ext_get_ust, +   NULL, +}; + +static const __DRIextension *loader_extensions[] = { +   &loader_ext_dri2_loader.base, +   &loader_ext_system_time.base, +   NULL +}; + +static struct droid_loader * +loader_create(struct droid_backend *backend) +{ +   struct droid_loader *loader; + +   loader = calloc(1, sizeof(*loader)); +   if (!loader) +      return NULL; + +   loader->backend = backend; + +   return loader; +} + +static void +loader_destroy(struct droid_loader *loader) +{ +   if (loader->filename) +      free(loader->filename); +   if (loader->handle) +      dlclose(loader->handle); +   free(loader); +} + +static int +loader_load(struct droid_loader *loader, const char *filename) +{ +   const __DRIextension **extensions; +   const char *path = NULL; +   int i; + +   LOGD("Loading DRI driver %s", filename); + +   loader->handle = dlopen(filename, RTLD_NOW | RTLD_LOCAL); +   if (loader->handle == NULL) { +      LOGE("dlopen: %s", dlerror()); +      return 0; +   } + +   extensions = dlsym(loader->handle, __DRI_DRIVER_EXTENSIONS); +   if (extensions == NULL) { +      LOGE("dlsym: %s", dlerror()); +      dlclose(loader->handle); +      loader->handle = NULL; +      return 0; +   } + +   for (i = 0; extensions[i]; i++) { +      if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && +          extensions[i]->version >= __DRI_CORE_VERSION) { +         loader->core = (__DRIcoreExtension *) extensions[i]; +      } + +      if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 && +          extensions[i]->version >= __DRI_DRI2_VERSION) { +         loader->dri2 = (__DRIdri2Extension *) extensions[i]; +      } +   } + +   if (loader->core == NULL || loader->dri2 == NULL) { +      LOGE("missing required DRI extensions"); +      dlclose(loader->handle); +      loader->handle = NULL; +      return 0; +   } + +   return 1; +} + +static int +loader_init(struct droid_loader *loader) +{ +   char filename[1024]; +   const char *path; + +   path = DROID_DRIVER_PATH; +   snprintf(filename, sizeof(filename), "%s/%s_dri.so", +            path, loader->backend->driver_name); + +   if (!loader_load(loader, filename)) +      return 0; + +   loader->filename = strdup(filename); + +   return 1; +} + +void +droid_backend_destroy(struct droid_backend *backend) +{ +   backend->destroy(backend); +} + +struct droid_screen * +droid_screen_create(struct droid_backend *backend) +{ +   struct droid_screen *screen = NULL; +   struct droid_loader *loader; +   const __DRIextension **extensions; +   int fd, screen_number; +   int i; + +   loader = loader_create(backend); +   if (!loader || !loader_init(loader)) { +      LOGE("failed to initialize loader"); +      goto fail; +   } + +   screen = calloc(1, sizeof(*screen)); +   if (!screen) { +      LOGE("failed to allocate new screen"); +      goto fail; +   } + +   if (!loader->backend->initialize(loader->backend, &fd, &screen_number)) { +      LOGE("failed to initialize backend"); +      goto fail; +   } + +   screen->loader = loader; +   screen->dri_screen = +      loader->dri2->createNewScreen(screen_number, fd, +                                    loader_extensions, +                                    &screen->dri_configs, NULL); +   if (!screen->dri_screen) { +      LOGE("failed to create DRI screen"); +      goto fail; +   } + +   extensions = loader->core->getExtensions(screen->dri_screen); + +   for (i = 0; extensions && extensions[i]; i++) { +      if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0 && +          extensions[i]->version >= __DRI_TEX_BUFFER_VERSION) +         screen->tex_buffer = (__DRItexBufferExtension *) extensions[i]; + +      if (strcmp(extensions[i]->name, __DRI_COPY_BUFFER) == 0 && +          extensions[i]->version >= __DRI_COPY_BUFFER_VERSION) +         screen->copy_buffer = (__DRIcopyBufferExtension *) extensions[i]; +   } + +   if (!screen->tex_buffer) { +      LOGE("DRI driver has no TexBuffer extension"); +      goto fail; +   } + +   if (!screen->tex_buffer) { +      LOGE("DRI driver has no CopyBuffer extension"); +      goto fail; +   } + +   for (i = 0; screen->dri_configs[i]; i++) +      ; +   screen->num_dri_configs = i; + +   return screen; + +fail: +   if (screen) +      droid_screen_destroy(screen); +   if (loader) +      loader_destroy(loader); + +   return NULL; +} + +void +droid_screen_destroy(struct droid_screen *screen) +{ +   struct droid_loader *loader = screen->loader; +   if (screen->dri_screen) +      loader->core->destroyScreen(screen->dri_screen); +   free(screen); +} + +static const struct { +   EGLenum egl_attrib; +   unsigned int dri_attrib; +} droid_attrib_map[] = { +   { EGL_BUFFER_SIZE,              __DRI_ATTRIB_BUFFER_SIZE }, +   { EGL_RED_SIZE,                 __DRI_ATTRIB_RED_SIZE }, +   { EGL_GREEN_SIZE,               __DRI_ATTRIB_GREEN_SIZE }, +   { EGL_BLUE_SIZE,                __DRI_ATTRIB_BLUE_SIZE }, +   { EGL_ALPHA_SIZE,               __DRI_ATTRIB_ALPHA_SIZE }, +   { EGL_BIND_TO_TEXTURE_RGB,      __DRI_ATTRIB_BIND_TO_TEXTURE_RGB }, +   { EGL_BIND_TO_TEXTURE_RGBA,     __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA }, +   { EGL_CONFIG_CAVEAT,            __DRI_ATTRIB_CONFIG_CAVEAT }, +   { EGL_DEPTH_SIZE,               __DRI_ATTRIB_DEPTH_SIZE }, +   { EGL_LEVEL,                    __DRI_ATTRIB_LEVEL }, +   { 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 }, +   { EGL_SAMPLE_BUFFERS,           __DRI_ATTRIB_SAMPLE_BUFFERS }, +   { EGL_SAMPLES,                  __DRI_ATTRIB_SAMPLES }, +   { EGL_STENCIL_SIZE,             __DRI_ATTRIB_STENCIL_SIZE }, +}; + +void +droid_screen_convert_config(struct droid_screen *screen, +                            const __DRIconfig *conf, _EGLConfig *egl_conf) +{ +   struct droid_loader *loader = screen->loader; +   const int num_attrs = +      sizeof(droid_attrib_map) / sizeof(droid_attrib_map[0]); +   int i; + +   for (i = 0; i < num_attrs; i++) { +      unsigned int dri_attrib = droid_attrib_map[i].dri_attrib; +      unsigned int dri_value; +      EGLenum egl_attrib = droid_attrib_map[i].egl_attrib; +      EGLint egl_value; + +      if (!loader->core->getConfigAttrib(conf, dri_attrib, &dri_value)) { +         LOGE("failed to get attribute %02d for %p", dri_attrib, conf); +         continue; +      } + +      switch (egl_attrib) { +      case EGL_CONFIG_CAVEAT: +         if (dri_value & __DRI_ATTRIB_SLOW_BIT) +            egl_value = EGL_SLOW_CONFIG; +         else if  (dri_value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) +            egl_value = EGL_NON_CONFORMANT_CONFIG; +         else +            egl_value = EGL_NONE; +         break; +      default: +         egl_value = (EGLint) dri_value; +         break; +      } +      SET_CONFIG_ATTRIB(egl_conf, egl_attrib, egl_value); +   } +} + +struct droid_context * +droid_screen_create_context(struct droid_screen *screen, +                            const __DRIconfig *conf, +                            struct droid_context *shared) +{ +   struct droid_loader *loader = screen->loader; +   struct droid_context *ctx; + +   ctx = calloc(1, sizeof(*ctx)); +   if (!ctx) { +      LOGE("failed to allocate context"); +      return NULL; +   } + +   ctx->dri_context = +      loader->dri2->createNewContext(screen->dri_screen, conf, +                                     (shared) ? shared->dri_context : NULL, +                                     NULL); +   if (!ctx->dri_context) { +      LOGE("failed to create DRI context"); +      free(ctx); +      return NULL; +   } + +   return ctx; +} + +void +droid_screen_destroy_context(struct droid_screen *screen, +                             struct droid_context *ctx) +{ +   struct droid_loader *loader = screen->loader; +   loader->core->destroyContext(ctx->dri_context); +   free(ctx); +} + +struct droid_drawable * +droid_screen_create_drawable(struct droid_screen *screen, +                             const __DRIconfig *conf, +                             struct droid_surface *surf) +{ +   struct droid_loader *loader = screen->loader; +   struct droid_drawable *drawable; + +   drawable = calloc(1, sizeof(*drawable)); +   if (!drawable) { +      LOGE("failed to allocate drawable"); +      return NULL; +   } + +   /* needed in GetBuffers */ +   drawable->loader = loader; +   drawable->surface = surf; + +   drawable->dri_drawable = +      loader->dri2->createNewDrawable(screen->dri_screen, +                                      conf, (void *) drawable); +   if (!drawable->dri_drawable) { +      LOGE("failed to create DRI drawable"); +      free(drawable); +      return NULL; +   } + +   return drawable; +} + +void +droid_screen_destroy_drawable(struct droid_screen *screen, +                              struct droid_drawable *drawable) +{ +   struct droid_loader *loader = screen->loader; +   loader->core->destroyDrawable(drawable->dri_drawable); +   free(drawable); +} + +int +droid_screen_bind_context(struct droid_screen *screen, +                          struct droid_drawable *draw, +                          struct droid_drawable *read, +                          struct droid_context *ctx) +{ +   struct droid_loader *loader = screen->loader; +   int ret = 0; + +   if (ctx) { +      if (draw && read) +         ret = loader->core->bindContext(ctx->dri_context, +                                         draw->dri_drawable, +                                         read->dri_drawable); +      else if (!draw && !read) +         ret = loader->core->unbindContext(ctx->dri_context); +   } + +   if (!ret) +      LOGE("failed to bind context %p", ctx); + +   return ret; +} + +int +droid_screen_swap_buffers(struct droid_screen *screen, +                          struct droid_context *ctx, +                          struct droid_drawable *drawable) +{ +   struct droid_loader *loader = screen->loader; +   __DRIbuffer *native; +   int width, height; +   int err = 0; + +   native = loader->backend->get_native_buffer(loader->backend, +                                               drawable->surface, +                                               &width, &height); + +   /* copy from front buffer to native buffer */ +   if (native) +      err = screen->copy_buffer->copyBuffer(ctx->dri_context, native, 0, 0, +                                            drawable->dri_drawable, +                                            __DRI_BUFFER_FRONT_LEFT, 0, 0, +                                            width, height); + +   if (!err) +      loader->backend->swap_native_buffers(loader->backend, drawable->surface); + +   return (!err); +} diff --git a/src/egl/drivers/android/droid_ui.cpp b/src/egl/drivers/android/droid_ui.cpp new file mode 100644 index 0000000000..6ceff1b5fb --- /dev/null +++ b/src/egl/drivers/android/droid_ui.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * 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. + */ + +#include <ui/PixelFormat.h> +#include <ui/ISurfaceComposer.h> + +#include "droid_ui.h" + +using namespace android; + +namespace android { +   const sp<ISurfaceComposer>& _get_surface_manager(); +}; + +int +ui_auth_gpu(drm_magic_t magic) +{ +   /* +    * surface flinger itself or root; we might want something like +    * getSurfaceFlinger() from libEGL +    */ +   if (getuid() == 1000 || getuid() == 0) +      return 0; + +   sp<ISurfaceComposer> sm(_get_surface_manager()); +   if (sm == NULL) +      return -ENODEV; +   return sm->authGPU(magic); +} + +int ui_bytes_per_pixel(int format) +{ +   return bytesPerPixel(format); +} diff --git a/src/egl/drivers/android/droid_ui.h b/src/egl/drivers/android/droid_ui.h new file mode 100644 index 0000000000..3153ec849f --- /dev/null +++ b/src/egl/drivers/android/droid_ui.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * 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. + */ + +#ifndef _DROID_UI_H +#define _DROID_UI_H + +#ifdef __cplusplus +extern "C" { +#endif /*__cplusplus */ + +#include <drm.h> + +int ui_auth_gpu(drm_magic_t magic); +int ui_bytes_per_pixel(int format); + +#ifdef __cplusplus +} +#endif /*__cplusplus */ + +#endif /* _DROID_UI_H */ diff --git a/src/egl/drivers/android/egl_android.c b/src/egl/drivers/android/egl_android.c new file mode 100644 index 0000000000..10c0aea3ab --- /dev/null +++ b/src/egl/drivers/android/egl_android.c @@ -0,0 +1,462 @@ +/* + * Copyright (C) 2009 Chia-I Wu <olvaffe@gmail.com> + * + * 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. + */ + +#include "glapi/glapi.h" + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "egllog.h" +#include "eglsurface.h" +#include "eglimage.h" + +#include "EGL/internal/eglimage_dri.h" + +#include "droid.h" + +#ifndef DROID_DEVICE_PATH +#define DROID_DEVICE_PATH "/dev/dri/card0" +#endif + +struct droid_egl_driver +{ +   _EGLDriver base; + +   /* EGL_DEFAULT_DISPLAY */ +   struct droid_egl_display *default_display; +   void (*flush_current)(void); +   void (*finish_current)(void); +}; + +struct droid_egl_display +{ +   EGLint refcnt; + +   EGLint apis; +   EGLint major; +   EGLint minor; + +   struct droid_backend *backend; +   struct droid_screen *screen; +}; + +struct droid_egl_context { +   _EGLContext base; +   struct droid_context *context; +}; + +struct droid_egl_surface { +   _EGLSurface base; +   struct droid_drawable *drawable; +   struct droid_surface *surface; +}; + +struct droid_egl_config { +   _EGLConfig base; +   const __DRIconfig *config; +}; + +static INLINE struct droid_egl_driver * +lookup_driver(_EGLDriver *drv) +{ +   return (struct droid_egl_driver *) drv; +} + +static INLINE struct droid_egl_display * +lookup_display(_EGLDisplay *dpy) +{ +   return (struct droid_egl_display *) dpy->DriverData; +} + +static INLINE struct droid_egl_context * +lookup_context(_EGLContext *context) +{ +   return (struct droid_egl_context *) context; +} + +static INLINE struct droid_egl_surface * +lookup_surface(_EGLSurface *surface) +{ +   return (struct droid_egl_surface *) surface; +} + +static INLINE struct droid_egl_config * +lookup_config(_EGLConfig *conf) +{ +   return (struct droid_egl_config *) conf; +} + +static void +droid_create_configs(_EGLDisplay *dpy, struct droid_egl_display *droid_dpy, +                     const __DRIconfig **configs, EGLint num_configs) +{ +   EGLint i; +   EGLint id = 1; + +   for (i = 0; i < num_configs; i++) { +      struct droid_egl_config *droid_conf = calloc(1, sizeof(*droid_conf)); +      EGLint val; + +      if (!droid_conf) +         break; + +      _eglInitConfig(&droid_conf->base, id); +      droid_conf->config = configs[i]; +      droid_screen_convert_config(droid_dpy->screen, droid_conf->config, +                                  &droid_conf->base); + +      val = GET_CONFIG_ATTRIB(&droid_conf->base, EGL_CONFIG_CAVEAT); +      /* we do not want slow configs */ +      if (val == EGL_SLOW_CONFIG) { +         free(droid_conf); +      } else { +         _eglAddConfig(dpy, &droid_conf->base); +         id++; +      } +   } +} + + +static EGLBoolean +droid_initialize_display(struct droid_egl_display *droid_dpy) +{ +   const char *path = DROID_DEVICE_PATH; + +   droid_dpy->backend = droid_backend_create_intel(path); +   if (!droid_dpy->backend) +      return EGL_FALSE; + +   droid_dpy->screen = droid_screen_create(droid_dpy->backend); +   if (!droid_dpy->screen) { +      free(droid_dpy->backend); +      droid_dpy->backend = NULL; +      return EGL_FALSE; +   } + +   droid_dpy->apis = EGL_OPENGL_ES_BIT; +   droid_dpy->major = 1; +   droid_dpy->major = 4; + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, +                    EGLint *major, EGLint *minor) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   struct droid_egl_display *droid_dpy; + +   if (dpy->NativeDisplay != EGL_DEFAULT_DISPLAY) +      return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + +   /* the default display */ +   droid_dpy = droid_drv->default_display; +   if (!droid_dpy) { +      droid_dpy = calloc(1, sizeof(*droid_dpy)); +      if (!droid_dpy) +         return _eglError(EGL_BAD_ALLOC, "eglInitialize"); +      if (!droid_initialize_display(droid_dpy)) +         return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); + +      droid_create_configs(dpy, droid_dpy, droid_dpy->screen->dri_configs, +                           droid_dpy->screen->num_dri_configs); + +      droid_drv->default_display = droid_dpy; +   } + +   dpy->DriverData = (void *) droid_dpy; +   droid_dpy->refcnt++; + +   *major = droid_dpy->major; +   *minor = droid_dpy->minor; + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   struct droid_egl_display *droid_dpy = lookup_display(dpy); + +   dpy->DriverData = NULL; +   droid_dpy->refcnt--; +   if (!droid_dpy->refcnt) { +      _eglReleaseDisplayResources(drv, dpy); +      _eglCleanupDisplay(dpy); + +      free(droid_dpy); +      droid_drv->default_display = NULL; +   } + +   return EGL_TRUE; +} + +static _EGLProc +droid_eglGetProcAddress(const char *procname) +{ +   return (_EGLProc) _glapi_get_proc_address(procname); +} + +static _EGLContext * +droid_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, +                       _EGLContext *share_list, const EGLint *attrib_list) +{ +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_config *droid_conf = lookup_config(conf); +   struct droid_egl_context *shared = lookup_context(share_list); +   struct droid_egl_context *ctx; + +   ctx = calloc(1, sizeof(*ctx)); +   if (!ctx) { +      _eglError(EGL_BAD_ALLOC, "eglCreateContext"); +      return NULL; +   } + +   if (!_eglInitContext(drv, &ctx->base, &droid_conf->base, attrib_list)) { +      free(ctx); +      return NULL; +   } + +   ctx->context = +      droid_screen_create_context(droid_dpy->screen, droid_conf->config, +                                  (shared) ? shared->context : NULL); +   if (!ctx->context) { +      free(ctx); +      return NULL; +   } + +   return &ctx->base; +} + +static EGLBoolean +droid_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_context *droid_ctx = lookup_context(ctx); + +   if (!_eglIsContextBound(ctx)) +      droid_screen_destroy_context(droid_dpy->screen, droid_ctx->context); + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, +                     _EGLSurface *r, _EGLContext *ctx) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_surface *draw = lookup_surface(d); +   struct droid_egl_surface *read = lookup_surface(r); +   struct droid_egl_context *droid_ctx = lookup_context(ctx); +   _EGLContext *old; +   struct droid_egl_context *droid_old; + +   old = _eglGetCurrentContext(); +   /* an unlinked context will be invalid after context switch */ +   if (!_eglIsContextLinked(old)) +      old = NULL; + +   droid_old = lookup_context(old); + +   if (!_eglMakeCurrent(drv, dpy, d, r, ctx)) +      return EGL_FALSE; + +   if (droid_old && droid_old != droid_ctx && droid_drv->flush_current) +      droid_drv->flush_current(); + +   _glapi_check_multithread(); + +   /* bind new context or unbind old one */ +   if (droid_ctx) +      droid_screen_bind_context(droid_dpy->screen, +                                draw->drawable, read->drawable, +                                droid_ctx->context); +   else if (droid_old) +      droid_screen_bind_context(droid_dpy->screen, +                                NULL, NULL, +                                droid_old->context); + +   return EGL_TRUE; +} + +static _EGLSurface * +droid_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, +                             NativeWindowType window, const EGLint *attrib_list) +{ +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_config *droid_conf = lookup_config(conf); +   struct droid_egl_surface *surf; + +   surf = calloc(1, sizeof(*surf)); +   if (!surf) { +      _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface"); +      return NULL; +   } + +   if (!_eglInitSurface(drv, &surf->base, EGL_WINDOW_BIT, &droid_conf->base, attrib_list)) { +      free(surf); +      return NULL; +   } + +   surf->surface = +      droid_dpy->backend->create_window_surface(droid_dpy->backend, +                                                &surf->base, window); +   if (!surf->surface) { +      free(surf); +      return NULL; +   } + +   surf->drawable = droid_screen_create_drawable(droid_dpy->screen, +                                                 droid_conf->config, +                                                 surf->surface); +   if (!surf->drawable) { +      droid_dpy->backend->destroy_surface(droid_dpy->backend, surf->surface); +      free(surf); +      return NULL; +   } + +   return &surf->base; +} + +static EGLBoolean +droid_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_surface *droid_surf = lookup_surface(surf); + +   if (_eglIsSurfaceBound(&droid_surf->base)) +      return EGL_TRUE; + +   droid_screen_destroy_drawable(droid_dpy->screen, droid_surf->drawable); +   droid_dpy->backend->destroy_surface(droid_dpy->backend, droid_surf->surface); +   free(droid_surf); + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   struct droid_egl_surface *droid_surf = lookup_surface(surf); +   _EGLContext *ctx = _eglGetCurrentContext(); +   struct droid_egl_context *droid_ctx = lookup_context(ctx); + +   if (droid_ctx) { +      if (droid_drv->flush_current) +         droid_drv->flush_current(); + +      droid_screen_swap_buffers(droid_dpy->screen, +                                droid_ctx->context, +                                droid_surf->drawable); +   } + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglWaitClient(_EGLDriver *drv, _EGLDisplay *dpy) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   _EGLContext *ctx = _eglGetCurrentContext(); + +   if (!ctx || !droid_drv->finish_current) +      return EGL_TRUE; + +   if (!_eglIsSurfaceLinked(ctx->DrawSurface)) +      return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitClient"); + +   droid_drv->finish_current(); + +   return EGL_TRUE; +} + +static EGLBoolean +droid_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine) +{ +   struct droid_egl_display *droid_dpy = lookup_display(dpy); +   _EGLContext *ctx = _eglGetCurrentContext(); +   struct droid_egl_surface *droid_surf; + +   if (engine != EGL_CORE_NATIVE_ENGINE) +      return _eglError(EGL_BAD_PARAMETER, "eglWaitNative"); + +   if (!ctx)  +      return EGL_TRUE; + +   if (!_eglIsSurfaceLinked(ctx->DrawSurface)) +      return _eglError(EGL_BAD_CURRENT_SURFACE, "eglWaitNative"); + +   droid_surf = lookup_surface(ctx->DrawSurface); +   droid_dpy->backend->swap_native_buffers(droid_dpy->backend, +                                           droid_surf->surface); + +   return EGL_TRUE; +} + +static void +droid_Unload(_EGLDriver *drv) +{ +   struct droid_egl_driver *droid_drv = lookup_driver(drv); +   free(droid_drv); +} + +_EGLDriver * +_eglMain(const char *args) +{ +   struct droid_egl_driver *droid_drv = calloc(1, sizeof(*droid_drv)); +   if (!droid_drv) +      return NULL; + +   _eglInitDriverFallbacks(&droid_drv->base); +   droid_drv->base.API.Initialize = droid_eglInitialize; +   droid_drv->base.API.Terminate = droid_eglTerminate; + +   droid_drv->base.API.GetProcAddress = droid_eglGetProcAddress; + +   droid_drv->base.API.CreateContext = droid_eglCreateContext; +   droid_drv->base.API.DestroyContext = droid_eglDestroyContext; +   droid_drv->base.API.MakeCurrent = droid_eglMakeCurrent; +   droid_drv->base.API.CreateWindowSurface = droid_eglCreateWindowSurface; +   droid_drv->base.API.DestroySurface = droid_eglDestroySurface; +   droid_drv->base.API.SwapBuffers = droid_eglSwapBuffers; +   droid_drv->base.API.WaitClient = droid_eglWaitClient; +   droid_drv->base.API.WaitNative = droid_eglWaitNative; + +   droid_drv->base.Name = "Android/i915"; +   droid_drv->base.Unload = droid_Unload; + +   /* we need a way to flush commands */ +   droid_drv->flush_current = +      (void (*)(void)) droid_eglGetProcAddress("glFlush"); +   droid_drv->finish_current = +      (void (*)(void)) droid_eglGetProcAddress("glFinish"); + +   return &droid_drv->base; +} diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 89e04a7130..f693b304d4 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -195,7 +195,11 @@ _eglLoadDriver(char *path, char *args)     lib_handle lib;     _EGLDriver *drv = NULL; -   mainFunc = _eglOpenLibrary(path, &lib); +   /* temporary hack */ +   (void) _eglOpenLibrary; +   mainFunc = _eglMain; +   lib = (lib_handle) 0; +     if (!mainFunc)        return NULL; diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h index b6321716d3..a62d1edc27 100644 --- a/src/egl/main/egltypedefs.h +++ b/src/egl/main/egltypedefs.h @@ -6,6 +6,62 @@  #include <EGL/egl.h>  #include <EGL/eglext.h> +#ifndef EGL_MESA_screen_surface +#define EGL_MESA_screen_surface 1 + +#define EGL_BAD_SCREEN_MESA                    0x4000 +#define EGL_BAD_MODE_MESA                      0x4001 +#define EGL_SCREEN_COUNT_MESA                  0x4002 +#define EGL_SCREEN_POSITION_MESA               0x4003 +#define EGL_SCREEN_POSITION_GRANULARITY_MESA   0x4004 +#define EGL_MODE_ID_MESA                       0x4005 +#define EGL_REFRESH_RATE_MESA                  0x4006 +#define EGL_OPTIMAL_MESA                       0x4007 +#define EGL_INTERLACED_MESA                    0x4008 +#define EGL_SCREEN_BIT_MESA                    0x08 + +typedef uint32_t EGLScreenMESA; +typedef uint32_t EGLModeMESA; + +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); +EGLAPI EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); +EGLAPI EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); +EGLAPI EGLSurface EGLAPIENTRY eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode); +EGLAPI EGLBoolean EGLAPIENTRY eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); +EGLAPI const char * EGLAPIENTRY eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode); +#endif /* EGL_EGLEXT_PROTOTYPES */ + +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSEMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMODESMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGetModeATTRIBMESA) (EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSCRREENSMESA) (EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESCREENSURFACEMESA) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSHOWSCREENSURFACEMESA) (EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSCREENPOSIITONMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENSURFACEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSCREENMODEMESA) (EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode); +typedef const char * (EGLAPIENTRYP PFNEGLQUERYMODESTRINGMESA) (EGLDisplay dpy, EGLModeMESA mode); + +#endif /* EGL_MESA_screen_surface */ + +#ifndef EGL_MESA_copy_context +#define EGL_MESA_copy_context 1 + +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); +#endif /* EGL_EGLEXT_PROTOTYPES */ + +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask); + +#endif /* EGL_MESA_copy_context */ +  #include "eglcompiler.h"  typedef struct _egl_api _EGLAPI; | 
