diff options
Diffstat (limited to 'src/egl/drivers/android')
-rw-r--r-- | src/egl/drivers/android/droid.c | 223 | ||||
-rw-r--r-- | src/egl/drivers/android/droid.h | 3 | ||||
-rw-r--r-- | src/egl/drivers/android/droid_core.c | 26 | ||||
-rw-r--r-- | src/egl/drivers/android/egl_android.c | 2 |
4 files changed, 195 insertions, 59 deletions
diff --git a/src/egl/drivers/android/droid.c b/src/egl/drivers/android/droid.c index 60c100bb13..a902b2d86e 100644 --- a/src/egl/drivers/android/droid.c +++ b/src/egl/drivers/android/droid.c @@ -27,9 +27,11 @@ #define LOG_TAG "MESA-EGL" +#include <stdlib.h> +#include <string.h> +#include <dlfcn.h> #include <cutils/log.h> -#include "glapi/glapi.h" #include "droid.h" static const __DRIuseInvalidateExtension use_invalidate = { @@ -157,6 +159,9 @@ droid_get_buffers_with_format(__DRIdrawable * driDrawable, return NULL; } + dsurf->base.Width = dsurf->buffer->width; + dsurf->base.Height = dsurf->buffer->height; + if (width) *width = dsurf->buffer->width; if (height) @@ -216,6 +221,7 @@ static const EGLint droid_to_egl_attribute_map[] = { 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */ EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ + 0, /* __DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE */ }; static struct droid_egl_config * @@ -226,7 +232,7 @@ droid_add_config(_EGLDisplay *dpy, const __DRIconfig *dri_config, int id, struct droid_egl_display *ddpy; _EGLConfig base; unsigned int attrib, value, double_buffer; - EGLint key, bind_to_texture_rgb, bind_to_texture_rgba; + EGLint key; int dri_masks[4] = { 0, 0, 0, 0 }; int i; @@ -235,8 +241,6 @@ droid_add_config(_EGLDisplay *dpy, const __DRIconfig *dri_config, int 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) { @@ -260,14 +264,6 @@ droid_add_config(_EGLDisplay *dpy, const __DRIconfig *dri_config, int id, _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; @@ -315,15 +311,9 @@ droid_add_config(_EGLDisplay *dpy, const __DRIconfig *dri_config, int id, _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); + _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, dpy->ClientAPIs); + _eglSetConfigKey(&base, EGL_CONFORMANT, dpy->ClientAPIs); if (!_eglValidateConfig(&base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); @@ -462,15 +452,15 @@ droid_create_screen(_EGLDisplay *dpy) if (ddpy->dri2->base.version >= 2) api_mask = ddpy->dri2->getAPIMask(ddpy->dri_screen); else - api_mask = __DRI_API_OPENGL; + api_mask = 1 << __DRI_API_OPENGL; - dpy->ClientAPIsMask = 0; + dpy->ClientAPIs = 0; if (api_mask & (1 <<__DRI_API_OPENGL)) - dpy->ClientAPIsMask |= EGL_OPENGL_BIT; + dpy->ClientAPIs |= EGL_OPENGL_BIT; if (api_mask & (1 <<__DRI_API_GLES)) - dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES_BIT; if (api_mask & (1 << __DRI_API_GLES2)) - dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT; if (ddpy->dri2->base.version >= 2) { dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE; @@ -482,26 +472,110 @@ droid_create_screen(_EGLDisplay *dpy) } static EGLBoolean -droid_load_driver(_EGLDisplay *disp) +droid_load_driver(_EGLDisplay *dpy, const char *driver_name) { - struct droid_egl_display *ddpy = disp->DriverData; + struct droid_egl_display *ddpy = droid_egl_display(dpy); const __DRIextension **extensions; + char path[PATH_MAX], *base = NULL; + void *handle; + + if (geteuid() == getuid()) { + /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */ + base = getenv("LIBGL_DRIVERS_PATH"); + } + if (!base) + base = DEFAULT_DRIVER_DIR; + snprintf(path, sizeof(path), "%s/%s_dri.so", base, driver_name); + + handle = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (!handle) { + _eglLog(_EGL_WARNING, "DRI2: failed to load %s: %s", path, dlerror()); + return EGL_FALSE; + } - extensions = __driDriverExtensions; + _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path); + extensions = dlsym(handle, __DRI_DRIVER_EXTENSIONS); + if (!extensions) { + _eglLog(_EGL_WARNING, "DRI2: driver exports no extensions"); + dlclose(handle); + return EGL_FALSE; + } - if (!droid_bind_extensions(ddpy, droid_driver_extensions, extensions)) + if (!droid_bind_extensions(ddpy, droid_driver_extensions, extensions)) { + dlclose(handle); return EGL_FALSE; + } + + ddpy->dri_handle = handle; return EGL_TRUE; } -static EGLBoolean -droid_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) +#include <xf86drm.h> +/* for i915 */ +#include <i915_drm.h> +#include "dri/intel/intel_chipset.h" +/* for radeon */ +#include <radeon_drm.h> +#include "radeon/drm/radeon_drm_public.h" +static const char * +droid_get_driver_name(int fd) +{ + drmVersionPtr version; + char *name = NULL; + + version = drmGetVersion(fd); + if (!version) { + _eglLog(_EGL_WARNING, "invalid drm fd"); + return NULL; + } + if (!version->name) { + _eglLog(_EGL_WARNING, "unable to determine the driver name"); + drmFreeVersion(version); + return NULL; + } + + if (strcmp(version->name, "i915") == 0) { + struct drm_i915_getparam gp; + int id, ret; + + memset(&gp, 0, sizeof(gp)); + gp.param = I915_PARAM_CHIPSET_ID; + gp.value = &id; + ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); + if (ret) { + _eglLog(_EGL_WARNING, "failed to get param for i915"); + } + else { + name = (IS_965(id)) ? "i965" : "i915"; + } + } + else if (strcmp(version->name, "radeon") == 0) { + struct drm_radeon_info info; + int id, ret; + + memset(&info, 0, sizeof(info)); + info.request = RADEON_INFO_DEVICE_ID; + info.value = (long) &id; + ret = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); + if (ret) { + _eglLog(_EGL_WARNING, "failed to get info for radeon"); + } + else { + name = (is_r3xx(id)) ? "r300" : "r600"; + } + } + + drmFreeVersion(version); + + return name; +} + +static int +droid_open_device(void) { - struct droid_egl_display *ddpy; - int fd = -1, err, i; const hw_module_t *mod; + int fd = -1, err; err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod); if (!err) { @@ -513,17 +587,34 @@ droid_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy, } if (err || fd < 0) { _eglLog(_EGL_WARNING, "fail to get drm fd"); - return EGL_FALSE; + fd = -1; } + return fd; +} + +static EGLBoolean +droid_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy) +{ + struct droid_egl_display *ddpy; + const char *driver_name; + int fd; + + fd = droid_open_device(); + if (fd < 0) + return EGL_FALSE; + driver_name = droid_get_driver_name(fd); + if (!driver_name) + return EGL_FALSE; + ddpy = calloc(1, sizeof(*ddpy)); if (!ddpy) return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + ddpy->fd = fd; dpy->DriverData = (void *) ddpy; - ddpy->fd = fd; - if (!droid_load_driver(dpy)) + if (!droid_load_driver(dpy, driver_name)) return EGL_FALSE; ddpy->loader_extension.base.name = __DRI_DRI2_LOADER; @@ -552,8 +643,8 @@ droid_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy, dpy->Extensions.KHR_image_base = EGL_TRUE; /* we're supporting EGL 1.4 */ - *major = 1; - *minor = 4; + dpy->VersionMajor = 1; + dpy->VersionMinor = 4; return EGL_TRUE; } @@ -567,19 +658,26 @@ droid_terminate(_EGLDriver *drv, _EGLDisplay *dpy) _eglCleanupDisplay(dpy); ddpy->core->destroyScreen(ddpy->dri_screen); + dlclose(ddpy->dri_handle); free(ddpy); + dpy->DriverData = NULL; return EGL_TRUE; } static EGLBoolean -droid_initialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) +droid_initialize(_EGLDriver *drv, _EGLDisplay *dpy) { + /* not until swrast_dri is supported */ + if (dpy->Options.UseFallback) + return EGL_FALSE; + switch (dpy->Platform) { case _EGL_PLATFORM_ANDROID: - return droid_initialize_android(drv, dpy, major, minor); + if (dpy->Options.TestOnly) + return EGL_TRUE; + return droid_initialize_android(drv, dpy); default: return EGL_FALSE; } @@ -588,16 +686,9 @@ droid_initialize(_EGLDriver *drv, _EGLDisplay *dpy, 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); + return ddrv->get_proc_address(procname); } static void @@ -621,6 +712,30 @@ droid_log(EGLint level, const char *msg) } } +static void +droid_unload(_EGLDriver *drv) +{ + struct droid_egl_driver *ddrv = droid_egl_driver(drv); + + free(ddrv); +} + +#include "glapi/glapi.h" /* for _glapi_get_proc_address */ +static EGLBoolean +droid_load(_EGLDriver *drv) +{ + struct droid_egl_driver *ddrv = droid_egl_driver(drv); + + ddrv->get_proc_address = (_EGLProc (*)(const char *)) _glapi_get_proc_address; + + ddrv->glFlush = (void (*)(void)) + ddrv->get_proc_address("glFlush"); + ddrv->glFinish = (void (*)(void)) + ddrv->get_proc_address("glFinish"); + + return EGL_TRUE; +} + _EGLDriver * droid_create_driver(void) { @@ -630,6 +745,9 @@ droid_create_driver(void) if (!ddrv) return NULL; + if (!droid_load(&ddrv->base)) + return NULL; + _eglSetLogProc(droid_log); ddrv->base.Name = "Droid"; @@ -640,10 +758,5 @@ droid_create_driver(void) 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 index 20e32a6588..0a0e6147f2 100644 --- a/src/egl/drivers/android/droid.h +++ b/src/egl/drivers/android/droid.h @@ -50,6 +50,7 @@ struct droid_egl_driver { _EGLDriver base; + _EGLProc (*get_proc_address)(const char *procname); void (*glFlush)(void); void (*glFinish)(void); }; @@ -58,6 +59,8 @@ struct droid_egl_display { int fd; + void *dri_handle; + __DRIscreen *dri_screen; const __DRIconfig **dri_configs; __DRIcoreExtension *core; diff --git a/src/egl/drivers/android/droid_core.c b/src/egl/drivers/android/droid_core.c index 82c21d4aa9..26eb96c7ff 100644 --- a/src/egl/drivers/android/droid_core.c +++ b/src/egl/drivers/android/droid_core.c @@ -105,6 +105,24 @@ droid_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } +static EGLBoolean +droid_destroy_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx) +{ + struct droid_egl_display *ddpy = droid_egl_display(disp); + struct droid_egl_context *dctx = droid_egl_context(ctx); + + (void) drv; + + if (!_eglPutContext(ctx)) + return EGL_TRUE; + + (*ddpy->core->destroyContext)(dctx->dri_context); + + free(dctx); + + return EGL_TRUE; +} + static _EGLSurface * droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, @@ -203,7 +221,9 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) (*ddpy->core->destroyDrawable)(dsurf->dri_drawable); - droid_enqueue_buffer(dsurf); + if (dsurf->buffer) + droid_enqueue_buffer(dsurf); + dsurf->window->common.decRef(&dsurf->window->common); free(surf); @@ -247,8 +267,7 @@ droid_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, __DRIcontext *old_cctx = droid_egl_context(old_ctx)->dri_context; ddpy->core->unbindContext(old_cctx); } - /* no destroy? */ - _eglPutContext(old_ctx); + droid_destroy_context(drv, disp, old_ctx); } return EGL_TRUE; @@ -317,6 +336,7 @@ 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.DestroyContext = droid_destroy_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; diff --git a/src/egl/drivers/android/egl_android.c b/src/egl/drivers/android/egl_android.c index 3f1cb36b78..56a29bb7b7 100644 --- a/src/egl/drivers/android/egl_android.c +++ b/src/egl/drivers/android/egl_android.c @@ -28,7 +28,7 @@ #include "droid.h" _EGLDriver * -_eglMain(const char *args) +_EGL_MAIN(const char *args) { _EGLDriver *drv; |