mesa: Changes to 'ubuntu'
debian/changelog | 21
debian/control | 14
debian/libegl1-mesa-drivers.install.linux.in | 2
debian/libegl1-mesa.symbols | 1
debian/libgbm1.install.in | 2
debian/libgl1-mesa-dri.install.in | 4
debian/libopenvg1-mesa-dev.install.in | 6
debian/libopenvg1-mesa.install.in | 2
debian/patches/aarch64.diff | 12
debian/patches/egl-platform-mir.patch | 1550 +++++++++++++++++++++++++++
debian/patches/series | 3
debian/rules | 37
12 files changed, 1632 insertions(+), 22 deletions(-)
New commits:
commit fdefb253e21e87ca5c4310168f454d0433e62e3c
Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
Date: Fri Aug 2 20:43:44 2013 +1000
Add Mir EGL platform patch
diff --git a/debian/changelog b/debian/changelog
index 4c58b09..a16a96b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+mesa (9.1.4-0ubuntu6) saucy; urgency=low
+
+ * Add Mir EGL platform
+
+ -- Christopher James Halse Rogers <raof@ubuntu.com> Fri, 02 Aug 2013 13:30:23 +1000
+
mesa (9.1.4-0ubuntu5) saucy; urgency=low
* Fix the build on Aarch64, disabling most of the acceleration
diff --git a/debian/control b/debian/control
index e6f4449..f7c2d41 100644
--- a/debian/control
+++ b/debian/control
@@ -33,6 +33,7 @@ Build-Depends:
bison,
llvm-3.2-dev (>= 1:3.2repack-7~) [amd64 i386 kfreebsd-amd64 kfreebsd-i386 armhf powerpc],
libwayland-dev (>= 1.0.2) [linux-any],
+ libmirclient-dev [linux-any],
Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/mesa
Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/mesa.git
Homepage: http://mesa3d.sourceforge.net/
@@ -183,6 +184,7 @@ Depends:
libxcb-glx0-dev,
libxcb-dri2-0-dev,
libx11-xcb-dev,
+ libmirclient-dev [linux-any],
${misc:Depends},
Description: free implementation of the EGL API -- development files
This package contains the development environment required for compiling
diff --git a/debian/libegl1-mesa.symbols b/debian/libegl1-mesa.symbols
index 0f89904..3af6509 100644
--- a/debian/libegl1-mesa.symbols
+++ b/debian/libegl1-mesa.symbols
@@ -9,6 +9,7 @@ libEGL.so.1 libegl1-mesa #MINVER# | libegl1-x11
(arch=linux-any)dri2_get_device_name_for_fd@Base 8.1~0
(arch=linux-any)dri2_get_driver_for_fd@Base 8.1~0
(arch=linux-any)dri2_initialize_drm@Base 8.1~0
+ (arch=linux-any)dri2_initialize_mir@Base 9.1.4-0ubuntu6~
(arch=linux-any)dri2_initialize_wayland@Base 8.1~0
dri2_initialize_x11@Base 8.1~0
dri2_load_driver@Base 8.1~0
diff --git a/debian/patches/egl-platform-mir.patch b/debian/patches/egl-platform-mir.patch
new file mode 100644
index 0000000..58c69b4
--- /dev/null
+++ b/debian/patches/egl-platform-mir.patch
@@ -0,0 +1,1550 @@
+Index: mesa/configure.ac
+===================================================================
+--- mesa.orig/configure.ac 2013-08-02 13:52:39.909145976 +1000
++++ mesa/configure.ac 2013-08-02 13:52:39.893145977 +1000
+@@ -1547,7 +1547,9 @@
+
+ android|gdi)
+ ;;
+-
++ mir)
++ PKG_CHECK_MODULES([MIR], [mirclient])
++ ;;
+ *)
+ AC_MSG_ERROR([EGL platform '$plat' does not exist])
+ ;;
+@@ -1575,6 +1577,7 @@
+ AM_CONDITIONAL(HAVE_EGL_PLATFORM_DRM, echo "$egl_platforms" | grep 'drm' >/dev/null 2>&1)
+ AM_CONDITIONAL(HAVE_EGL_PLATFORM_FBDEV, echo "$egl_platforms" | grep 'fbdev' >/dev/null 2>&1)
+ AM_CONDITIONAL(HAVE_EGL_PLATFORM_NULL, echo "$egl_platforms" | grep 'null' >/dev/null 2>&1)
++AM_CONDITIONAL(HAVE_EGL_PLATFORM_MIR, echo "$egl_platforms" | grep 'mir' >/dev/null 2>&1)
+
+ AM_CONDITIONAL(HAVE_EGL_DRIVER_DRI2, test "x$HAVE_EGL_DRIVER_DRI2" != "x")
+ AM_CONDITIONAL(HAVE_EGL_DRIVER_GLX, test "x$HAVE_EGL_DRIVER_GLX" != "x")
+Index: mesa/include/EGL/eglplatform.h
+===================================================================
+--- mesa.orig/include/EGL/eglplatform.h 2013-08-02 13:52:39.909145976 +1000
++++ mesa/include/EGL/eglplatform.h 2013-08-02 13:52:39.893145977 +1000
+@@ -104,6 +104,13 @@
+ typedef struct egl_native_pixmap_t *EGLNativePixmapType;
+ typedef void *EGLNativeDisplayType;
+
++#elif defined(MIR_EGL_PLATFORM)
++
++#include <mir_toolkit/mir_client_library.h>
++typedef MirEGLNativeDisplayType EGLNativeDisplayType;
++typedef void *EGLNativePixmapType;
++typedef MirEGLNativeWindowType EGLNativeWindowType;
++
+ #elif defined(__unix__)
+
+ #ifdef MESA_EGL_NO_X11_HEADERS
+Index: mesa/include/GL/internal/dri_interface.h
+===================================================================
+--- mesa.orig/include/GL/internal/dri_interface.h 2013-08-02 13:52:39.909145976 +1000
++++ mesa/include/GL/internal/dri_interface.h 2013-08-02 13:52:39.893145977 +1000
+@@ -766,10 +766,12 @@
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
++ unsigned int fd; /**< Only available with DRI2_LOADER_VERSION >= 4, */
++ /**< Only valid if name == 0 */
+ };
+
+ #define __DRI_DRI2_LOADER "DRI_DRI2Loader"
+-#define __DRI_DRI2_LOADER_VERSION 3
++#define __DRI_DRI2_LOADER_VERSION 4
+ struct __DRIdri2LoaderExtensionRec {
+ __DRIextension base;
+
+@@ -1021,6 +1023,9 @@
+ #define __DRI_IMAGE_ATTRIB_WIDTH 0x2004 /* available in versions 4+ */
+ #define __DRI_IMAGE_ATTRIB_HEIGHT 0x2005
+ #define __DRI_IMAGE_ATTRIB_COMPONENTS 0x2006 /* available in versions 5+ */
++#define __DRI_IMAGE_ATTRIB_FD 0x2007 /* available in versions
++ * 7+. Each query will return a
++ * new fd. */
+
+ typedef struct __DRIimageRec __DRIimage;
+ typedef struct __DRIimageExtensionRec __DRIimageExtension;
+Index: mesa/src/egl/drivers/dri2/Makefile.am
+===================================================================
+--- mesa.orig/src/egl/drivers/dri2/Makefile.am 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/drivers/dri2/Makefile.am 2013-08-02 13:52:39.893145977 +1000
+@@ -62,3 +62,9 @@
+ libegl_dri2_la_SOURCES += platform_drm.c
+ AM_CFLAGS += -DHAVE_DRM_PLATFORM
+ endif
++
++if HAVE_EGL_PLATFORM_MIR
++libegl_dri2_la_SOURCES += platform_mir.c
++AM_CFLAGS += -DHAVE_MIR_PLATFORM
++AM_CFLAGS += $(MIR_CFLAGS)
++endif
+Index: mesa/src/egl/drivers/dri2/egl_dri2.c
+===================================================================
+--- mesa.orig/src/egl/drivers/dri2/egl_dri2.c 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/drivers/dri2/egl_dri2.c 2013-08-02 13:52:39.897145977 +1000
+@@ -594,6 +594,12 @@
+ return EGL_TRUE;
+ return dri2_initialize_wayland(drv, disp);
+ #endif
++#ifdef HAVE_MIR_PLATFORM
++ case _EGL_PLATFORM_MIR:
++ if (disp->Options.TestOnly)
++ return EGL_TRUE;
++ return dri2_initialize_mir(drv, disp);
++#endif
+ #endif
+ #ifdef HAVE_ANDROID_PLATFORM
+ case _EGL_PLATFORM_ANDROID:
+Index: mesa/src/egl/drivers/dri2/egl_dri2.h
+===================================================================
+--- mesa.orig/src/egl/drivers/dri2/egl_dri2.h 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/drivers/dri2/egl_dri2.h 2013-08-02 13:52:39.897145977 +1000
+@@ -65,6 +65,11 @@
+
+ #endif /* HAVE_ANDROID_PLATFORM */
+
++#ifdef HAVE_MIR_PLATFORM
++#include <mir_toolkit/mir_client_library.h>
++#include <mir_toolkit/mesa/native_display.h>
++#endif
++
+ #include "eglconfig.h"
+ #include "eglcontext.h"
+ #include "egldisplay.h"
+@@ -134,6 +139,10 @@
+ int formats;
+ #endif
+
++#ifdef HAVE_MIR_PLATFORM
++ MirMesaEGLNativeDisplay *mir_disp;
++#endif
++
+ int (*authenticate) (_EGLDisplay *disp, uint32_t id);
+ };
+
+@@ -182,7 +191,9 @@
+ struct gbm_dri_surface *gbm_surf;
+ #endif
+
+-#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
++#if defined(HAVE_WAYLAND_PLATFORM) \
++ || defined(HAVE_DRM_PLATFORM) \
++ || defined(HAVE_MIR_PLATFORM)
+ __DRIbuffer *dri_buffers[__DRI_BUFFER_COUNT];
+ struct {
+ #ifdef HAVE_WAYLAND_PLATFORM
+@@ -204,6 +215,10 @@
+ /* EGL-owned buffers */
+ __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
+ #endif
++
++#ifdef HAVE_MIR_PLATFORM
++ MirMesaEGLNativeSurface *mir_surf;
++#endif
+ };
+
+
+@@ -265,6 +280,9 @@
+ EGLBoolean
+ dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
+
++EGLBoolean
++dri2_initialize_mir(_EGLDriver *drv, _EGLDisplay *disp);
++
+ char *
+ dri2_get_driver_for_fd(int fd);
+ char *
+Index: mesa/src/egl/drivers/dri2/platform_mir.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mesa/src/egl/drivers/dri2/platform_mir.c 2013-08-02 13:52:39.897145977 +1000
+@@ -0,0 +1,349 @@
++/*
++ * Copyright © 2012 Canonical, 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 (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.
++ *
++ * Authors:
++ * Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
++ */
++
++#include <mir_toolkit/mesa/native_display.h>
++
++#include "egl_dri2.h"
++
++#include <stdlib.h>
++#include <string.h>
++
++static __DRIbuffer *
++dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
++ int *width, int *height,
++ unsigned int *attachments, int count,
++ int *out_count, void *loaderPrivate)
++{
++ struct dri2_egl_surface *dri2_surf = loaderPrivate;
++ struct dri2_egl_display *dri2_dpy =
++ dri2_egl_display(dri2_surf->base.Resource.Display);
++ int i;
++
++ dri2_surf->buffer_count = 0;
++ for (i = 0; i < 2*count; i+=2) {
++ assert(attachments[i] < __DRI_BUFFER_COUNT);
++ assert(dri2_surf->buffer_count < 5);
++
++ if (dri2_surf->dri_buffers[attachments[i]] == NULL) {
++ /* Our frame callback must keep these buffers valid */
++ assert(attachments[i] != __DRI_BUFFER_FRONT_LEFT);
++ assert(attachments[i] != __DRI_BUFFER_BACK_LEFT);
++
++ dri2_surf->dri_buffers[attachments[i]] =
++ dri2_dpy->dri2->allocateBuffer(dri2_dpy->dri_screen,
++ attachments[i], attachments[i+1],
++ dri2_surf->base.Width, dri2_surf->base.Height);
++
++ if (!dri2_surf->dri_buffers[attachments[i]])
++ continue;
++ }
++
++ memcpy(&dri2_surf->buffers[dri2_surf->buffer_count],
++ dri2_surf->dri_buffers[attachments[i]],
++ sizeof(__DRIbuffer));
++
++ dri2_surf->buffer_count++;
++ }
++
++ assert(dri2_surf->base.Type == EGL_PIXMAP_BIT ||
++ dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]);
++
++ *out_count = dri2_surf->buffer_count;
++ if (dri2_surf->buffer_count == 0)
++ return NULL;
++
++ *width = dri2_surf->base.Width;
++ *height = dri2_surf->base.Height;
++
++ return dri2_surf->buffers;
++}
++
++static __DRIbuffer *
++dri2_get_buffers(__DRIdrawable * driDrawable,
++ int *width, int *height,
++ unsigned int *attachments, int count,
++ int *out_count, void *loaderPrivate)
++{
++ unsigned int *attachments_with_format;
++ __DRIbuffer *buffer;
++ const unsigned int format = 32;
++ int i;
++
++ attachments_with_format = calloc(count * 2, sizeof(unsigned int));
++ if (!attachments_with_format) {
++ *out_count = 0;
++ return NULL;
++ }
++
++ for (i = 0; i < count; ++i) {
++ attachments_with_format[2*i] = attachments[i];
++ attachments_with_format[2*i + 1] = format;
++ }
++
++ buffer =
++ dri2_get_buffers_with_format(driDrawable,
++ width, height,
++ attachments_with_format, count,
++ out_count, loaderPrivate);
++
++ free(attachments_with_format);
++
++ return buffer;
++}
++
++
++static void
++dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
++{
++ (void) driDrawable;
++
++ /* FIXME: Does EGL support front buffer rendering at all? */
++
++#if 0
++ struct dri2_egl_surface *dri2_surf = loaderPrivate;
++
++ dri2WaitGL(dri2_surf);
++#else
++ (void) loaderPrivate;
++#endif
++}
++
++static EGLBoolean
++mir_advance_colour_buffer(struct dri2_egl_surface *surf)
++{
++ MirBufferPackage buffer_package;
++ if(!surf->mir_surf->surface_advance_buffer(surf->mir_surf, &buffer_package))
++ return EGL_FALSE;
++
++ /* We expect no data items, and (for the moment) one PRIME fd */
++ assert(buffer_package.data_items == 0);
++ assert(buffer_package.fd_items == 1);
++
++ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->name = 0;
++ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->fd = buffer_package.fd[0];
++ surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->pitch = buffer_package.stride;
++ return EGL_TRUE;
++}
++
++/**
++ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
++ */
++static _EGLSurface *
++dri2_create_mir_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
++ _EGLConfig *conf, EGLNativeWindowType window,
++ const EGLint *attrib_list)
++{
++ int rc;
++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++ struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
++ struct dri2_egl_surface *dri2_surf;
++ MirSurfaceParameters surf_params;
++
++ (void) drv;
++
++ dri2_surf = calloc(1, sizeof *dri2_surf);
++ if (!dri2_surf) {
++ _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
++ return NULL;
++ }
++
++ if (!_eglInitSurface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf, attrib_list))
++ goto cleanup_surf;
++
++ dri2_surf->mir_surf = window;
++ if (!dri2_surf->mir_surf->surface_get_parameters(dri2_surf->mir_surf, &surf_params))
++ goto cleanup_surf;
++
++ dri2_surf->base.Width = surf_params.width;
++ dri2_surf->base.Height = surf_params.height;
++
++ dri2_surf->dri_buffers[__DRI_BUFFER_FRONT_LEFT] =
++ calloc(sizeof(*dri2_surf->dri_buffers[0]), 1);
++ dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT] =
++ calloc(sizeof(*dri2_surf->dri_buffers[0]), 1);
++
++ dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->attachment =
++ __DRI_BUFFER_BACK_LEFT;
++ /* We only do ARGB 8888 for the moment */
++ dri2_surf->dri_buffers[__DRI_BUFFER_BACK_LEFT]->cpp = 4;
++
++ if(!mir_advance_colour_buffer(dri2_surf))
++ goto cleanup_surf;
++
++ dri2_surf->dri_drawable =
++ (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
++ dri2_conf->dri_double_config,
++ dri2_surf);
++
++ if (dri2_surf->dri_drawable == NULL) {
++ _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
++ }
++
++ return &dri2_surf->base;
++
++cleanup_surf:
++ free(dri2_surf);
++ return NULL;
++}
++
++static EGLBoolean
++dri2_destroy_mir_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
++{
++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
++ int i;
++
++ (void) drv;
++
++ if (!_eglPutSurface(surf))
++ return EGL_TRUE;
++
++ (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
++
++ for (i = 0; i < __DRI_BUFFER_COUNT; ++i) {
++ if (dri2_surf->dri_buffers[i] && !((i == __DRI_BUFFER_FRONT_LEFT) ||
++ (i == __DRI_BUFFER_BACK_LEFT))) {
++ dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
++ dri2_surf->dri_buffers[i]);
++ }
++ }
++
++ free(surf);
++
++ return EGL_TRUE;
++}
++
++/**
++ * Called via eglSwapInterval(), drv->API.SwapInterval().
++ */
++static EGLBoolean
++dri2_set_swap_interval(_EGLDriver *drv, _EGLDisplay *disp,
++ _EGLSurface *surf, EGLint interval)
++{
++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
++ if(!dri2_surf->mir_surf->surface_set_swapinterval(dri2_surf->mir_surf, interval))
++ return EGL_FALSE;
++ return EGL_TRUE;
++}
++
++/**
++ * Called via eglSwapBuffers(), drv->API.SwapBuffers().
++ */
++static EGLBoolean
++dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
++{
++ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
++ struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
++
++ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
++
++ int rc = mir_advance_colour_buffer(dri2_surf);
++
++ (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable);
++
++ return rc;
++}
++
++static int
++dri2_mir_authenticate(_EGLDisplay *disp, uint32_t id)
++{
++ return 0;
++}
++
++EGLBoolean
++dri2_initialize_mir(_EGLDriver *drv, _EGLDisplay *disp)
++{
++ struct dri2_egl_display *dri2_dpy;
++ MirPlatformPackage platform;
++ const __DRIconfig *config;
++ static const unsigned int argb_masks[4] =
++ { 0xff0000, 0xff00, 0xff, 0xff000000 };
++ uint32_t types;
++ int i;
++
++ drv->API.CreateWindowSurface = dri2_create_mir_window_surface;
++ drv->API.DestroySurface = dri2_destroy_mir_surface;
++ drv->API.SwapBuffers = dri2_swap_buffers;
++ drv->API.SwapInterval = dri2_set_swap_interval;
++/* drv->API.CreatePixmapSurface = dri2_create_pixmap_surface;
++ drv->API.CreatePbufferSurface = dri2_create_pbuffer_surface;
++ drv->API.CopyBuffers = dri2_copy_buffers;
++ drv->API.CreateImageKHR = dri2_x11_create_image_khr;
++*/
++
++ dri2_dpy = calloc(1, sizeof *dri2_dpy);
++ if (!dri2_dpy)
++ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
++
++ disp->DriverData = (void *) dri2_dpy;
++ dri2_dpy->mir_disp = disp->PlatformDisplay;
++ dri2_dpy->mir_disp->display_get_platform(dri2_dpy->mir_disp, &platform);
++ dri2_dpy->fd = platform.fd[0];
++ dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
++ dri2_dpy->device_name = dri2_get_device_name_for_fd(dri2_dpy->fd);
++
++ if (dri2_dpy->driver_name == NULL ||
++ dri2_dpy->device_name == NULL)
++ goto cleanup_dpy;
++
++ if (!dri2_load_driver(disp))
++ goto cleanup_dpy;
++
++ dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
++ dri2_dpy->dri2_loader_extension.base.version = 4;
++ dri2_dpy->dri2_loader_extension.getBuffers = dri2_get_buffers;
++ dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
++ dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
++ dri2_get_buffers_with_format;
++
++ dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
++ dri2_dpy->extensions[1] = &image_lookup_extension.base;
++ dri2_dpy->extensions[2] = &use_invalidate.base;
++ dri2_dpy->extensions[3] = NULL;
++
++ if (!dri2_create_screen(disp))
++ goto cleanup_dpy;
++
++ types = EGL_WINDOW_BIT;
++ for (i = 0; dri2_dpy->driver_configs[i]; i++) {
++ config = dri2_dpy->driver_configs[i];
++ dri2_add_config(disp, config, i + 1, 0, types, NULL, argb_masks);
++ }
++
++ dri2_dpy->authenticate = dri2_mir_authenticate;
++
++ disp->VersionMajor = 1;
++ disp->VersionMinor = 4;
++
++ return EGL_TRUE;
++
++ cleanup_dpy:
++ free(dri2_dpy);
++
++ return EGL_FALSE;
++}
+Index: mesa/src/egl/main/Makefile.am
+===================================================================
+--- mesa.orig/src/egl/main/Makefile.am 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/main/Makefile.am 2013-08-02 13:52:39.897145977 +1000
+@@ -103,6 +103,11 @@
+ AM_CFLAGS += -DHAVE_NULL_PLATFORM
+ endif
+
++if HAVE_EGL_PLATFORM_MIR
++AM_CFLAGS += -DHAVE_MIR_PLATFORM
++AM_CFLAGS += $(MIR_CFLAGS)
++endif
++
+ if HAVE_EGL_DRIVER_GLX
+ AM_CFLAGS += -D_EGL_BUILT_IN_DRIVER_GLX
+ libEGL_la_LIBADD += ../drivers/glx/libegl_glx.la
+Index: mesa/src/egl/main/egldisplay.c
+===================================================================
+--- mesa.orig/src/egl/main/egldisplay.c 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/main/egldisplay.c 2013-08-02 13:52:39.897145977 +1000
+@@ -59,7 +59,10 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #endif
+-
++#ifdef HAVE_MIR_PLATFORM
++#include <dlfcn.h>
++#include <mir_toolkit/mesa/native_display.h>
++#endif
+
+ /**
+ * Map --with-egl-platforms names to platform types.
+@@ -74,7 +77,8 @@
+ { _EGL_PLATFORM_DRM, "drm" },
+ { _EGL_PLATFORM_FBDEV, "fbdev" },
+ { _EGL_PLATFORM_NULL, "null" },
+- { _EGL_PLATFORM_ANDROID, "android" }
++ { _EGL_PLATFORM_ANDROID, "android" },
++ { _EGL_PLATFORM_MIR, "mir" },
+ };
+
+
+@@ -134,6 +138,47 @@
+ #endif
+ }
+
++#ifdef HAVE_MIR_PLATFORM
++static EGLBoolean
++_mir_display_is_valid(EGLNativeDisplayType nativeDisplay)
++{
++ typedef int (*MirEGLNativeDisplayIsValidFunc)(MirMesaEGLNativeDisplay*);
++
++ void *lib;
++ MirEGLNativeDisplayIsValidFunc general_check;
++ MirEGLNativeDisplayIsValidFunc client_check;
++ MirEGLNativeDisplayIsValidFunc server_check;
++ EGLBoolean is_valid = EGL_FALSE;
++
++ lib = dlopen(NULL, RTLD_LAZY);
++ if (lib == NULL)
++ return EGL_FALSE;
++
++ general_check = (MirEGLNativeDisplayIsValidFunc) dlsym(lib, "mir_egl_mesa_display_is_valid");
++ client_check = (MirEGLNativeDisplayIsValidFunc) dlsym(lib, "mir_client_mesa_egl_native_display_is_valid");
++ server_check = (MirEGLNativeDisplayIsValidFunc) dlsym(lib, "mir_server_mesa_egl_native_display_is_valid");
++
++ if (general_check != NULL &&
++ general_check((MirMesaEGLNativeDisplay *)nativeDisplay))
++ {
++ is_valid = EGL_TRUE;
++ }
++ else if (client_check != NULL &&
++ client_check((MirMesaEGLNativeDisplay *)nativeDisplay))
++ {
++ is_valid = EGL_TRUE;
++ }
++ else if (server_check != NULL &&
++ server_check((MirMesaEGLNativeDisplay *)nativeDisplay))
++ {
++ is_valid = EGL_TRUE;
++ }
++
++ dlclose(lib);
++
++ return is_valid;
++}
++#endif
+
+ /**
+ * Try detecting native platform with the help of native display characteristcs.
+@@ -154,6 +199,11 @@
+ return _EGL_PLATFORM_FBDEV;
+ #endif
+
++#ifdef HAVE_MIR_PLATFORM
++ if (_mir_display_is_valid(nativeDisplay))
++ return _EGL_PLATFORM_MIR;
++#endif
++
+ if (_eglPointerIsDereferencable(nativeDisplay)) {
+ void *first_pointer = *(void **) nativeDisplay;
+
+@@ -188,7 +238,7 @@
+ _EGLPlatformType
+ _eglGetNativePlatform(EGLNativeDisplayType nativeDisplay)
+ {
+- static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
++ _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
+ char *detection_method = NULL;
+
+ if (native_platform == _EGL_INVALID_PLATFORM) {
+Index: mesa/src/egl/main/egldisplay.h
+===================================================================
+--- mesa.orig/src/egl/main/egldisplay.h 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/main/egldisplay.h 2013-08-02 13:52:39.897145977 +1000
+@@ -46,6 +46,7 @@
+ _EGL_PLATFORM_FBDEV,
+ _EGL_PLATFORM_NULL,
+ _EGL_PLATFORM_ANDROID,
++ _EGL_PLATFORM_MIR,
+
+ _EGL_NUM_PLATFORMS,
+ _EGL_INVALID_PLATFORM = -1
+Index: mesa/src/egl/main/egldriver.c
+===================================================================
+--- mesa.orig/src/egl/main/egldriver.c 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/egl/main/egldriver.c 2013-08-02 13:52:39.897145977 +1000
+@@ -57,7 +57,7 @@
+ char *Path;
+ _EGLMain_t BuiltIn;
+ void *Handle;
+- _EGLDriver *Driver;
++ _EGLDriver *Driver[_EGL_NUM_PLATFORMS];
+ } _EGLModule;
+
+ static _EGL_DECLARE_MUTEX(_eglModuleMutex);
+@@ -134,7 +134,6 @@
+
+ #endif
+
+-
+ /**
+ * Open the named driver and find its bootstrap function: _eglMain().
+ */
+@@ -147,8 +146,12 @@
+
+ assert(driverPath);
+
+- _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+- lib = open_library(driverPath);
++ if (*handle) {
++ lib = *handle;
++ } else {
++ _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
++ lib = open_library(driverPath);
++ }
+
+ #if defined(_EGL_OS_WINDOWS)
+ /* XXX untested */
+@@ -194,13 +197,13 @@
+ * Load a module and create the driver object.
+ */
+ static EGLBoolean
+-_eglLoadModule(_EGLModule *mod)
++_eglLoadModule(_EGLModule *mod, _EGLPlatformType plat)
+ {
+ _EGLMain_t mainFunc;
+- lib_handle lib;
++ lib_handle lib = (lib_handle) mod->Handle;
+ _EGLDriver *drv;
+
+- if (mod->Driver)
++ if (mod->Driver[plat])
+ return EGL_TRUE;
+
+ if (mod->BuiltIn) {
+@@ -226,7 +229,7 @@
+ }
+
+ mod->Handle = (void *) lib;
+- mod->Driver = drv;
++ mod->Driver[plat] = drv;
+
+ return EGL_TRUE;
+ }
+@@ -240,8 +243,10 @@
+ {
+ #if defined(_EGL_OS_UNIX)
+ /* destroy the driver */
+- if (mod->Driver && mod->Driver->Unload)
+- mod->Driver->Unload(mod->Driver);
++ for (int plat = 0; plat < _EGL_NUM_PLATFORMS; ++plat) {
++ if (mod->Driver[plat] && mod->Driver[plat]->Unload)
++ mod->Driver[plat]->Unload(mod->Driver[plat]);
++ }
+
+ /*
+ * XXX At this point (atexit), the module might be the last reference to
+@@ -255,7 +260,9 @@
+ /* XXX Windows unloads DLLs before atexit */
+ #endif
+
+- mod->Driver = NULL;
++ for (int plat = 0; plat < _EGL_NUM_PLATFORMS; ++plat) {
++ mod->Driver[plat] = NULL;
++ }
+ mod->Handle = NULL;
+ }
+
+@@ -599,17 +606,17 @@
+ while (i < _eglModules->Size) {
+ _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
+
+- if (!_eglLoadModule(mod)) {
++ if (!_eglLoadModule(mod, dpy->Platform)) {
+ /* remove invalid modules */
+ _eglEraseArray(_eglModules, i, _eglFreeModule);
+ continue;
+ }
+
+- if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
+- drv = mod->Driver;
++ drv = mod->Driver[dpy->Platform];
++ if (drv->API.Initialize(drv, dpy))
+ break;
+- }
+ else {
++ drv = NULL;
+ i++;
+ }
+ }
+@@ -661,7 +668,6 @@
+ _eglGetDriverProc(const char *procname)
+ {
+ EGLint i;
+- _EGLProc proc = NULL;
+
+ if (!_eglModules) {
+ /* load the driver for the default display */
+@@ -673,15 +679,18 @@
+
+ for (i = 0; i < _eglModules->Size; i++) {
+ _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
++ _EGLProc proc;
+
+- if (!mod->Driver)
+- break;
+- proc = mod->Driver->API.GetProcAddress(mod->Driver, procname);
+- if (proc)
+- break;
++ for (_EGLPlatformType plat = 0; plat < _EGL_NUM_PLATFORMS; ++plat) {
++ if (!mod->Driver[plat])
++ continue;
++ proc = mod->Driver[plat]->API.GetProcAddress(mod->Driver[plat], procname);
++ if (proc)
++ return proc;
++ }
+ }
+
+- return proc;
++ return NULL;
+ }
+
+
+Index: mesa/src/gallium/drivers/nouveau/nouveau_screen.c
+===================================================================
+--- mesa.orig/src/gallium/drivers/nouveau/nouveau_screen.c 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/gallium/drivers/nouveau/nouveau_screen.c 2013-08-02 13:52:39.897145977 +1000
+@@ -14,6 +14,7 @@
+ #include <errno.h>
+ #include <stdlib.h>
+
++#include <xf86drm.h>
+ #include <libdrm/nouveau_drm.h>
+
+ #include "nouveau_winsys.h"
+@@ -86,7 +87,18 @@
+ struct nouveau_bo *bo = 0;
+ int ret;
+
+- ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
++ if (whandle->type != DRM_API_HANDLE_TYPE_SHARED &&
++ whandle->type != DRM_API_HANDLE_TYPE_FD) {
++ debug_printf("%s: attempt to import unsupported handle type %d\n",
++ __FUNCTION__, whandle->type);
++ return NULL;
++ }
++
++ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
++ ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
++ else
++ ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo);
++
+ if (ret) {
+ debug_printf("%s: ref name 0x%08x failed with %d\n",
+ __FUNCTION__, whandle->handle, ret);
+@@ -111,6 +123,8 @@
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = bo->handle;
+ return TRUE;
++ } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
++ return nouveau_bo_set_prime(bo, (int *)&whandle->handle) == 0;
+ } else {
+ return FALSE;
+ }
+Index: mesa/src/gallium/include/state_tracker/drm_driver.h
+===================================================================
+--- mesa.orig/src/gallium/include/state_tracker/drm_driver.h 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/gallium/include/state_tracker/drm_driver.h 2013-08-02 13:52:39.897145977 +1000
+@@ -10,6 +10,8 @@
+
+ #define DRM_API_HANDLE_TYPE_SHARED 0
+ #define DRM_API_HANDLE_TYPE_KMS 1
++#define DRM_API_HANDLE_TYPE_FD 2
++
+
+ /**
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
+@@ -17,9 +19,10 @@
+ struct winsys_handle
+ {
+ /**
+- * Unused for texture_from_handle, always
+- * DRM_API_HANDLE_TYPE_SHARED. Input to texture_get_handle,
+- * use TEXTURE_USAGE to select handle for kms or ipc.
++ * Input for texture_from_handle, valid values are
++ * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD.
++ * Input to texture_get_handle,
++ * to select handle for kms, flink, or prime.
+ */
+ unsigned type;
+ /**
+Index: mesa/src/gallium/state_trackers/dri/drm/dri2.c
+===================================================================
+--- mesa.orig/src/gallium/state_trackers/dri/drm/dri2.c 2013-08-02 13:52:39.909145976 +1000
++++ mesa/src/gallium/state_trackers/dri/drm/dri2.c 2013-08-02 13:52:39.901145976 +1000
+@@ -231,7 +231,13 @@
+
+ templ.format = format;
+ templ.bind = bind;
+- whandle.handle = buf->name;
++ if (buf->fd != 0) {
++ whandle.type = DRM_API_HANDLE_TYPE_FD;
++ whandle.handle = buf->fd;
++ } else {
++ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
++ whandle.handle = buf->name;
++ }
+ whandle.stride = buf->pitch;
+
+ drawable->textures[statt] =
+@@ -452,14 +458,14 @@
+ }
+
+ static __DRIimage *
+-dri2_create_image_from_name(__DRIscreen *_screen,
+- int width, int height, int format,
+- int name, int pitch, void *loaderPrivate)
++dri2_create_image_from_winsys(__DRIscreen *_screen,
++ int width, int height, int format,
++ struct winsys_handle *whandle, int pitch,
++ void *loaderPrivate)
+ {
+ struct dri_screen *screen = dri_screen(_screen);
+ __DRIimage *img;
+ struct pipe_resource templ;
+- struct winsys_handle whandle;
+ unsigned tex_usage;
+ enum pipe_format pf;
+
+@@ -499,12 +505,10 @@
+ templ.depth0 = 1;
+ templ.array_size = 1;
+
+- memset(&whandle, 0, sizeof(whandle));
+- whandle.handle = name;
+- whandle.stride = pitch * util_format_get_blocksize(pf);
++ whandle->stride = pitch * util_format_get_blocksize(pf);
+
+ img->texture = screen->base.screen->resource_from_handle(screen->base.screen,
+- &templ, &whandle);
++ &templ, whandle);
+ if (!img->texture) {
+ FREE(img);
+ return NULL;
+@@ -519,6 +523,39 @@
+ }
+
+ static __DRIimage *
++dri2_create_image_from_name(__DRIscreen *_screen,
++ int width, int height, int format,
++ int name, int pitch, void *loaderPrivate)
++{
++ struct winsys_handle whandle;
++
++ memset(&whandle, 0, sizeof(whandle));
++ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
++ whandle.handle = name;
++
++ return dri2_create_image_from_winsys(_screen, width, height, format,
++ &whandle, pitch, loaderPrivate);
++}
++
++static __DRIimage *
++dri2_create_image_from_fd(__DRIscreen *_screen,
++ int width, int height, int format,
++ int fd, int pitch, void *loaderPrivate)
++{
++ struct winsys_handle whandle;
++
++ if (fd < 0)
++ return NULL;
++
++ memset(&whandle, 0, sizeof(whandle));
Reply to: