summaryrefslogtreecommitdiffstats
path: root/src/egl/drivers/android/droid.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers/android/droid.c')
-rw-r--r--src/egl/drivers/android/droid.c223
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;
}