DRM solution for Accelerated Compositing 51/12351/4
authorKondapally Kalyan <kalyan.kondapally@intel.com>
Mon, 14 Oct 2013 21:49:43 +0000 (14:49 -0700)
committerJoone Hur <joone.hur@intel.com>
Thu, 21 Nov 2013 06:50:07 +0000 (22:50 -0800)
This solution allows to use GPU memory directly in order to share a platform surface
through Intel DRM APIs. All the authentications are done through Wayland and the WebProcess
renders content to the DRM buffer. With the Wayland nested Compositor, we are able to create
an EGL image and a texture for the DRM handle on the UIProcess.

We are going to use single buffered surface (i.e similar to Pixmap surface), which allows to
render WebGL and Canvas static content.
Regarding Accelerated Compositing, the UIProcess does not need to upload textures in the
UIProcess.

This patch includes a fix(Call SharedPlatformSurfaceTizen::querySurface instead of
EGLHelper::querySurface) written by Joone Hur.

Change-Id: I5b83f3d74bc7a00f7455605359aef74ef8521131

19 files changed:
Source/WebCore/PlatformTizen.cmake
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/efl/tizen/SharedPlatformSurfaceTizen.cpp
Source/WebCore/platform/graphics/opengl/GLPlatformSurface.cpp
Source/WebCore/platform/graphics/opengl/GLPlatformSurface.h
Source/WebCore/platform/graphics/surfaces/egl/EGLSurface.cpp
Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.cpp
Source/WebCore/platform/graphics/surfaces/wayland/WaylandDisplay.h
Source/WebCore/platform/graphics/surfaces/wayland/WaylandHelper.h
Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.h [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.h [new file with mode: 0644]
Source/cmake/FindWayland.cmake
Source/cmake/OptionsTizen.cmake

index cf4b9ca..30511ab 100755 (executable)
@@ -232,12 +232,20 @@ IF (WTF_USE_ACCELERATED_COMPOSITING AND ENABLE_WEBKIT2)
             platform/graphics/efl/tizen/AcceleratedPlatformLayer.cpp
             platform/graphics/surfaces/egl/EGLWaylandSurface.cpp
             platform/graphics/surfaces/wayland/PlatformTextureWayland.cpp
+            platform/graphics/surfaces/wayland/WaylandBufferManager.cpp
             platform/graphics/surfaces/wayland/WaylandCompositor.cpp
             platform/graphics/surfaces/wayland/WaylandDisplay.cpp
+            platform/graphics/surfaces/wayland/WaylandLockSurface.cpp
+            platform/graphics/surfaces/wayland/Wayland-drm-protocol.cpp
             platform/graphics/surfaces/wayland/WaylandSurface.cpp
             platform/graphics/surfaces/wayland/GraphicsSurfaceWayland.cpp
             platform/graphics/surfaces/tizen/SharedVideoPlatformSurfaceTizenWayland.cpp
         )
+        IF (WTF_USE_MESA)
+            LIST(APPEND WebCore_SOURCES
+            platform/graphics/surfaces/wayland/WaylandMesaBufferManager.cpp
+        )
+        ENDIF()
     ENDIF()
 ENDIF()
 
index d8a2927..e9859af 100755 (executable)
@@ -55,7 +55,6 @@
 #if ENABLE(TIZEN_CANVAS_CAIRO_GLES_RENDERING) || ENABLE(TIZEN_CANVAS_SURFACE_LOCKING)
 #include "EGLHelper.h"
 #endif
-
 using namespace std;
 
 namespace WebCore {
@@ -302,13 +301,17 @@ bool ImageBuffer::unlockSurface() const
 PassRefPtr<cairo_surface_t> ImageBuffer::querySurface() const
 {
     int* bitmapPtr;
+    int pitch = 0;
+#if PLATFORM(WAYLAND)
+    bool ret = m_offScreenSurface->querySurface(&bitmapPtr);
+    pitch = 4 * m_size.width();
+#else
     if (!EGLHelper::querySurface(m_offScreenSurface->drawable(), EGL_BITMAP_POINTER_KHR, (EGLint*)&bitmapPtr))
         return 0;
 
-    int pitch = 0;
     if (!EGLHelper::querySurface(m_offScreenSurface->drawable(), EGL_BITMAP_PITCH_KHR, static_cast<EGLint*>(&pitch)))
         return 0;
-
+#endif
     return adoptRef(cairo_image_surface_create_for_data(reinterpret_cast<unsigned char*>(bitmapPtr), CAIRO_FORMAT_ARGB32, m_size.width(), m_size.height(), pitch));
 }
 #endif
index 35c42dd..7911fe5 100755 (executable)
@@ -96,10 +96,13 @@ bool SharedPlatformSurfaceTizen::supportsLockSurfaceExtension()
         return supportLockSurfaceExt;
 
     initialized = true;
-#if PLATFORM(WAYLAND)
-    needsLockSurfaceWorkAround = EGLHelper::isVendor("mesa");
-#endif
+
+#if PLATFORM(WAYLAND) && USE(MESA)
+    supportLockSurfaceExt = true;
+#else
     supportLockSurfaceExt = GLPlatformContext::supportsEGLExtension(EGLHelper::currentDisplay(), "EGL_KHR_lock_surface");
+#endif
+
     return supportLockSurfaceExt;
 }
 
@@ -115,6 +118,13 @@ SharedPlatformSurfaceTizen::~SharedPlatformSurfaceTizen()
     if (!m_offScreenSurface)
         return;
 
+#if PLATFORM(WAYLAND)
+    if (!m_offScreenContext) {
+        m_offScreenSurface->destroy();
+        return;
+    }
+#endif
+
     GLPlatformContext* previousContext = GLPlatformContext::getCurrent();
     GLPlatformSurface* previousSurface = GLPlatformSurface::getCurrent();
     if (previousSurface == m_offScreenSurface.get())
@@ -139,7 +149,8 @@ bool SharedPlatformSurfaceTizen::initialize(GLPlatformSurface::SurfaceAttributes
     if (m_size.isEmpty())
         return false;
 
-    if ((attributes & GLPlatformSurface::Lockable) && !supportsLockSurfaceExtension())
+    GLPlatformSurface::SurfaceAttributes surfaceAttributes = attributes;
+    if ((surfaceAttributes & GLPlatformSurface::Lockable) && !supportsLockSurfaceExtension())
         return false;
 
     m_offScreenSurface = GLPlatformSurface::createOffScreenSurface(attributes, m_size);
@@ -147,6 +158,11 @@ bool SharedPlatformSurfaceTizen::initialize(GLPlatformSurface::SurfaceAttributes
     if (!m_offScreenSurface)
         return false;
 
+#if PLATFORM(WAYLAND)
+    if (surfaceAttributes & GLPlatformSurface::Lockable)
+        return true;
+#endif
+
     PixmapContextPool& pixmapContextPool = PixmapContextPool::getInstance();
     m_offScreenContext = pixmapContextPool.getContext(m_offScreenSurface.get());
 
@@ -156,9 +172,6 @@ bool SharedPlatformSurfaceTizen::initialize(GLPlatformSurface::SurfaceAttributes
         return false;
     }
 
-    if (needsLockSurfaceWorkAround)
-        makeContextCurrent();
-
     return true;
 }
 
@@ -175,33 +188,28 @@ bool SharedPlatformSurfaceTizen::makeContextCurrent()
 
 bool SharedPlatformSurfaceTizen::lockSurface()
 {
-    static bool needsMakeCurrent = !(EGLHelper::isVendor("imagination") || EGLHelper::isVendor("mesa") || EGLHelper::isVendor("arm"));
+    static bool needsMakeCurrent = !(EGLHelper::isVendor("imagination") || EGLHelper::isVendor("arm"));
     if (needsMakeCurrent)
         makeContextCurrent();
-#if PLATFORM(WAYLAND)
-    else if (needsLockSurfaceWorkAround)
-        m_offScreenContext->releaseCurrent();
-#endif
+
     return m_offScreenSurface->lockSurface();
 }
 
 bool SharedPlatformSurfaceTizen::unlockSurface()
 {
-    bool value = m_offScreenSurface->unlockSurface();
-#if PLATFORM(WAYLAND)
-    if (needsLockSurfaceWorkAround)
-        makeContextCurrent();
-
-    if (m_offScreenSurface->attributes() & GLPlatformSurface::DoubleBuffered)
-        m_offScreenSurface->swapBuffers();
-#endif
-    return value;
+    return m_offScreenSurface->unlockSurface();
 }
 
 bool SharedPlatformSurfaceTizen::querySurface(int** value)
 {
     int* value_local;
+
+#if PLATFORM(WAYLAND)
+    bool ret = m_offScreenSurface->querySurface(&value_local);
+#else
     bool ret = EGLHelper::querySurface(m_offScreenSurface->drawable(), EGL_BITMAP_POINTER_KHR, (EGLint*)&value_local);
+#endif
+
     *value = value_local;
 
     return ret;
index 016ac87..7c2b771 100644 (file)
@@ -47,14 +47,27 @@ static GLPlatformSurface* m_currentDrawable = 0;
 PassOwnPtr<GLPlatformSurface> GLPlatformSurface::createOffScreenSurface(SurfaceAttributes attributes, const IntSize& size)
 {
     OwnPtr<GLPlatformSurface> surface;
+
 #if USE(GLX)
     surface = adoptPtr(new GLXOffScreenSurface(attributes));
 #else
     surface = EGLOffScreenSurface::createOffScreenSurface(size, attributes);
 #endif
 
+#if PLATFORM(X11)
     if (surface && surface->drawable())
         return surface.release();
+#elif PLATFORM(WAYLAND)
+    if (surface) {
+        if (attributes & GLPlatformSurface::Lockable) {
+            if (surface->handle())
+                return surface.release();
+        } else {
+            if (surface->drawable())
+                return surface.release();
+        }
+    }
+#endif
 
     return nullptr;
 }
@@ -152,6 +165,11 @@ bool GLPlatformSurface::unlockSurface()
     return false;
 }
 
+bool GLPlatformSurface::querySurface(int**)
+{
+    return false;
+}
+
 }
 
 #endif
index 7218ffb..9beacc1 100644 (file)
@@ -92,6 +92,7 @@ public:
 
     virtual bool lockSurface();
     virtual bool unlockSurface();
+    virtual bool querySurface(int**);
 
     static GLPlatformSurface* getCurrent();
 
index ec2952c..090d1ef 100644 (file)
 #include "EGLXSurface.h"
 #elif PLATFORM(WAYLAND)
 #include "EGLWaylandSurface.h"
+#include "WaylandLockSurface.h"
 #endif
 
 #include <wtf/UnusedParam.h>
+
 namespace WebCore {
 
 PassOwnPtr<GLPlatformSurface> EGLTransportSurface::createTransportSurface(const IntSize& size, SurfaceAttributes attributes)
@@ -101,12 +103,19 @@ PassOwnPtr<GLPlatformSurface> EGLOffScreenSurface::createOffScreenSurface(const
 {
     EGLHelper::resolveEGLBindings();
     OwnPtr<GLPlatformSurface> surface;
+
 #if PLATFORM(X11)
     surface = adoptPtr(new EGLPixmapSurface(size, attributes));
 #elif PLATFORM(WAYLAND)
     SurfaceAttributes surfaceAttributes = attributes;
-    surfaceAttributes |= GLPlatformSurface::DoubleBuffered;
-    surface = adoptPtr(new EGLWindowSurface(size, surfaceAttributes));
+    if (!(attributes & GLPlatformSurface::Lockable)) {
+        surfaceAttributes |= GLPlatformSurface::DoubleBuffered;
+        surface = adoptPtr(new EGLWindowSurface(size, surfaceAttributes));
+    } else {
+        surface = adoptPtr(new WaylandLockSurface(size, surfaceAttributes));
+        if (surface && surface->handle())
+            return surface.release();
+    }
 #else
     UNUSED_PARAM(attributes);
 #endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.cpp
new file mode 100644 (file)
index 0000000..59364d3
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include "Wayland-drm-protocol.h"
+
+//#include "WaylandHelper.h"
+
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_buffer_interface;
+extern const struct wl_interface wl_buffer_interface;
+
+static const struct wl_interface *types[] = {
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       &wl_buffer_interface,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+       NULL,
+};
+
+static const struct wl_message wl_drm_requests[] = {
+       { "authenticate", "u", types + 0 },
+       { "create_buffer", "nuiiuu", types + 1 },
+       { "create_planar_buffer", "nuiiuiiiiii", types + 7 },
+       { "create_prime_buffer", "nhiiuiiiiii", types + 18 },
+};
+
+static const struct wl_message wl_drm_events[] = {
+       { "device", "s", types + 0 },
+       { "format", "u", types + 0 },
+       { "authenticated", "", types + 0 },
+       { "capabilities", "u", types + 0 },
+};
+
+WL_EXPORT const struct wl_interface wl_drm_interface = {
+       "wl_drm", 2,
+       4, wl_drm_requests,
+       4, wl_drm_events,
+};
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.h b/Source/WebCore/platform/graphics/surfaces/wayland/Wayland-drm-protocol.h
new file mode 100644 (file)
index 0000000..46b6b6f
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2010-2011 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this
+ * software and its documentation for any purpose is hereby granted
+ * without fee, provided that\n the above copyright notice appear in
+ * all copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of
+ * the copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+
+#ifndef DRM_CLIENT_PROTOCOL_H
+#define DRM_CLIENT_PROTOCOL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include <wayland-client.h>
+#include <wayland-server.h>
+#include <wayland-util.h>
+
+//struct wl_client;
+//struct wl_resource;
+
+//struct wl_drm;
+
+extern const struct wl_interface wl_drm_interface;
+
+#ifndef WL_DRM_ERROR_ENUM
+#define WL_DRM_ERROR_ENUM
+enum wl_drm_error {
+    WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
+    WL_DRM_ERROR_INVALID_FORMAT = 1,
+    WL_DRM_ERROR_INVALID_NAME = 2,
+};
+#endif /* WL_DRM_ERROR_ENUM */
+
+#ifndef WL_DRM_FORMAT_ENUM
+#define WL_DRM_FORMAT_ENUM
+enum wl_drm_format {
+    WL_DRM_FORMAT_C8 = 0x20203843,
+    WL_DRM_FORMAT_RGB332 = 0x38424752,
+    WL_DRM_FORMAT_BGR233 = 0x38524742,
+    WL_DRM_FORMAT_XRGB4444 = 0x32315258,
+    WL_DRM_FORMAT_XBGR4444 = 0x32314258,
+    WL_DRM_FORMAT_RGBX4444 = 0x32315852,
+    WL_DRM_FORMAT_BGRX4444 = 0x32315842,
+    WL_DRM_FORMAT_ARGB4444 = 0x32315241,
+    WL_DRM_FORMAT_ABGR4444 = 0x32314241,
+    WL_DRM_FORMAT_RGBA4444 = 0x32314152,
+    WL_DRM_FORMAT_BGRA4444 = 0x32314142,
+    WL_DRM_FORMAT_XRGB1555 = 0x35315258,
+    WL_DRM_FORMAT_XBGR1555 = 0x35314258,
+    WL_DRM_FORMAT_RGBX5551 = 0x35315852,
+    WL_DRM_FORMAT_BGRX5551 = 0x35315842,
+    WL_DRM_FORMAT_ARGB1555 = 0x35315241,
+    WL_DRM_FORMAT_ABGR1555 = 0x35314241,
+    WL_DRM_FORMAT_RGBA5551 = 0x35314152,
+    WL_DRM_FORMAT_BGRA5551 = 0x35314142,
+    WL_DRM_FORMAT_RGB565 = 0x36314752,
+    WL_DRM_FORMAT_BGR565 = 0x36314742,
+    WL_DRM_FORMAT_RGB888 = 0x34324752,
+    WL_DRM_FORMAT_BGR888 = 0x34324742,
+    WL_DRM_FORMAT_XRGB8888 = 0x34325258,
+    WL_DRM_FORMAT_XBGR8888 = 0x34324258,
+    WL_DRM_FORMAT_RGBX8888 = 0x34325852,
+    WL_DRM_FORMAT_BGRX8888 = 0x34325842,
+    WL_DRM_FORMAT_ARGB8888 = 0x34325241,
+    WL_DRM_FORMAT_ABGR8888 = 0x34324241,
+    WL_DRM_FORMAT_RGBA8888 = 0x34324152,
+    WL_DRM_FORMAT_BGRA8888 = 0x34324142,
+    WL_DRM_FORMAT_XRGB2101010 = 0x30335258,
+    WL_DRM_FORMAT_XBGR2101010 = 0x30334258,
+    WL_DRM_FORMAT_RGBX1010102 = 0x30335852,
+    WL_DRM_FORMAT_BGRX1010102 = 0x30335842,
+    WL_DRM_FORMAT_ARGB2101010 = 0x30335241,
+    WL_DRM_FORMAT_ABGR2101010 = 0x30334241,
+    WL_DRM_FORMAT_RGBA1010102 = 0x30334152,
+    WL_DRM_FORMAT_BGRA1010102 = 0x30334142,
+    WL_DRM_FORMAT_YUYV = 0x56595559,
+    WL_DRM_FORMAT_YVYU = 0x55595659,
+    WL_DRM_FORMAT_UYVY = 0x59565955,
+    WL_DRM_FORMAT_VYUY = 0x59555956,
+    WL_DRM_FORMAT_AYUV = 0x56555941,
+    WL_DRM_FORMAT_NV12 = 0x3231564e,
+    WL_DRM_FORMAT_NV21 = 0x3132564e,
+    WL_DRM_FORMAT_NV16 = 0x3631564e,
+    WL_DRM_FORMAT_NV61 = 0x3136564e,
+    WL_DRM_FORMAT_YUV410 = 0x39565559,
+    WL_DRM_FORMAT_YVU410 = 0x39555659,
+    WL_DRM_FORMAT_YUV411 = 0x31315559,
+    WL_DRM_FORMAT_YVU411 = 0x31315659,
+    WL_DRM_FORMAT_YUV420 = 0x32315559,
+    WL_DRM_FORMAT_YVU420 = 0x32315659,
+    WL_DRM_FORMAT_YUV422 = 0x36315559,
+    WL_DRM_FORMAT_YVU422 = 0x36315659,
+    WL_DRM_FORMAT_YUV444 = 0x34325559,
+    WL_DRM_FORMAT_YVU444 = 0x34325659,
+};
+#endif /* WL_DRM_FORMAT_ENUM */
+
+#ifndef WL_DRM_CAPABILITY_ENUM
+#define WL_DRM_CAPABILITY_ENUM
+/**
+ * wl_drm_capability - wl_drm capability bitmask
+ * @WL_DRM_CAPABILITY_PRIME: wl_drm prime available
+ *
+ * Bitmask of capabilities.
+ */
+enum wl_drm_capability {
+    WL_DRM_CAPABILITY_PRIME = 1,
+};
+#endif /* WL_DRM_CAPABILITY_ENUM */
+
+struct wl_drm_listener {
+    /**
+     * device - (none)
+     * @name: (none)
+     * @since: 2
+     */
+    void (*device)(void *data,
+               struct wl_drm *wl_drm,
+               const char *name);
+    /**
+     * format - (none)
+     * @format: (none)
+     * @since: 2
+     */
+    void (*format)(void *data,
+               struct wl_drm *wl_drm,
+               uint32_t format);
+    /**
+     * authenticated - (none)
+     * @since: 2
+     */
+    void (*authenticated)(void *data,
+                  struct wl_drm *wl_drm);
+};
+
+static inline int
+wl_drm_add_listener(struct wl_drm *wl_drm,
+            const struct wl_drm_listener *listener, void *data)
+{
+    return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
+                     (void (**)(void)) listener, data);
+}
+
+#define WL_DRM_AUTHENTICATE    0
+#define WL_DRM_CREATE_BUFFER   1
+#define WL_DRM_CREATE_PLANAR_BUFFER    2
+#define WL_DRM_CREATE_PRIME_BUFFER     3
+
+static inline void
+wl_drm_set_user_data(struct wl_drm *wl_drm, void *user_data)
+{
+    wl_proxy_set_user_data((struct wl_proxy *) wl_drm, user_data);
+}
+
+static inline void *
+wl_drm_get_user_data(struct wl_drm *wl_drm)
+{
+    return wl_proxy_get_user_data((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_destroy(struct wl_drm *wl_drm)
+{
+    wl_proxy_destroy((struct wl_proxy *) wl_drm);
+}
+
+static inline void
+wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
+{
+    wl_proxy_marshal((struct wl_proxy *) wl_drm,
+             WL_DRM_AUTHENTICATE, id);
+}
+
+static inline struct wl_buffer *
+wl_drm_create_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t stride, uint32_t format)
+{
+    struct wl_proxy *id;
+
+    id = wl_proxy_create((struct wl_proxy *) wl_drm,
+                 &wl_buffer_interface);
+    if (!id)
+        return NULL;
+
+    wl_proxy_marshal((struct wl_proxy *) wl_drm,
+             WL_DRM_CREATE_BUFFER, id, name, width, height, stride, format);
+
+    return (struct wl_buffer *) id;
+}
+
+static inline struct wl_buffer *
+wl_drm_create_planar_buffer(struct wl_drm *wl_drm, uint32_t name, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+    struct wl_proxy *id;
+
+    id = wl_proxy_create((struct wl_proxy *) wl_drm,
+                 &wl_buffer_interface);
+    if (!id)
+        return NULL;
+
+    wl_proxy_marshal((struct wl_proxy *) wl_drm,
+             WL_DRM_CREATE_PLANAR_BUFFER, id, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+    return (struct wl_buffer *) id;
+}
+
+static inline struct wl_buffer *
+wl_drm_create_prime_buffer(struct wl_drm *wl_drm, int32_t name, int32_t width, int32_t height, uint32_t format, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
+{
+    struct wl_proxy *id;
+
+    id = wl_proxy_create((struct wl_proxy *) wl_drm,
+                 &wl_buffer_interface);
+    if (!id)
+        return NULL;
+
+    wl_proxy_marshal((struct wl_proxy *) wl_drm,
+             WL_DRM_CREATE_PRIME_BUFFER, id, name, width, height, format, offset0, stride0, offset1, stride1, offset2, stride2);
+
+    return (struct wl_buffer *) id;
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.cpp
new file mode 100644 (file)
index 0000000..f85ec21
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandBufferManager.h"
+
+#ifdef USE(MESA)
+#include "WaylandMesaBufferManager.h"
+#endif
+
+namespace WebCore {
+
+WaylandBufferManager* WaylandBufferManager::create(int fd)
+{
+#ifdef USE(MESA)
+    return new WaylandMesaBufferManager(fd);
+#else
+    return nullptr;
+#endif
+}
+
+}
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandBufferManager.h
new file mode 100644 (file)
index 0000000..30e30d6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandBufferManager_h
+#define WaylandBufferManager_h
+
+#include "WaylandDisplay.h"
+
+namespace WebCore {
+
+class WaylandBufferManager {
+public:
+    static WaylandBufferManager* create(int);
+    WaylandBufferManager() { }
+    virtual ~WaylandBufferManager() { }
+    virtual int allocateBO(unsigned, unsigned, uint32_t*) = 0;
+    virtual bool lockSurface(unsigned) = 0;
+    virtual bool unlockSurface(unsigned) = 0;
+    virtual bool querySurface(unsigned, int**) = 0;
+    virtual void freeBO(unsigned) = 0;
+};
+
+}
+
+#endif
index e85aae6..20e334b 100644 (file)
@@ -26,7 +26,9 @@
 #include "config.h"
 #include "WaylandDisplay.h"
 
+#include "WaylandBufferManager.h"
 #include "WaylandCompositor.h"
+#include "Wayland-drm-protocol.h"
 
 #include <errno.h>
 #include <fcntl.h>
 
 #include <wtf/text/CString.h>
 #include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+#include <libdrm/drm.h>
+#ifdef USE(MESA)
+#include <xf86drm.h>
+#endif
 
 // os-compatibility
+static struct wl_drm* m_drm = 0;
+
 extern "C" {
+
 int osEpollCreateCloExec(void);
 
 static int setCloExecOrClose(int fd)
@@ -84,6 +94,42 @@ int osEpollCreateCloExec(void)
 
 namespace WebCore {
 
+static inline int
+align(int value, int size)
+{
+    return (value + size - 1) & ~(size - 1);
+}
+
+void drm_handle_device(void* data, struct wl_drm*, const char* device)
+{
+    WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
+    display->drmHandleDevice(device);
+}
+
+void drm_handle_format(void* data, struct wl_drm*, uint32_t format)
+{
+    WaylandDisplay* d = static_cast<WaylandDisplay*>(data);
+    d->setWLDrmFormat(format);
+}
+
+void drm_handle_authenticated(void* data, struct wl_drm*)
+{
+    WaylandDisplay* d = static_cast<WaylandDisplay*>(data);
+    d->drmAuthenticated();
+}
+
+void drm_capabilities(void* data, struct wl_drm*, uint32_t value)
+{
+    struct WaylandDisplay* d = static_cast<WaylandDisplay*>(data);
+    d->setDrmCapabilities(value);
+}
+
+static const struct wl_drm_listener drm_listener = {
+    drm_handle_device,
+    drm_handle_format,
+    drm_handle_authenticated
+};
+
 WaylandDisplay* WaylandDisplay::m_instance = 0;
 String WaylandDisplay::m_socketString = "Wayland-";
 static int MAXEVENTS = 64;
@@ -350,6 +396,11 @@ WaylandDisplay::WaylandDisplay()
     , m_registry(0)
     , m_wlCompositor(0)
     , m_queue(0)
+    , m_bufmgr(0)
+    , m_deviceName(0)
+    , m_fd(-1)
+    , m_capabilities(0)
+    , m_authenticated(false)
     , m_pendingEvents(false)
 {
 }
@@ -380,7 +431,6 @@ void WaylandDisplay::initialize(wl_display* display)
         }
 
         m_eventDispatcher->start(m_display, display);
-
     } else {
         m_display = wl_display_connect(m_socketString.utf8().data());
 
@@ -401,6 +451,8 @@ void WaylandDisplay::initialize(wl_display* display)
 
         m_queue = wl_display_create_queue(m_display);
         wl_proxy_set_queue((struct wl_proxy *)m_registry, m_queue);
+        while(!m_bufmgr)
+            wl_display_roundtrip(m_display);
     }
 }
 
@@ -422,6 +474,22 @@ void WaylandDisplay::terminate()
     }
 
     if (m_registry) {
+
+        if (m_deviceName) {
+            free(m_deviceName);
+            m_deviceName = 0;
+        }
+
+        if (m_bufmgr) {
+            delete m_bufmgr;
+            m_bufmgr = 0;
+        }
+
+        if (m_drm) {
+            wl_drm_destroy(m_drm);
+            m_drm = 0;
+        }
+
         wl_registry_destroy(m_registry);
         m_registry = 0;
 
@@ -502,11 +570,18 @@ void WaylandDisplay::handlePendingEvents()
     m_compositor->flush();
 }
 
-void WaylandDisplay::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t)
+void WaylandDisplay::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t id)
 {
     WaylandDisplay* display = static_cast<WaylandDisplay*>(data);
-    if (display && !strcmp(interface, "wl_compositor"))
+    if (!display)
+        return;
+
+    if (!strcmp(interface, "wl_compositor"))
         display->m_wlCompositor = static_cast<struct wl_compositor*>(wl_registry_bind(registry, name, &wl_compositor_interface, 1));
+    else if (!display->m_eventDispatcher && !strcmp(interface, "wl_drm")) {
+        m_drm = static_cast<struct wl_drm*>(wl_registry_bind(registry, name, &wl_drm_interface, 1));
+        wl_drm_add_listener(m_drm, &drm_listener, display);
+    }
 }
 
 void WaylandDisplay::handleGlobalRemove(void*, struct wl_registry*, uint32_t)
@@ -546,4 +621,82 @@ int WaylandDisplay::syncDisplay()
     return ret;
 }
 
+void WaylandDisplay::drmHandleDevice(const char* device)
+{
+    drm_magic_t magic;
+    m_deviceName = strdup(device);
+
+    if (!m_deviceName)
+        return;
+#ifdef O_CLOEXEC
+    m_fd = open(device, O_RDWR | O_CLOEXEC);
+    if (m_fd == -1 && errno == EINVAL)
+#endif
+    {
+        m_fd = open(m_deviceName, O_RDWR);
+        if (m_fd != -1)
+            fcntl(m_fd, F_SETFD, fcntl(m_fd, F_GETFD) | FD_CLOEXEC);
+    }
+
+    if (m_fd == -1) {
+        LOG_ERROR("WaylandDisplay: could not open %s (%s)", m_deviceName, strerror(errno));
+        return;
+    }
+
+    drmGetMagic(m_fd, &magic);
+    wl_drm_authenticate(m_drm, magic);
+}
+
+void WaylandDisplay::setWLDrmFormat(uint32_t)
+{
+}
+
+void WaylandDisplay::drmAuthenticated()
+{
+    m_authenticated = true;
+    m_bufmgr = WaylandBufferManager::create(m_fd);
+}
+
+void WaylandDisplay::setDrmCapabilities(uint32_t value)
+{
+    m_capabilities = value;
+}
+
+bool WaylandDisplay::lockSurface(unsigned handle)
+{
+   return m_bufmgr->lockSurface(handle);
+}
+
+bool WaylandDisplay::unlockSurface(unsigned handle)
+{
+    return m_bufmgr->unlockSurface(handle);
+}
+
+bool WaylandDisplay::querySurface(unsigned handle, int** value)
+{
+    return m_bufmgr->querySurface(handle, value);
+}
+
+void WaylandDisplay::freeBO(unsigned handle)
+{
+    return m_bufmgr->freeBO(handle);
+}
+
+void* WaylandDisplay::createDrmBuffer(int width, int height, int* drmHandle)
+{
+    if (!m_drm || !m_bufmgr)
+        return 0;
+
+    uint32_t stride, offset, total, name = 0;
+    void* buffer = 0;
+    stride = width * 4;
+    total = stride * height;
+    offset = align(total, 4096);
+    total = offset + (width * height) / 2;
+    *drmHandle = m_bufmgr->allocateBO(total, 0, &name);
+    buffer =  wl_drm_create_buffer(m_drm, name, width, height, stride, WL_DRM_FORMAT_ARGB8888);
+
+    return buffer;
+}
+
 }
index 40c3ca3..7886512 100644 (file)
@@ -33,6 +33,7 @@
 
 namespace WebCore {
 class WaylandBuffer;
+class WaylandBufferManager;
 
 class WaylandBufferListener {
 public:
@@ -49,6 +50,7 @@ public:
     struct wl_display* nativeDisplay() const;
     struct wl_compositor* compositor() const;
     struct wl_registry* registry() const;
+
     int syncDisplay();
     int flush();
 
@@ -69,6 +71,18 @@ public:
     static void setSocketString(String socketString) { m_socketString = socketString; }
     static String socketString() { return m_socketString; }
 
+    // DRM related.
+    void* createDrmBuffer(int width, int height, int* drmHandle);
+    bool lockSurface(unsigned);
+    bool unlockSurface(unsigned);
+    bool querySurface(unsigned, int**);
+    void freeBO(unsigned);
+
+    void drmHandleDevice(const char*);
+    void setWLDrmFormat(uint32_t);
+    void drmAuthenticated();
+    void setDrmCapabilities(uint32_t);
+
 protected:
     WaylandDisplay();
     virtual ~WaylandDisplay();
@@ -98,6 +112,11 @@ private:
     struct wl_registry* m_registry;
     struct wl_compositor* m_wlCompositor;
     struct wl_event_queue* m_queue;
+    WaylandBufferManager* m_bufmgr;
+    char* m_deviceName;
+    int m_fd;
+    uint32_t m_capabilities;
+    bool m_authenticated :1;
     bool m_pendingEvents :1;
     friend class WaylandBuffer;
     friend class WaylandSurface;
index d745f08..fd32bfe 100644 (file)
@@ -29,6 +29,7 @@
 #include <wayland-client.h>
 #include <wayland-egl.h>
 #include <wayland-server.h>
+#include <wayland-util.h>
 
 #include <wtf/MainThread.h>
 #include <wtf/MessageQueue.h>
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.cpp
new file mode 100644 (file)
index 0000000..200f7ef
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandLockSurface.h"
+
+#include "WaylandBufferManager.h"
+
+#if PLATFORM(WAYLAND)
+
+namespace WebCore {
+
+WaylandLockSurface::WaylandLockSurface(const IntSize& size, GLPlatformSurface::SurfaceAttributes attributes)
+    : GLPlatformSurface()
+    , m_attributes(attributes)
+    , m_drmHandle(0)
+    , m_buffer(0)
+{
+    m_surface = WaylandDisplay::instance()->createSurface();
+
+    if (!m_surface) {
+        LOG_ERROR("Failed to create surface.");
+        destroy();
+        return;
+    }
+
+    m_bufferHandle = m_surface->handle();
+    m_rect = IntRect(0, 0, size.width(), size.height());
+    m_buffer = WaylandDisplay::instance()->createDrmBuffer(size.width(), size.height(), &m_drmHandle);
+    if (!m_drmHandle) {
+        LOG_ERROR("Failed to create DRM handle.");
+        destroy();
+        return;
+    }
+}
+
+WaylandLockSurface::~WaylandLockSurface()
+{
+    m_bufferHandle = 0;
+}
+
+void WaylandLockSurface::swapBuffers()
+{
+    if (m_surface->ensureFrameCallBackDone() == -1)
+        return;
+
+    m_surface->addFrameCallBack();
+}
+
+void WaylandLockSurface::destroy()
+{
+    if (m_surface) {
+        m_surface->ensureFrameCallBackDone();
+        m_surface->deleteFrameCallBack();
+    }
+
+    WaylandDisplay::instance()->freeBO(m_drmHandle);
+    GLPlatformSurface::destroy();
+    m_surface = nullptr;
+    m_bufferHandle = 0;
+}
+
+void WaylandLockSurface::setGeometry(const IntRect& rect)
+{
+    if (m_surface && rect != m_rect) {
+        m_rect = rect;
+        m_surface->ensureFrameCallBackDone();
+        WaylandDisplay::instance()->freeBO(m_drmHandle);
+        m_buffer = WaylandDisplay::instance()->createDrmBuffer(rect.width(), rect.height(), &m_drmHandle);
+        WaylandDisplay::instance()->syncDisplay();
+    }
+}
+
+bool WaylandLockSurface::lockSurface()
+{
+    if (m_surface->ensureFrameCallBackDone() == -1)
+        return false;
+
+    return WaylandDisplay::instance()->lockSurface(m_drmHandle);
+}
+
+bool WaylandLockSurface::unlockSurface()
+{
+    bool value = WaylandDisplay::instance()->unlockSurface(m_drmHandle);
+    if (!value)
+        return false;
+
+    m_surface->addFrameCallBack();
+    wl_surface_attach(m_surface->wlSurface(), static_cast<wl_buffer*>(m_buffer), 0, 0);
+    wl_surface_damage(m_surface->wlSurface(), 0, 0, m_rect.width(), m_rect.height());
+    wl_surface_commit(m_surface->wlSurface());
+    return value;
+}
+
+bool WaylandLockSurface::querySurface(int** value)
+{
+    return WaylandDisplay::instance()->querySurface(m_drmHandle, value);
+}
+
+GLPlatformSurface::SurfaceAttributes WaylandLockSurface::attributes() const
+{
+    return m_attributes;
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandLockSurface.h
new file mode 100644 (file)
index 0000000..877eaaf
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandLockSurface_h
+#define WaylandLockSurface_h
+
+#if PLATFORM(WAYLAND)
+
+#include "GLPlatformSurface.h"
+#include "WaylandDisplay.h"
+
+namespace WebCore {
+
+class WaylandLockSurface : public GLPlatformSurface {
+public:
+    WaylandLockSurface(const IntSize&, GLPlatformSurface::SurfaceAttributes);
+    virtual ~WaylandLockSurface();
+    virtual void swapBuffers() OVERRIDE;
+    virtual void destroy() OVERRIDE;
+    virtual void setGeometry(const IntRect&) OVERRIDE;
+    virtual bool lockSurface() OVERRIDE;
+    virtual bool unlockSurface() OVERRIDE;
+    virtual bool querySurface(int**) OVERRIDE;
+    virtual GLPlatformSurface::SurfaceAttributes attributes() const OVERRIDE;
+
+private:
+    OwnPtr<WaylandSurface> m_surface;
+    GLPlatformSurface::SurfaceAttributes m_attributes;
+    int m_drmHandle;
+    void* m_buffer;
+};
+
+}
+
+#endif
+
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.cpp b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.cpp
new file mode 100644 (file)
index 0000000..6c79707
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WaylandMesaBufferManager.h"
+
+#ifdef USE(MESA)
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+WaylandMesaBufferManager::WaylandMesaBufferManager(int fd)
+    : WaylandBufferManager()
+{
+    m_bufferManager = drm_intel_bufmgr_gem_init(fd, 4096);
+}
+
+WaylandMesaBufferManager::~WaylandMesaBufferManager()
+{
+    if (m_bufferManager)
+        drm_intel_bufmgr_destroy(m_bufferManager);
+}
+
+int WaylandMesaBufferManager::allocateBO(unsigned size, unsigned alignment, uint32_t* fd)
+{
+    static int allocationId = 0;
+    allocationId++;
+    String bufferString("WaylandNativeBuffer-");
+    bufferString.append(String::format("%d", allocationId));
+    drm_intel_bo* bo = drm_intel_bo_alloc(m_bufferManager, bufferString.utf8().data(), size, alignment);
+    if (!bo) {
+        LOG_ERROR("Failed to Allocate Drm Buffer.");
+        return 0;
+    }
+
+    drm_intel_bo_map(bo, true);
+    drm_intel_bo_flink(bo, fd);
+    m_bufferMap.add(allocationId, bo);
+
+    return allocationId;
+}
+
+void WaylandMesaBufferManager::freeBO(unsigned handleId)
+{
+    if (m_bufferMap.isEmpty())
+        return;
+
+    PlatformBufferMap::iterator it = m_bufferMap.find(handleId);
+    if (it != m_bufferMap.end()) {
+        drm_intel_bo* bo = it->second;
+        drm_intel_bo_unmap(bo);
+        drm_intel_bo_unreference(bo);
+        m_bufferMap.remove(it);
+    }
+}
+
+bool WaylandMesaBufferManager::lockSurface(unsigned handleId)
+{
+    PlatformBufferMap::iterator it = m_bufferMap.find(handleId);
+    if (it != m_bufferMap.end()) {
+        drm_intel_bo_map(it->second, true);
+        return true;
+    }
+
+    return false;
+}
+
+bool WaylandMesaBufferManager::unlockSurface(unsigned handleId)
+{
+    PlatformBufferMap::iterator it = m_bufferMap.find(handleId);
+    if (it != m_bufferMap.end()) {
+        drm_intel_bo_unmap(it->second);
+        return true;
+    }
+
+    return false;
+}
+
+bool WaylandMesaBufferManager::querySurface(unsigned handleId, int** value)
+{
+    PlatformBufferMap::iterator it = m_bufferMap.find(handleId);
+    drm_intel_bo* bo = NULL;
+    if (it == m_bufferMap.end())
+        return false;
+
+    bo = it->second;
+    *value = (int*)bo->virt;
+
+    return true;
+}
+
+}
+#endif
diff --git a/Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.h b/Source/WebCore/platform/graphics/surfaces/wayland/WaylandMesaBufferManager.h
new file mode 100644 (file)
index 0000000..d982314
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WaylandMesaBufferManager_h
+#define WaylandMesaBufferManager_h
+
+#ifdef USE(MESA)
+#include "WaylandBufferManager.h"
+#include <wtf/HashMap.h>
+
+extern "C" {
+#include <intel_bufmgr.h>
+}
+
+namespace WebCore {
+
+class WaylandMesaBufferManager : public WaylandBufferManager {
+public:
+    explicit WaylandMesaBufferManager(int);
+    virtual ~WaylandMesaBufferManager();
+    virtual int allocateBO(unsigned, unsigned, uint32_t*) OVERRIDE;
+    virtual bool lockSurface(unsigned) OVERRIDE;
+    virtual bool unlockSurface(unsigned) OVERRIDE;
+    virtual bool querySurface(unsigned, int**) OVERRIDE;
+    virtual void freeBO(unsigned) OVERRIDE;
+private:
+    drm_intel_bufmgr* m_bufferManager;
+    // Map Id and Buffer
+    typedef HashMap<int, drm_intel_bo*> PlatformBufferMap;
+    PlatformBufferMap m_bufferMap;
+};
+
+}
+
+#endif
+#endif
index d674ab9..cbae174 100644 (file)
 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 INCLUDE(FindPkgConfig)
-PKG_CHECK_MODULES(WAYLAND_PKG wayland-client wayland-egl)
+PKG_CHECK_MODULES(WAYLAND_PKG wayland-client wayland-egl gbm)
 
 # Include dir
 FIND_PATH(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h HINTS ${WAYLAND_PKG_INCLUDE_DIRS})
 FIND_PATH(WAYLAND_EGL_INCLUDE_DIR NAMES wayland-egl.h HINTS ${WAYLAND_PKG_INCLUDE_DIRS})
+#FIND_PATH(WAYLAND_DRM_INCLUDE_DIR NAMES drm.h HINTS ${WAYLAND_PKG_INCLUDE_DIRS})
+
+FIND_PATH(WAYLAND_DRM_INCLUDE_DIR drm.h /usr/include/libdrm/)
 
 # Finally the library itself
 FIND_LIBRARY(WAYLAND_CLIENT_LIBRARY NAMES wayland-client HINTS ${WAYLAND_PKG_LIBRARY_DIRS})
 FIND_LIBRARY(WAYLAND_EGL_LIBRARY NAMES wayland-egl HINTS ${WAYLAND_PKG_LIBRARY_DIRS})
+FIND_LIBRARY(WAYLAND_GBM_LIBRARY NAMES gbm PATHS /usr/lib)
+
+FIND_LIBRARY(WAYLAND_DRM_INTEL_LIBRARY NAMES DRM_INTEL drm_intel PATHS /usr/lib)
 
-SET(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARY} ${WAYLAND_EGL_LIBRARY})
-SET(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR})
+SET(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARY} ${WAYLAND_EGL_LIBRARY} ${WAYLAND_GBM_LIBRARY} ${WAYLAND_DRM_INTEL_LIBRARY})
+SET(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR} ${WAYLAND_EGL_INCLUDE_DIR} ${WAYLAND_DRM_INCLUDE_DIR})
 list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS)
 
 include(FindPackageHandleStandardArgs)
index 9d071ee..b4ebfb6 100644 (file)
@@ -425,6 +425,7 @@ ENDIF ()
 
 IF (USE_MESA)
     ADD_DEFINITIONS(-DWTF_USE_MESA=1)
+    SET(WTF_USE_MESA 1)
 ENDIF ()
 
 FIND_PACKAGE(Eina 1.2 REQUIRED)