aboutsummaryrefslogtreecommitdiffstats
path: root/src/egl/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main')
-rw-r--r--src/egl/main/Android.mk64
-rw-r--r--src/egl/main/Makefile15
-rw-r--r--src/egl/main/eglapi.c33
-rw-r--r--src/egl/main/eglapi.h8
-rw-r--r--src/egl/main/eglconfig.c5
-rw-r--r--src/egl/main/egldisplay.c136
-rw-r--r--src/egl/main/egldisplay.h6
-rw-r--r--src/egl/main/eglmisc.c3
-rw-r--r--src/egl/main/eglsurface.c4
9 files changed, 252 insertions, 22 deletions
diff --git a/src/egl/main/Android.mk b/src/egl/main/Android.mk
new file mode 100644
index 00000000000..25a7c657676
--- /dev/null
+++ b/src/egl/main/Android.mk
@@ -0,0 +1,64 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2010-2011 Chia-I Wu <[email protected]>
+# Copyright (C) 2010-2011 LunarG Inc.
+#
+# 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 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.
+
+# Android.mk for core EGL
+
+LOCAL_PATH := $(call my-dir)
+
+# from Makefile
+SOURCES = \
+ eglapi.c \
+ eglarray.c \
+ eglconfig.c \
+ eglcontext.c \
+ eglcurrent.c \
+ egldisplay.c \
+ egldriver.c \
+ eglfallbacks.c \
+ eglglobals.c \
+ eglimage.c \
+ egllog.c \
+ eglmisc.c \
+ eglmode.c \
+ eglscreen.c \
+ eglstring.c \
+ eglsurface.c \
+ eglsync.c
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(SOURCES)
+
+LOCAL_CFLAGS := \
+ -D_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_ANDROID \
+ -D_EGL_DRIVER_SEARCH_DIR=\"/system/lib/egl\" \
+ -D_EGL_OS_UNIX=1
+
+ifeq ($(strip $(MESA_BUILD_GALLIUM)),true)
+LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_GALLIUM
+endif
+
+LOCAL_MODULE := libmesa_egl
+
+include $(MESA_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 775fbbe178b..3172ad2ec03 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -63,6 +63,7 @@ EGL_LIB_DEPS += $(XCB_DRI2_LIBS)
endif
ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
EGL_LIB_DEPS += -lgbm
+INCLUDE_DIRS += -I$(TOP)/src/gbm/main
endif
EGL_LIB_DEPS += $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
endif
@@ -70,6 +71,7 @@ endif
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
+INCLUDE_DIRS += $(WAYLAND_CFLAGS)
endif
ifeq ($(filter glx, $(EGL_DRIVERS_DIRS)),glx)
@@ -93,6 +95,19 @@ ifeq ($(firstword $(EGL_PLATFORMS)),fbdev)
EGL_NATIVE_PLATFORM=_EGL_PLATFORM_FBDEV
endif
+ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
+LOCAL_CFLAGS += -DHAVE_X11_PLATFORM
+endif
+ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
+LOCAL_CFLAGS += -DHAVE_WAYLAND_PLATFORM
+endif
+ifneq ($(findstring drm, $(EGL_PLATFORMS)),)
+LOCAL_CFLAGS += -DHAVE_DRM_PLATFORM
+endif
+ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
+LOCAL_CFLAGS += -DHAVE_FBDEV_PLATFORM
+endif
+
LOCAL_CFLAGS += \
-D_EGL_NATIVE_PLATFORM=$(EGL_NATIVE_PLATFORM) \
-D_EGL_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\"
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 0ba7794e2c9..3cb1a5baaf3 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -301,7 +301,7 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
EGLDisplay EGLAPIENTRY
eglGetDisplay(EGLNativeDisplayType nativeDisplay)
{
- _EGLPlatformType plat = _eglGetNativePlatform();
+ _EGLPlatformType plat = _eglGetNativePlatform(nativeDisplay);
_EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
return _eglGetDisplayHandle(dpy);
}
@@ -538,7 +538,7 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
EGLSurface ret;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
- if (disp->Platform != _eglGetNativePlatform())
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
@@ -559,7 +559,7 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
EGLSurface ret;
_EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
- if (disp->Platform != _eglGetNativePlatform())
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
@@ -720,7 +720,7 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
EGLBoolean ret;
_EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
- if (disp->Platform != _eglGetNativePlatform())
+ if (disp->Platform != _eglGetNativePlatform(disp->PlatformDisplay))
RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
ret = drv->API.CopyBuffers(drv, disp, surf, target);
@@ -948,6 +948,9 @@ eglGetProcAddress(const char *procname)
{ "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
{ "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
#endif
+#ifdef EGL_ANDROID_swap_rectangle
+ { "eglSetSwapRectangleANDROID", (_EGLProc) eglSetSwapRectangleANDROID },
+#endif
{ NULL, NULL }
};
EGLint i;
@@ -1565,3 +1568,25 @@ eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
RETURN_EGL_EVAL(disp, ret);
}
#endif
+
+#ifdef EGL_ANDROID_swap_rectangle
+EGLBoolean EGLAPIENTRY
+eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
+ EGLint left, EGLint top,
+ EGLint width, EGLint height)
+{
+ _EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLSurface *surf = _eglLookupSurface(draw, disp);
+ _EGLDriver *drv;
+ EGLBoolean ret;
+
+ _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+ if (!disp->Extensions.ANDROID_swap_rectangle)
+ RETURN_EGL_EVAL(disp, EGL_FALSE);
+
+ ret = drv->API.SetSwapRectangleANDROID(drv, disp, surf, left, top, width, height);
+
+ RETURN_EGL_EVAL(disp, ret);
+}
+#endif
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index 4fcbe40cd4c..1e0aef69dd7 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -131,6 +131,10 @@ typedef EGLBoolean (*BindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp,
typedef EGLBoolean (*UnbindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
#endif
+#ifdef EGL_ANDROID_swap_rectangle
+typedef EGLBoolean (*SetSwapRectangleANDROID_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, EGLint left, EGLint top, EGLint width, EGLint height);
+#endif
+
/**
* The API dispatcher jumps through these functions
*/
@@ -210,6 +214,10 @@ struct _egl_api
BindWaylandDisplayWL_t BindWaylandDisplayWL;
UnbindWaylandDisplayWL_t UnbindWaylandDisplayWL;
#endif
+
+#ifdef EGL_ANDROID_swap_rectangle
+ SetSwapRectangleANDROID_t SetSwapRectangleANDROID;
+#endif
};
#endif /* EGLAPI_INCLUDED */
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 483d9807cf0..e1d53da3cd5 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -529,8 +529,9 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *dpy,
if (!_eglValidateConfig(conf, EGL_TRUE))
return EGL_FALSE;
- /* the spec says that EGL_LEVEL cannot be EGL_DONT_CARE */
- if (conf->Level == EGL_DONT_CARE)
+ /* EGL_LEVEL and EGL_MATCH_NATIVE_PIXMAP cannot be EGL_DONT_CARE */
+ if (conf->Level == EGL_DONT_CARE ||
+ conf->MatchNativePixmap == EGL_DONT_CARE)
return EGL_FALSE;
/* ignore other attributes when EGL_CONFIG_ID is given */
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 60f31777272..1d05e57c429 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -43,6 +43,39 @@
#include "eglmutex.h"
#include "egllog.h"
+/* Includes for _eglNativePlatformDetectNativeDisplay */
+#ifdef HAVE_MINCORE
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_WAYLAND_PLATFORM
+#include <wayland-client.h>
+#endif
+#ifdef HAVE_DRM_PLATFORM
+#include <gbm.h>
+#endif
+#ifdef HAVE_FBDEV_PLATFORM
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+
+/**
+ * Map --with-egl-platforms names to platform types.
+ */
+static const struct {
+ _EGLPlatformType platform;
+ const char *name;
+} egl_platforms[_EGL_NUM_PLATFORMS] = {
+ { _EGL_PLATFORM_WINDOWS, "gdi" },
+ { _EGL_PLATFORM_X11, "x11" },
+ { _EGL_PLATFORM_WAYLAND, "wayland" },
+ { _EGL_PLATFORM_DRM, "drm" },
+ { _EGL_PLATFORM_FBDEV, "fbdev" },
+ { _EGL_PLATFORM_ANDROID, "android" }
+};
+
/**
* Return the native platform by parsing EGL_PLATFORM.
@@ -50,17 +83,6 @@
static _EGLPlatformType
_eglGetNativePlatformFromEnv(void)
{
- /* map --with-egl-platforms names to platform types */
- static const struct {
- _EGLPlatformType platform;
- const char *name;
- } egl_platforms[_EGL_NUM_PLATFORMS] = {
- { _EGL_PLATFORM_WINDOWS, "gdi" },
- { _EGL_PLATFORM_X11, "x11" },
- { _EGL_PLATFORM_WAYLAND, "wayland" },
- { _EGL_PLATFORM_DRM, "drm" },
- { _EGL_PLATFORM_FBDEV, "fbdev" }
- };
_EGLPlatformType plat = _EGL_INVALID_PLATFORM;
const char *plat_name;
EGLint i;
@@ -84,19 +106,105 @@ _eglGetNativePlatformFromEnv(void)
/**
+ * Perform validity checks on a generic pointer.
+ */
+static EGLBoolean
+_eglPointerIsDereferencable(void *p)
+{
+#ifdef HAVE_MINCORE
+ uintptr_t addr = (uintptr_t) p;
+ unsigned char valid = 0;
+ const long page_size = getpagesize();
+
+ if (p == NULL)
+ return EGL_FALSE;
+
+ /* align addr to page_size */
+ addr &= ~(page_size - 1);
+
+ if (mincore((void *) addr, page_size, &valid) < 0) {
+ _eglLog(_EGL_DEBUG, "mincore failed: %m");
+ return EGL_FALSE;
+ }
+
+ return (valid & 0x01) == 0x01;
+#else
+ return p != NULL;
+#endif
+}
+
+
+/**
+ * Try detecting native platform with the help of native display characteristcs.
+ */
+static _EGLPlatformType
+_eglNativePlatformDetectNativeDisplay(EGLNativeDisplayType nativeDisplay)
+{
+#ifdef HAVE_FBDEV_PLATFORM
+ struct stat buf;
+#endif
+
+ if (nativeDisplay == EGL_DEFAULT_DISPLAY)
+ return _EGL_INVALID_PLATFORM;
+
+#ifdef HAVE_FBDEV_PLATFORM
+ /* fbdev is the only platform that can be a file descriptor. */
+ if (fstat((intptr_t) nativeDisplay, &buf) == 0 && S_ISCHR(buf.st_mode))
+ return _EGL_PLATFORM_FBDEV;
+#endif
+
+ if (_eglPointerIsDereferencable(nativeDisplay)) {
+ void *first_pointer = *(void **) nativeDisplay;
+
+#ifdef HAVE_WAYLAND_PLATFORM
+ /* wl_display is a wl_proxy, which is a wl_object.
+ * wl_object's first element points to the interfacetype. */
+ if (first_pointer == &wl_display_interface)
+ return _EGL_PLATFORM_WAYLAND;
+#endif
+
+#ifdef HAVE_DRM_PLATFORM
+ /* gbm has a pointer to its constructor as first element. */
+ if (first_pointer == gbm_create_device)
+ return _EGL_PLATFORM_DRM;
+#endif
+
+#ifdef HAVE_X11_PLATFORM
+ /* If not matched to any other platform, fallback to x11. */
+ return _EGL_PLATFORM_X11;
+#endif
+ }
+
+ return _EGL_INVALID_PLATFORM;
+}
+
+
+/**
* Return the native platform. It is the platform of the EGL native types.
*/
_EGLPlatformType
-_eglGetNativePlatform(void)
+_eglGetNativePlatform(EGLNativeDisplayType nativeDisplay)
{
static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
+ char *detection_method = NULL;
if (native_platform == _EGL_INVALID_PLATFORM) {
native_platform = _eglGetNativePlatformFromEnv();
- if (native_platform == _EGL_INVALID_PLATFORM)
- native_platform = _EGL_NATIVE_PLATFORM;
+ detection_method = "environment overwrite";
+ if (native_platform == _EGL_INVALID_PLATFORM) {
+ native_platform = _eglNativePlatformDetectNativeDisplay(nativeDisplay);
+ detection_method = "autodetected";
+ if (native_platform == _EGL_INVALID_PLATFORM) {
+ native_platform = _EGL_NATIVE_PLATFORM;
+ detection_method = "build-time configuration";
+ }
+ }
}
+ if (detection_method != NULL)
+ _eglLog(_EGL_DEBUG, "Native platform type: %s (%s)",
+ egl_platforms[native_platform].name, detection_method);
+
return native_platform;
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 9cd4dbfcc8a..cddea803c24 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -44,6 +44,7 @@ enum _egl_platform_type {
_EGL_PLATFORM_WAYLAND,
_EGL_PLATFORM_DRM,
_EGL_PLATFORM_FBDEV,
+ _EGL_PLATFORM_ANDROID,
_EGL_NUM_PLATFORMS,
_EGL_INVALID_PLATFORM = -1
@@ -107,6 +108,9 @@ struct _egl_extensions
EGLBoolean NOK_swap_region;
EGLBoolean NOK_texture_from_pixmap;
+
+ EGLBoolean ANDROID_image_native_buffer;
+ EGLBoolean ANDROID_swap_rectangle;
};
@@ -150,7 +154,7 @@ struct _egl_display
extern _EGLPlatformType
-_eglGetNativePlatform(void);
+_eglGetNativePlatform(EGLNativeDisplayType nativeDisplay);
extern void
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index da189b689a3..ab48bc68218 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -113,6 +113,9 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(NOK_swap_region);
_EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
+
+ _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer);
+ _EGL_CHECK_EXTENSION(ANDROID_swap_rectangle);
#undef _EGL_CHECK_EXTENSION
}
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index c9cfb01388e..3564ecd01b0 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -269,11 +269,13 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
{
const char *func;
EGLint renderBuffer = EGL_BACK_BUFFER;
+ EGLint swapBehavior = EGL_BUFFER_PRESERVED;
EGLint err;
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
+ swapBehavior = EGL_BUFFER_DESTROYED;
break;
case EGL_PIXMAP_BIT:
func = "eglCreatePixmapSurface";
@@ -315,7 +317,7 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
surf->MipmapLevel = 0;
surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
- surf->SwapBehavior = EGL_BUFFER_DESTROYED;
+ surf->SwapBehavior = swapBehavior;
surf->HorizontalResolution = EGL_UNKNOWN;
surf->VerticalResolution = EGL_UNKNOWN;