diff options
Diffstat (limited to 'src/egl/drivers/android/droid.c')
-rw-r--r-- | src/egl/drivers/android/droid.c | 223 |
1 files changed, 168 insertions, 55 deletions
diff --git a/src/egl/drivers/android/droid.c b/src/egl/drivers/android/droid.c index 60c100bb131..a902b2d86e6 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; } |