summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2013-08-05 19:31:53 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2013-08-09 17:42:20 +0400
commitddaa9c34dbf4119f556fa64b16f7d7b52f0ea530 (patch)
tree199b7899855fe3bdc233e48b6c982435aaedb523
parent9ab05f88786e8dd79f7d868c62d286555343941d (diff)
downloademulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.tar.gz
emulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.tar.bz2
emulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.zip
YaGL: wayland platform added
Change-Id: Ife2fa6fde03f956d7753987e7d09deda4cf1bff7
-rw-r--r--CMake/WPCodegenTarget.cmake15
-rw-r--r--CMakeLists.txt22
-rw-r--r--EGL/CMakeLists.txt26
-rw-r--r--EGL/gbm/yagl_gbm_display.c72
-rw-r--r--EGL/gbm/yagl_gbm_platform.c1
-rw-r--r--EGL/wayland-drm.c194
-rw-r--r--EGL/wayland-drm.h41
-rw-r--r--EGL/wayland-drm.xml155
-rw-r--r--EGL/wayland/yagl_wayland_display.c353
-rw-r--r--EGL/wayland/yagl_wayland_display.h33
-rw-r--r--EGL/wayland/yagl_wayland_platform.c32
-rw-r--r--EGL/wayland/yagl_wayland_platform.h10
-rw-r--r--EGL/wayland/yagl_wayland_window.c407
-rw-r--r--EGL/wayland/yagl_wayland_window.h36
-rw-r--r--EGL/x11/yagl_x11_display.c56
-rw-r--r--EGL/x11/yagl_x11_platform.c1
-rw-r--r--EGL/yagl_backend.h14
-rw-r--r--EGL/yagl_display.c56
-rw-r--r--EGL/yagl_display.h7
-rw-r--r--EGL/yagl_egl_calls.c220
-rw-r--r--EGL/yagl_image.c17
-rw-r--r--EGL/yagl_image.h12
-rw-r--r--EGL/yagl_native_display.c123
-rw-r--r--EGL/yagl_native_display.h31
-rw-r--r--EGL/yagl_native_platform.c6
-rw-r--r--EGL/yagl_native_platform.h2
-rw-r--r--EGL/yagl_offscreen.c32
-rw-r--r--EGL/yagl_offscreen_image.h22
-rw-r--r--EGL/yagl_offscreen_image_pixmap.c (renamed from EGL/yagl_offscreen_image.c)43
-rw-r--r--EGL/yagl_offscreen_image_pixmap.h26
-rw-r--r--EGL/yagl_onscreen.c45
-rw-r--r--EGL/yagl_onscreen_image.h25
-rw-r--r--EGL/yagl_onscreen_image_pixmap.c (renamed from EGL/yagl_onscreen_image.c)31
-rw-r--r--EGL/yagl_onscreen_image_pixmap.h26
-rw-r--r--EGL/yagl_onscreen_image_wl_buffer.c74
-rw-r--r--EGL/yagl_onscreen_image_wl_buffer.h25
-rw-r--r--gbm/yagl_gbm.c15
-rw-r--r--include/EGL/eglext.h279
-rw-r--r--include/EGL/eglmesaext.h12
-rw-r--r--include/EGL/eglplatform.h4
-rw-r--r--include/yagl_wayland_egl.h25
-rw-r--r--packaging/emulator-yagl.spec8
-rw-r--r--wayland-egl/CMakeLists.txt14
-rw-r--r--wayland-egl/yagl_wayland_egl.c54
44 files changed, 2484 insertions, 218 deletions
diff --git a/CMake/WPCodegenTarget.cmake b/CMake/WPCodegenTarget.cmake
new file mode 100644
index 0000000..ec5e072
--- /dev/null
+++ b/CMake/WPCodegenTarget.cmake
@@ -0,0 +1,15 @@
+function(wp_codegen_target _TARGET _INPUT _OUT_DIR)
+ file(MAKE_DIRECTORY ${_OUT_DIR})
+ add_custom_command(OUTPUT ${_OUT_DIR}/${_TARGET}-server-protocol.h
+ COMMAND ${CMAKE_FIND_ROOT_PATH}${WAYLAND_CLIENT_PREFIX}/bin/wayland-scanner server-header < ${_INPUT} > ${_OUT_DIR}/${_TARGET}-server-protocol.h
+ DEPENDS ${_INPUT}
+ VERBATIM)
+ add_custom_command(OUTPUT ${_OUT_DIR}/${_TARGET}-client-protocol.h
+ COMMAND ${CMAKE_FIND_ROOT_PATH}${WAYLAND_CLIENT_PREFIX}/bin/wayland-scanner client-header < ${_INPUT} > ${_OUT_DIR}/${_TARGET}-client-protocol.h
+ DEPENDS ${_INPUT}
+ VERBATIM)
+ add_custom_command(OUTPUT ${_OUT_DIR}/${_TARGET}-protocol.c
+ COMMAND ${CMAKE_FIND_ROOT_PATH}${WAYLAND_CLIENT_PREFIX}/bin/wayland-scanner code < ${_INPUT} > ${_OUT_DIR}/${_TARGET}-protocol.c
+ DEPENDS ${_INPUT}
+ VERBATIM)
+endfunction ()
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ce1b2df..be38025 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,6 +18,8 @@ endif ()
project(YAGL C)
+set(CMAKE_MODULE_PATH "${YAGL_SOURCE_DIR}/CMake")
+
# USER SETTINGS
if (CMAKE_BUILD_TYPE STREQUAL "")
@@ -88,6 +90,23 @@ if (PLATFORM_GBM)
add_definitions(${GBM_CFLAGS})
include_directories(${GBM_INCLUDE_DIRS})
+
+ pkg_check_modules(LIBUDEV REQUIRED libudev)
+
+ add_definitions(${LIBUDEV_CFLAGS})
+ include_directories(${LIBUDEV_INCLUDE_DIRS})
+endif ()
+
+if (PLATFORM_WAYLAND)
+ pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client)
+
+ add_definitions(${WAYLAND_CLIENT_CFLAGS})
+ include_directories(${WAYLAND_CLIENT_INCLUDE_DIRS})
+
+ pkg_check_modules(WAYLAND_SERVER REQUIRED wayland-server)
+
+ add_definitions(${WAYLAND_SERVER_CFLAGS})
+ include_directories(${WAYLAND_SERVER_INCLUDE_DIRS})
endif ()
#fix output directories
@@ -130,6 +149,9 @@ message(STATUS "Install lib dir: " ${INSTALL_LIB_DIR})
if (PLATFORM_GBM)
add_subdirectory(gbm)
endif ()
+if (PLATFORM_WAYLAND)
+add_subdirectory(wayland-egl)
+endif ()
add_subdirectory(EGL)
add_subdirectory(GLESv1_CM)
add_subdirectory(GLESv2)
diff --git a/EGL/CMakeLists.txt b/EGL/CMakeLists.txt
index fe4970f..dc72574 100644
--- a/EGL/CMakeLists.txt
+++ b/EGL/CMakeLists.txt
@@ -1,3 +1,5 @@
+include (WPCodegenTarget)
+
set(SOURCES
yagl_context.c
yagl_display.c
@@ -10,10 +12,10 @@ set(SOURCES
yagl_log.c
yagl_malloc.c
yagl_offscreen.c
- yagl_offscreen_image.c
+ yagl_offscreen_image_pixmap.c
yagl_offscreen_surface.c
yagl_onscreen.c
- yagl_onscreen_image.c
+ yagl_onscreen_image_pixmap.c
yagl_onscreen_surface.c
yagl_onscreen_utils.c
yagl_ref.c
@@ -60,14 +62,34 @@ if (PLATFORM_GBM)
)
set(LIBRARIES ${LIBRARIES}
gbm-yagl
+ ${LIBUDEV_LIBRARIES}
)
add_definitions(-DYAGL_PLATFORM_GBM)
endif ()
if (PLATFORM_WAYLAND)
+ set(SOURCES ${SOURCES}
+ wayland/yagl_wayland_platform.c
+ wayland/yagl_wayland_display.c
+ wayland/yagl_wayland_window.c
+ ${CMAKE_CURRENT_BINARY_DIR}/wayland-drm-server-protocol.h
+ ${CMAKE_CURRENT_BINARY_DIR}/wayland-drm-client-protocol.h
+ ${CMAKE_CURRENT_BINARY_DIR}/wayland-drm-protocol.c
+ wayland-drm.c
+ yagl_onscreen_image_wl_buffer.c
+ )
+ set(LIBRARIES ${LIBRARIES}
+ wayland-egl-yagl
+ ${WAYLAND_CLIENT_LIBRARIES}
+ ${WAYLAND_SERVER_LIBRARIES}
+ )
add_definitions(-DYAGL_PLATFORM_WAYLAND)
+ wp_codegen_target(wayland-drm
+ ${CMAKE_CURRENT_SOURCE_DIR}/wayland-drm.xml
+ ${CMAKE_CURRENT_BINARY_DIR})
endif ()
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(.)
add_library(EGL SHARED ${SOURCES})
diff --git a/EGL/gbm/yagl_gbm_display.c b/EGL/gbm/yagl_gbm_display.c
index 51d5057..5e1d162 100644
--- a/EGL/gbm/yagl_gbm_display.c
+++ b/EGL/gbm/yagl_gbm_display.c
@@ -5,6 +5,67 @@
#include "yagl_log.h"
#include "yagl_malloc.h"
#include "yagl_gbm.h"
+#include "vigs.h"
+#include <xf86drm.h>
+#include <libudev.h>
+#include <string.h>
+#include <stdlib.h>
+
+static struct udev_device *udev_device_new_from_fd(struct udev *udev, int fd)
+{
+ struct udev_device *device;
+ struct stat buf;
+
+ if (fstat(fd, &buf) < 0) {
+ return NULL;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+
+ if (!device) {
+ return NULL;
+ }
+
+ return device;
+}
+
+static char *get_device_name_for_fd(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device;
+ const char *const_device_name;
+ char *device_name = NULL;
+
+ udev = udev_new();
+
+ device = udev_device_new_from_fd(udev, fd);
+
+ if (!device) {
+ return NULL;
+ }
+
+ const_device_name = udev_device_get_devnode(device);
+
+ if (!const_device_name) {
+ goto out;
+ }
+
+ device_name = strdup(const_device_name);
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return device_name;
+}
+
+static int yagl_gbm_display_authenticate(struct yagl_native_display *dpy,
+ uint32_t id)
+{
+ struct gbm_device *gbm_dpy = YAGL_GBM_DPY(dpy->os_dpy);
+
+ return drmAuthMagic(gbm_dpy->drm_dev->fd, id);
+}
static struct yagl_native_drawable
*yagl_gbm_display_wrap_window(struct yagl_native_display *dpy,
@@ -58,14 +119,21 @@ struct yagl_native_display
{
struct gbm_device *gbm_dpy = YAGL_GBM_DPY(os_dpy);
struct yagl_native_display *dpy;
+ char *device_name = get_device_name_for_fd(gbm_dpy->drm_dev->fd);
+
+ if (!device_name) {
+ return NULL;
+ }
dpy = yagl_malloc0(sizeof(*dpy));
yagl_native_display_init(dpy,
platform,
os_dpy,
- gbm_dpy->drm_dev);
+ gbm_dpy->drm_dev,
+ device_name);
+ dpy->authenticate = &yagl_gbm_display_authenticate;
dpy->wrap_window = &yagl_gbm_display_wrap_window;
dpy->wrap_pixmap = &yagl_gbm_display_wrap_pixmap;
dpy->create_pixmap = &yagl_gbm_display_create_pixmap;
@@ -73,5 +141,7 @@ struct yagl_native_display
dpy->get_visual = &yagl_gbm_display_get_visual;
dpy->destroy = &yagl_gbm_display_destroy;
+ free(device_name);
+
return dpy;
}
diff --git a/EGL/gbm/yagl_gbm_platform.c b/EGL/gbm/yagl_gbm_platform.c
index a459a90..19ca7ce 100644
--- a/EGL/gbm/yagl_gbm_platform.c
+++ b/EGL/gbm/yagl_gbm_platform.c
@@ -26,6 +26,7 @@ static struct yagl_native_display
struct yagl_native_platform yagl_gbm_platform =
{
+ .pixmaps_supported = 1,
.probe = yagl_gbm_platform_probe,
.wrap_display = yagl_gbm_wrap_display
};
diff --git a/EGL/wayland-drm.c b/EGL/wayland-drm.c
new file mode 100644
index 0000000..b231476
--- /dev/null
+++ b/EGL/wayland-drm.c
@@ -0,0 +1,194 @@
+#include "wayland-drm.h"
+#include <wayland-server.h>
+#include "wayland-drm-server-protocol.h"
+#include "yagl_malloc.h"
+#include "vigs.h"
+#include <string.h>
+#include <stdlib.h>
+
+struct wl_drm
+{
+ struct wl_display *display;
+ char *device_name;
+ struct wayland_drm_callbacks *callbacks;
+ void *user_data;
+};
+
+static void buffer_destroy(struct wl_resource *resource)
+{
+ struct wl_drm_buffer *buffer = resource->data;
+
+ vigs_drm_gem_unref(&buffer->drm_sfc->gem);
+
+ yagl_free(buffer);
+}
+
+static void drm_buffer_destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+
+static struct wl_buffer_interface drm_buffer_interface =
+{
+ drm_buffer_destroy
+};
+
+static void drm_create_buffer(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id, uint32_t name,
+ int32_t width, int32_t height,
+ uint32_t stride, uint32_t format)
+{
+ struct wl_drm *drm = resource->data;
+ struct wl_drm_buffer *buffer;
+
+ switch (format) {
+ case WL_DRM_FORMAT_ARGB8888:
+ case WL_DRM_FORMAT_XRGB8888:
+ break;
+ default:
+ wl_resource_post_error(resource,
+ WL_DRM_ERROR_INVALID_FORMAT,
+ "invalid format");
+ return;
+ }
+
+ buffer = yagl_malloc0(sizeof(*buffer));
+
+ if (!buffer) {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ buffer->drm_sfc = drm->callbacks->acquire_buffer(drm->user_data, name);
+
+ if (!buffer->drm_sfc) {
+ wl_resource_post_error(resource,
+ WL_DRM_ERROR_INVALID_NAME,
+ "invalid name");
+ yagl_free(buffer);
+ return;
+ }
+
+ buffer->resource = wl_resource_create(client,
+ &wl_buffer_interface,
+ 1,
+ id);
+ if (!buffer->resource) {
+ wl_resource_post_no_memory(resource);
+ vigs_drm_gem_unref(&buffer->drm_sfc->gem);
+ yagl_free(buffer);
+ return;
+ }
+
+ buffer->drm = drm;
+ buffer->format = format;
+
+ wl_resource_set_implementation(buffer->resource,
+ (void(**)(void))&drm_buffer_interface,
+ buffer,
+ buffer_destroy);
+}
+
+static void drm_create_planar_buffer(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id, 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)
+{
+ wl_resource_post_error(resource,
+ WL_DRM_ERROR_INVALID_FORMAT,
+ "invalid format");
+}
+
+static void drm_authenticate(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id)
+{
+ struct wl_drm *drm = resource->data;
+
+ if (drm->callbacks->authenticate(drm->user_data, id) < 0) {
+ wl_resource_post_error(resource,
+ WL_DRM_ERROR_AUTHENTICATE_FAIL,
+ "authenicate failed");
+ } else {
+ wl_drm_send_authenticated(resource);
+ }
+}
+
+static struct wl_drm_interface drm_interface =
+{
+ drm_authenticate,
+ drm_create_buffer,
+ drm_create_planar_buffer
+};
+
+static void bind_drm(struct wl_client *client,
+ void *data,
+ uint32_t version,
+ uint32_t id)
+{
+ struct wl_drm *drm = data;
+ struct wl_resource *resource;
+
+ resource = wl_resource_create(client,
+ &wl_drm_interface,
+ 1,
+ id);
+
+ if (!resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ wl_resource_set_implementation(resource, &drm_interface, data, NULL);
+
+ wl_drm_send_device(resource, drm->device_name);
+ wl_drm_send_format(resource, WL_DRM_FORMAT_ARGB8888);
+ wl_drm_send_format(resource, WL_DRM_FORMAT_XRGB8888);
+}
+
+struct wl_drm *wayland_drm_create(struct wl_display *display,
+ char *device_name,
+ struct wayland_drm_callbacks *callbacks,
+ void *user_data)
+{
+ struct wl_drm *drm;
+
+ drm = yagl_malloc0(sizeof(*drm));
+
+ drm->display = display;
+ drm->device_name = strdup(device_name);
+ drm->callbacks = callbacks;
+ drm->user_data = user_data;
+
+ wl_global_create(display, &wl_drm_interface, 1, drm, bind_drm);
+
+ return drm;
+}
+
+void wayland_drm_destroy(struct wl_drm *drm)
+{
+ free(drm->device_name);
+
+ yagl_free(drm);
+}
+
+struct wl_drm_buffer *wayland_drm_get_buffer(struct wl_resource *resource)
+{
+ if (!resource) {
+ return NULL;
+ }
+
+ if (wl_resource_instance_of(resource,
+ &wl_buffer_interface,
+ &drm_buffer_interface)) {
+ return wl_resource_get_user_data(resource);
+ } else {
+ return NULL;
+ }
+}
diff --git a/EGL/wayland-drm.h b/EGL/wayland-drm.h
new file mode 100644
index 0000000..374f8a5
--- /dev/null
+++ b/EGL/wayland-drm.h
@@ -0,0 +1,41 @@
+#ifndef _WAYLAND_DRM_H_
+#define _WAYLAND_DRM_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+
+struct wl_drm;
+struct wl_resource;
+struct wl_display;
+struct vigs_drm_surface;
+
+struct wl_drm_buffer
+{
+ struct wl_resource *resource;
+
+ struct wl_drm *drm;
+
+ uint32_t format;
+
+ struct vigs_drm_surface *drm_sfc;
+};
+
+struct wayland_drm_callbacks
+{
+ int (*authenticate)(void */*user_data*/,
+ uint32_t /*id*/);
+
+ struct vigs_drm_surface *(*acquire_buffer)(void */*user_data*/,
+ uint32_t /*name*/);
+};
+
+struct wl_drm *wayland_drm_create(struct wl_display *display,
+ char *device_name,
+ struct wayland_drm_callbacks *callbacks,
+ void *user_data);
+
+void wayland_drm_destroy(struct wl_drm *drm);
+
+struct wl_drm_buffer *wayland_drm_get_buffer(struct wl_resource *resource);
+
+#endif
diff --git a/EGL/wayland-drm.xml b/EGL/wayland-drm.xml
new file mode 100644
index 0000000..265d4f8
--- /dev/null
+++ b/EGL/wayland-drm.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="drm">
+
+ <copyright>
+ 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.
+ </copyright>
+
+ <!-- drm support. This object is created by the server and published
+ using the display's global event. -->
+ <interface name="wl_drm" version="1">
+ <enum name="error">
+ <entry name="authenticate_fail" value="0"/>
+ <entry name="invalid_format" value="1"/>
+ <entry name="invalid_name" value="2"/>
+ </enum>
+
+ <enum name="format">
+ <!-- The drm format codes match the #defines in drm_fourcc.h.
+ The formats actually supported by the compositor will be
+ reported by the format event. -->
+ <entry name="c8" value="0x20203843"/>
+ <entry name="rgb332" value="0x38424752"/>
+ <entry name="bgr233" value="0x38524742"/>
+ <entry name="xrgb4444" value="0x32315258"/>
+ <entry name="xbgr4444" value="0x32314258"/>
+ <entry name="rgbx4444" value="0x32315852"/>
+ <entry name="bgrx4444" value="0x32315842"/>
+ <entry name="argb4444" value="0x32315241"/>
+ <entry name="abgr4444" value="0x32314241"/>
+ <entry name="rgba4444" value="0x32314152"/>
+ <entry name="bgra4444" value="0x32314142"/>
+ <entry name="xrgb1555" value="0x35315258"/>
+ <entry name="xbgr1555" value="0x35314258"/>
+ <entry name="rgbx5551" value="0x35315852"/>
+ <entry name="bgrx5551" value="0x35315842"/>
+ <entry name="argb1555" value="0x35315241"/>
+ <entry name="abgr1555" value="0x35314241"/>
+ <entry name="rgba5551" value="0x35314152"/>
+ <entry name="bgra5551" value="0x35314142"/>
+ <entry name="rgb565" value="0x36314752"/>
+ <entry name="bgr565" value="0x36314742"/>
+ <entry name="rgb888" value="0x34324752"/>
+ <entry name="bgr888" value="0x34324742"/>
+ <entry name="xrgb8888" value="0x34325258"/>
+ <entry name="xbgr8888" value="0x34324258"/>
+ <entry name="rgbx8888" value="0x34325852"/>
+ <entry name="bgrx8888" value="0x34325842"/>
+ <entry name="argb8888" value="0x34325241"/>
+ <entry name="abgr8888" value="0x34324241"/>
+ <entry name="rgba8888" value="0x34324152"/>
+ <entry name="bgra8888" value="0x34324142"/>
+ <entry name="xrgb2101010" value="0x30335258"/>
+ <entry name="xbgr2101010" value="0x30334258"/>
+ <entry name="rgbx1010102" value="0x30335852"/>
+ <entry name="bgrx1010102" value="0x30335842"/>
+ <entry name="argb2101010" value="0x30335241"/>
+ <entry name="abgr2101010" value="0x30334241"/>
+ <entry name="rgba1010102" value="0x30334152"/>
+ <entry name="bgra1010102" value="0x30334142"/>
+ <entry name="yuyv" value="0x56595559"/>
+ <entry name="yvyu" value="0x55595659"/>
+ <entry name="uyvy" value="0x59565955"/>
+ <entry name="vyuy" value="0x59555956"/>
+ <entry name="ayuv" value="0x56555941"/>
+ <entry name="nv12" value="0x3231564e"/>
+ <entry name="nv21" value="0x3132564e"/>
+ <entry name="nv16" value="0x3631564e"/>
+ <entry name="nv61" value="0x3136564e"/>
+ <entry name="yuv410" value="0x39565559"/>
+ <entry name="yvu410" value="0x39555659"/>
+ <entry name="yuv411" value="0x31315559"/>
+ <entry name="yvu411" value="0x31315659"/>
+ <entry name="yuv420" value="0x32315559"/>
+ <entry name="yvu420" value="0x32315659"/>
+ <entry name="yuv422" value="0x36315559"/>
+ <entry name="yvu422" value="0x36315659"/>
+ <entry name="yuv444" value="0x34325559"/>
+ <entry name="yvu444" value="0x34325659"/>
+ </enum>
+
+ <!-- Call this request with the magic received from drmGetMagic().
+ It will be passed on to the drmAuthMagic() or
+ DRIAuthConnection() call. This authentication must be
+ completed before create_buffer could be used. -->
+ <request name="authenticate">
+ <arg name="id" type="uint"/>
+ </request>
+
+ <!-- Create a wayland buffer for the named DRM buffer. The DRM
+ surface must have a name using the flink ioctl -->
+ <request name="create_buffer">
+ <arg name="id" type="new_id" interface="wl_buffer"/>
+ <arg name="name" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ <arg name="stride" type="uint"/>
+ <arg name="format" type="uint"/>
+ </request>
+
+ <!-- Create a wayland buffer for the named DRM buffer. The DRM
+ surface must have a name using the flink ioctl -->
+ <request name="create_planar_buffer">
+ <arg name="id" type="new_id" interface="wl_buffer"/>
+ <arg name="name" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ <arg name="format" type="uint"/>
+ <arg name="offset0" type="int"/>
+ <arg name="stride0" type="int"/>
+ <arg name="offset1" type="int"/>
+ <arg name="stride1" type="int"/>
+ <arg name="offset2" type="int"/>
+ <arg name="stride2" type="int"/>
+ </request>
+
+ <!-- Notification of the path of the drm device which is used by
+ the server. The client should use this device for creating
+ local buffers. Only buffers created from this device should
+ be be passed to the server using this drm object's
+ create_buffer request. -->
+ <event name="device">
+ <arg name="name" type="string"/>
+ </event>
+
+ <event name="format">
+ <arg name="format" type="uint"/>
+ </event>
+
+ <!-- Raised if the authenticate request succeeded -->
+ <event name="authenticated"/>
+ </interface>
+
+</protocol>
diff --git a/EGL/wayland/yagl_wayland_display.c b/EGL/wayland/yagl_wayland_display.c
new file mode 100644
index 0000000..41778e8
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_display.c
@@ -0,0 +1,353 @@
+#include "yagl_wayland_display.h"
+#include "yagl_wayland_window.h"
+#include "yagl_log.h"
+#include "yagl_malloc.h"
+#include "wayland-drm-client-protocol.h"
+#include "vigs.h"
+#include <xf86drm.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+static void yagl_wayland_display_roundtrip_done(void *data,
+ struct wl_callback *callback,
+ uint32_t serial)
+{
+ int *done = data;
+
+ *done = 1;
+
+ wl_callback_destroy(callback);
+}
+
+static struct wl_callback_listener yagl_wayland_display_roundtrip_listener =
+{
+ yagl_wayland_display_roundtrip_done
+};
+
+static int yagl_wayland_display_roundtrip(struct wl_display *dpy,
+ struct wl_event_queue *queue)
+{
+ struct wl_callback *callback;
+ int done = 0, ret = 0;
+
+ callback = wl_display_sync(dpy);
+ wl_callback_add_listener(callback,
+ &yagl_wayland_display_roundtrip_listener,
+ &done);
+ wl_proxy_set_queue((struct wl_proxy*)callback, queue);
+
+ while ((ret != -1) && !done) {
+ ret = wl_display_dispatch_queue(dpy, queue);
+ }
+
+ if (!done) {
+ wl_callback_destroy(callback);
+ }
+
+ return ret >= 0;
+}
+
+static void yagl_wayland_display_drm_device(void *data,
+ struct wl_drm *wl_drm,
+ const char *name)
+{
+ struct yagl_wayland_display *dpy = data;
+ drm_magic_t magic;
+ int ret;
+
+ YAGL_LOG_FUNC_ENTER(yagl_wayland_display_drm_device,
+ "dpy = %p, wl_drm = %p, name = %s",
+ dpy, wl_drm, name);
+
+ if (dpy->drm_dev_name) {
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return;
+ }
+
+ dpy->drm_dev_name = strdup(name);
+
+ dpy->drm_fd = open(dpy->drm_dev_name, O_RDWR);
+
+ if (dpy->drm_fd < 0) {
+ fprintf(stderr, "Critical error! Failed to open(\"%s\"): %s\n",
+ dpy->drm_dev_name, strerror(errno));
+ goto fail;
+ }
+
+ memset(&magic, 0, sizeof(magic));
+
+ ret = drmGetMagic(dpy->drm_fd, &magic);
+
+ if (ret != 0) {
+ fprintf(stderr, "Critical error! drmGetMagic failed: %s\n", strerror(-ret));
+ goto fail;
+ }
+
+ wl_drm_authenticate(dpy->wl_drm, magic);
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return;
+
+fail:
+ if (dpy->drm_fd >= 0) {
+ close(dpy->drm_fd);
+ dpy->drm_fd = -1;
+ }
+ free(dpy->drm_dev_name);
+ dpy->drm_dev_name = NULL;
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static void yagl_wayland_display_drm_format(void *data,
+ struct wl_drm *wl_drm,
+ uint32_t format)
+{
+ YAGL_LOG_FUNC_ENTER(yagl_wayland_display_drm_format,
+ "dpy = %p, wl_drm = %p, format = %u",
+ data, wl_drm, format);
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static void yagl_wayland_display_drm_authenticated(void *data,
+ struct wl_drm *wl_drm)
+{
+ struct yagl_wayland_display *dpy = data;
+
+ YAGL_LOG_FUNC_ENTER(yagl_wayland_display_drm_authenticated,
+ "dpy = %p, wl_drm = %p",
+ dpy, wl_drm);
+
+ dpy->authenticated = 1;
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static struct wl_drm_listener yagl_wayland_display_drm_listener =
+{
+ yagl_wayland_display_drm_device,
+ yagl_wayland_display_drm_format,
+ yagl_wayland_display_drm_authenticated
+};
+
+static void yagl_wayland_display_registry_global(void *data,
+ struct wl_registry *registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version)
+{
+ struct yagl_wayland_display *dpy = data;
+
+ if (dpy->wl_drm) {
+ return;
+ }
+
+ if (strcmp(interface, "wl_drm") == 0) {
+ dpy->wl_drm = wl_registry_bind(registry,
+ name,
+ &wl_drm_interface,
+ 1);
+ wl_drm_add_listener(dpy->wl_drm,
+ &yagl_wayland_display_drm_listener,
+ dpy);
+ }
+}
+
+static struct wl_registry_listener yagl_wayland_display_registry_listener =
+{
+ yagl_wayland_display_registry_global
+};
+
+static int yagl_wayland_display_authenticate(struct yagl_native_display *dpy,
+ uint32_t id)
+{
+ struct yagl_wayland_display *wayland_dpy = (struct yagl_wayland_display*)dpy;
+ struct wl_display *wl_dpy = YAGL_WAYLAND_DPY(dpy->os_dpy);
+ int ret;
+
+ /*
+ * Set 'authenticated' temporary to 0, send
+ * an authenticate request, wait for the reply to set
+ * 'authenticated' to 1, in this case we're authenticated,
+ * otherwise an error has occurred and 'authenticated'
+ * will remain 0. Restore 'authenticated' to 1 afterwards.
+ */
+
+ wayland_dpy->authenticated = 0;
+
+ wl_drm_authenticate(wayland_dpy->wl_drm, id);
+ yagl_wayland_display_roundtrip(wl_dpy, wayland_dpy->queue);
+
+ ret = wayland_dpy->authenticated;
+
+ wayland_dpy->authenticated = 1;
+
+ return ret;
+}
+
+static struct yagl_native_drawable
+ *yagl_wayland_display_wrap_window(struct yagl_native_display *dpy,
+ yagl_os_window os_window)
+{
+ return yagl_wayland_window_create(dpy, os_window);
+}
+
+static struct yagl_native_drawable
+ *yagl_wayland_display_wrap_pixmap(struct yagl_native_display *dpy,
+ yagl_os_pixmap os_pixmap)
+{
+ return NULL;
+}
+
+static struct yagl_native_drawable
+ *yagl_wayland_display_create_pixmap(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ return NULL;
+}
+
+static struct yagl_native_image
+ *yagl_wayland_display_create_image(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ return NULL;
+}
+
+static int yagl_wayland_display_get_visual(struct yagl_native_display *dpy,
+ int *visual_id,
+ int *visual_type)
+{
+ return 0;
+}
+
+static void yagl_wayland_display_destroy(struct yagl_native_display *dpy)
+{
+ struct yagl_wayland_display *wayland_dpy = (struct yagl_wayland_display*)dpy;
+
+ free(wayland_dpy->drm_dev_name);
+ wayland_dpy->drm_dev_name = NULL;
+
+ close(wayland_dpy->drm_fd);
+ wayland_dpy->drm_fd = -1;
+
+ wl_drm_destroy(wayland_dpy->wl_drm);
+ wayland_dpy->wl_drm = NULL;
+
+ wl_event_queue_destroy(wayland_dpy->queue);
+ wayland_dpy->queue = NULL;
+
+ yagl_native_display_cleanup(dpy);
+
+ yagl_free(wayland_dpy);
+}
+
+struct yagl_native_display
+ *yagl_wayland_display_create(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy)
+{
+ struct wl_display *wl_dpy = YAGL_WAYLAND_DPY(os_dpy);
+ struct yagl_wayland_display *dpy;
+ int ret;
+ struct vigs_drm_device *drm_dev = NULL;
+
+ YAGL_LOG_FUNC_ENTER(yagl_wayland_display_create,
+ "os_dpy = %p", os_dpy);
+
+ dpy = yagl_malloc0(sizeof(*dpy));
+
+ dpy->drm_fd = -1;
+
+ dpy->queue = wl_display_create_queue(wl_dpy);
+
+ if (!dpy->queue) {
+ YAGL_LOG_ERROR("Unable to create event queue");
+ goto fail;
+ }
+
+ dpy->registry = wl_display_get_registry(wl_dpy);
+
+ wl_proxy_set_queue((struct wl_proxy*)dpy->registry, dpy->queue);
+
+ wl_registry_add_listener(dpy->registry,
+ &yagl_wayland_display_registry_listener,
+ dpy);
+
+ if (!yagl_wayland_display_roundtrip(wl_dpy, dpy->queue) ||
+ !dpy->wl_drm) {
+ YAGL_LOG_ERROR("Unable to obtain wl_drm interface");
+ goto fail;
+ }
+
+ if (!yagl_wayland_display_roundtrip(wl_dpy, dpy->queue) ||
+ (dpy->drm_fd == -1)) {
+ YAGL_LOG_ERROR("Unable to open wl_drm device");
+ goto fail;
+ }
+
+ if (!yagl_wayland_display_roundtrip(wl_dpy, dpy->queue) ||
+ !dpy->authenticated) {
+ YAGL_LOG_ERROR("Unable to authenticate on wl_drm interface");
+ goto fail;
+ }
+
+ ret = vigs_drm_device_create(dpy->drm_fd, &drm_dev);
+
+ if (ret != 0) {
+ fprintf(stderr,
+ "Critical error! vigs_drm_device_create failed: %s\n",
+ strerror(-ret));
+ goto fail;
+ }
+
+ yagl_native_display_init(&dpy->base,
+ platform,
+ os_dpy,
+ drm_dev,
+ dpy->drm_dev_name);
+
+ dpy->base.authenticate = &yagl_wayland_display_authenticate;
+ dpy->base.wrap_window = &yagl_wayland_display_wrap_window;
+ dpy->base.wrap_pixmap = &yagl_wayland_display_wrap_pixmap;
+ dpy->base.create_pixmap = &yagl_wayland_display_create_pixmap;
+ dpy->base.create_image = &yagl_wayland_display_create_image;
+ dpy->base.get_visual = &yagl_wayland_display_get_visual;
+ dpy->base.destroy = &yagl_wayland_display_destroy;
+
+ YAGL_LOG_FUNC_EXIT("display %p created", dpy);
+
+ return &dpy->base;
+
+fail:
+ free(dpy->drm_dev_name);
+ dpy->drm_dev_name = NULL;
+
+ if (dpy->drm_fd >= 0) {
+ close(dpy->drm_fd);
+ dpy->drm_fd = -1;
+ }
+
+ if (dpy->wl_drm) {
+ wl_drm_destroy(dpy->wl_drm);
+ dpy->wl_drm = NULL;
+ }
+
+ if (dpy->queue) {
+ wl_event_queue_destroy(dpy->queue);
+ dpy->queue = NULL;
+ }
+
+ yagl_free(dpy);
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return NULL;
+}
diff --git a/EGL/wayland/yagl_wayland_display.h b/EGL/wayland/yagl_wayland_display.h
new file mode 100644
index 0000000..15e8a76
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_display.h
@@ -0,0 +1,33 @@
+#ifndef _YAGL_WAYLAND_DISPLAY_H_
+#define _YAGL_WAYLAND_DISPLAY_H_
+
+#include "yagl_export.h"
+#include "yagl_native_display.h"
+#include <wayland-client.h>
+
+#define YAGL_WAYLAND_DPY(os_dpy) ((struct wl_display*)(os_dpy))
+
+struct wl_drm;
+
+struct yagl_wayland_display
+{
+ struct yagl_native_display base;
+
+ struct wl_event_queue *queue;
+
+ struct wl_registry *registry;
+
+ struct wl_drm *wl_drm;
+
+ char *drm_dev_name;
+
+ int drm_fd;
+
+ int authenticated;
+};
+
+struct yagl_native_display
+ *yagl_wayland_display_create(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy);
+
+#endif
diff --git a/EGL/wayland/yagl_wayland_platform.c b/EGL/wayland/yagl_wayland_platform.c
new file mode 100644
index 0000000..b0e4d96
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_platform.c
@@ -0,0 +1,32 @@
+#include "yagl_wayland_platform.h"
+#include "yagl_wayland_display.h"
+#include "yagl_native_platform.h"
+#include "EGL/egl.h"
+#include <wayland-client.h>
+
+static int yagl_wayland_platform_probe(yagl_os_display os_dpy)
+{
+ void *first_pointer;
+
+ if (os_dpy == (yagl_os_display)EGL_DEFAULT_DISPLAY) {
+ return 0;
+ }
+
+ first_pointer = *(void**)os_dpy;
+
+ return (first_pointer == &wl_display_interface);
+}
+
+static struct yagl_native_display
+ *yagl_wayland_wrap_display(yagl_os_display os_dpy,
+ int enable_drm)
+{
+ return yagl_wayland_display_create(&yagl_wayland_platform, os_dpy);
+}
+
+struct yagl_native_platform yagl_wayland_platform =
+{
+ .pixmaps_supported = 0,
+ .probe = yagl_wayland_platform_probe,
+ .wrap_display = yagl_wayland_wrap_display
+};
diff --git a/EGL/wayland/yagl_wayland_platform.h b/EGL/wayland/yagl_wayland_platform.h
new file mode 100644
index 0000000..fb7032f
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_platform.h
@@ -0,0 +1,10 @@
+#ifndef _YAGL_WAYLAND_PLATFORM_H_
+#define _YAGL_WAYLAND_PLATFORM_H_
+
+#include "yagl_export.h"
+
+struct yagl_native_platform;
+
+extern struct yagl_native_platform yagl_wayland_platform;
+
+#endif
diff --git a/EGL/wayland/yagl_wayland_window.c b/EGL/wayland/yagl_wayland_window.c
new file mode 100644
index 0000000..5e159e2
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_window.c
@@ -0,0 +1,407 @@
+#include "yagl_wayland_window.h"
+#include "yagl_wayland_display.h"
+#include "yagl_log.h"
+#include "yagl_malloc.h"
+#include "yagl_wayland_egl.h"
+#include "wayland-drm.h"
+#include "wayland-drm-client-protocol.h"
+#include "vigs.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+static void yagl_wayland_window_buffer_release(void *data,
+ struct wl_buffer *buffer)
+{
+ struct yagl_wayland_window *window = data;
+ int i;
+
+ for (i = 0;
+ i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
+ ++i) {
+ if (window->color_buffers[i].wl_buffer == buffer) {
+ /*
+ * The buffer is still in the pool, just unlock,
+ * don't destroy it.
+ */
+ window->color_buffers[i].locked = 0;
+ return;
+ }
+ }
+
+ /*
+ * Buffer is not in the pool, drop it.
+ */
+ wl_buffer_destroy(buffer);
+}
+
+static struct wl_buffer_listener yagl_wayland_window_buffer_listener =
+{
+ yagl_wayland_window_buffer_release
+};
+
+static void yagl_wayland_window_frame_done(void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ struct yagl_wayland_window *window = data;
+
+ window->frame_callback = NULL;
+ wl_callback_destroy(callback);
+}
+
+static struct wl_callback_listener yagl_wayland_window_frame_listener =
+{
+ yagl_wayland_window_frame_done
+};
+
+static int yagl_wayland_window_lock_back(struct yagl_wayland_window *window)
+{
+ struct yagl_wayland_display *dpy = (struct yagl_wayland_display*)window->base.dpy;
+ struct wl_display *wl_dpy = YAGL_WAYLAND_DPY(dpy->base.os_dpy);
+ int i, ret;
+
+ /*
+ * There might be a buffer release already queued that wasn't processed.
+ */
+ wl_display_dispatch_queue_pending(wl_dpy, dpy->queue);
+
+ if (!window->back) {
+ for (i = 0;
+ i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
+ ++i) {
+ if (window->color_buffers[i].locked) {
+ continue;
+ }
+ if (!window->back) {
+ window->back = &window->color_buffers[i];
+ } else if (!window->back->drm_sfc) {
+ /*
+ * Prefer buffers with DRM surfaces allocated.
+ */
+ window->back = &window->color_buffers[i];
+ }
+ }
+ }
+
+ if (!window->back) {
+ return 0;
+ }
+
+ if (!window->back->drm_sfc) {
+ ret = vigs_drm_surface_create(dpy->base.drm_dev,
+ window->width,
+ window->height,
+ (window->width * 4),
+ vigs_drm_surface_bgrx8888,
+ &window->back->drm_sfc);
+
+ if (ret != 0) {
+ fprintf(stderr,
+ "wayland: Unable to create DRM surface(%ux%u): %s\n",
+ window->width, window->height,
+ strerror(-ret));
+ window->back->drm_sfc = NULL;
+ }
+ }
+
+ if (!window->back->drm_sfc) {
+ return 0;
+ }
+
+ window->back->locked = 1;
+
+ return 1;
+}
+
+static void yagl_wayland_window_resize(struct wl_egl_window *egl_window,
+ void *user_data)
+{
+ struct yagl_wayland_window *window = user_data;
+
+ YAGL_LOG_FUNC_SET(yagl_wayland_window_resize);
+
+ ++window->base.stamp;
+
+ YAGL_LOG_DEBUG("window %p resized, stamp = %u",
+ egl_window, window->base.stamp);
+}
+
+static int yagl_wayland_window_get_buffer(struct yagl_native_drawable *drawable,
+ yagl_native_attachment attachment,
+ uint32_t *buffer_name,
+ struct vigs_drm_surface **buffer_sfc)
+{
+ struct yagl_wayland_window *window = (struct yagl_wayland_window*)drawable;
+ struct wl_egl_window *egl_window = YAGL_WAYLAND_WINDOW(drawable->os_drawable);
+ int i;
+
+ YAGL_LOG_FUNC_SET(yagl_wayland_window_get_buffer);
+
+ switch (attachment) {
+ case yagl_native_attachment_back:
+ break;
+ case yagl_native_attachment_front:
+ default:
+ YAGL_LOG_ERROR("Bad attachment %u", attachment);
+ return 0;
+ }
+
+ if ((window->width != egl_window->width) ||
+ (window->height != egl_window->height)) {
+ for (i = 0;
+ i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
+ ++i) {
+ if (window->color_buffers[i].wl_buffer &&
+ !window->color_buffers[i].locked) {
+ wl_buffer_destroy(window->color_buffers[i].wl_buffer);
+ }
+ if (window->color_buffers[i].drm_sfc) {
+ vigs_drm_gem_unref(&window->color_buffers[i].drm_sfc->gem);
+ }
+ window->color_buffers[i].wl_buffer = NULL;
+ window->color_buffers[i].drm_sfc = NULL;
+ window->color_buffers[i].locked = 0;
+ }
+
+ window->width = egl_window->width;
+ window->height = egl_window->height;
+ }
+
+ window->dx = egl_window->dx;
+ window->dy = egl_window->dy;
+
+ if (!yagl_wayland_window_lock_back(window)) {
+ YAGL_LOG_ERROR("Cannot lock back for egl_window %p", egl_window);
+ return 0;
+ }
+
+ /*
+ * What this does is handles the case when there was triple buffering
+ * for some period of time and now we're back to double buffering.
+ * Since we're back to double buffering we can free buffers
+ * in order not to waste memory.
+ *
+ * Some detailed explanation since it's not that trivial: When triple
+ * buffering is in place we'll allocate all 3 buffers in 'color_buffers',
+ * the release code only sets 'locked' to 0, it doesn't destroy the buffers,
+ * so they could be reused. So, with triple buffering all 3 buffers will be
+ * locked all the time, but once the "pressure" on the compositor will
+ * lower it'll release the excess buffer and here we just check for that
+ * excess buffer and destroy it, so we won't waste memory in vain.
+ */
+ for (i = 0;
+ i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
+ ++i) {
+ if (window->color_buffers[i].wl_buffer &&
+ !window->color_buffers[i].locked) {
+ wl_buffer_destroy(window->color_buffers[i].wl_buffer);
+ vigs_drm_gem_unref(&window->color_buffers[i].drm_sfc->gem);
+ window->color_buffers[i].wl_buffer = NULL;
+ window->color_buffers[i].drm_sfc = NULL;
+ }
+ }
+
+ vigs_drm_gem_ref(&window->back->drm_sfc->gem);
+
+ *buffer_sfc = window->back->drm_sfc;
+
+ return 1;
+}
+
+static void yagl_wayland_window_swap_buffers(struct yagl_native_drawable *drawable)
+{
+ struct yagl_wayland_window *window = (struct yagl_wayland_window*)drawable;
+ struct yagl_wayland_display *dpy = (struct yagl_wayland_display*)drawable->dpy;
+ struct wl_display *wl_dpy = YAGL_WAYLAND_DPY(drawable->dpy->os_dpy);
+ struct wl_egl_window *egl_window = YAGL_WAYLAND_WINDOW(drawable->os_drawable);
+ int ret = 0;
+
+ YAGL_LOG_FUNC_SET(yagl_wayland_window_swap_buffers);
+
+ /*
+ * Throttle.
+ */
+ while (window->frame_callback && (ret != -1)) {
+ ret = wl_display_dispatch_queue(wl_dpy, dpy->queue);
+ }
+
+ if (ret < 0) {
+ /*
+ * Is this possible ?
+ */
+ return;
+ }
+
+ window->frame_callback = wl_surface_frame(egl_window->surface);
+ wl_callback_add_listener(window->frame_callback,
+ &yagl_wayland_window_frame_listener,
+ window);
+ wl_proxy_set_queue((struct wl_proxy*)window->frame_callback, dpy->queue);
+
+ /*
+ * Make sure we have a back buffer in case we're swapping without ever
+ * rendering.
+ */
+ if (!yagl_wayland_window_lock_back(window)) {
+ YAGL_LOG_ERROR("Cannot lock back for egl_window %p", egl_window);
+ return;
+ }
+
+ window->front = window->back;
+ window->back = NULL;
+
+ if (!window->front->wl_buffer) {
+ ret = vigs_drm_gem_get_name(&window->front->drm_sfc->gem);
+
+ if (ret != 0) {
+ fprintf(stderr,
+ "wayland: Unable to get GEM name: %s\n", strerror(-ret));
+ }
+
+ window->front->wl_buffer =
+ wl_drm_create_buffer(dpy->wl_drm,
+ window->front->drm_sfc->gem.name,
+ window->width,
+ window->height,
+ window->front->drm_sfc->stride,
+ WL_DRM_FORMAT_XRGB8888);
+ wl_proxy_set_queue((struct wl_proxy*)window->front->wl_buffer,
+ dpy->queue);
+ wl_buffer_add_listener(window->front->wl_buffer,
+ &yagl_wayland_window_buffer_listener,
+ window);
+ }
+
+ wl_surface_attach(egl_window->surface,
+ window->front->wl_buffer,
+ window->dx,
+ window->dy);
+
+ egl_window->attached_width = window->width;
+ egl_window->attached_height = window->height;
+
+ /*
+ * Reset resize growing parameters.
+ */
+ window->dx = 0;
+ window->dy = 0;
+
+ wl_surface_damage(egl_window->surface, 0, 0,
+ window->width,
+ window->height);
+
+ wl_surface_commit(egl_window->surface);
+
+ ++drawable->stamp;
+}
+
+static void yagl_wayland_window_wait(struct yagl_native_drawable *drawable,
+ uint32_t width,
+ uint32_t height)
+{
+}
+
+static void yagl_wayland_window_copy_to_pixmap(struct yagl_native_drawable *drawable,
+ yagl_os_pixmap os_pixmap,
+ uint32_t from_x,
+ uint32_t from_y,
+ uint32_t to_x,
+ uint32_t to_y,
+ uint32_t width,
+ uint32_t height)
+{
+}
+
+static void yagl_wayland_window_set_swap_interval(struct yagl_native_drawable *drawable,
+ int interval)
+{
+}
+
+static void yagl_wayland_window_get_geometry(struct yagl_native_drawable *drawable,
+ uint32_t *width,
+ uint32_t *height,
+ uint32_t *depth)
+{
+}
+
+static struct yagl_native_image
+ *yagl_wayland_window_get_image(struct yagl_native_drawable *drawable,
+ uint32_t width,
+ uint32_t height)
+{
+ return NULL;
+}
+
+static void yagl_wayland_window_destroy(struct yagl_native_drawable *drawable)
+{
+ struct yagl_wayland_window *window = (struct yagl_wayland_window*)drawable;
+ struct wl_egl_window *egl_window = YAGL_WAYLAND_WINDOW(drawable->os_drawable);
+ int i;
+
+ for (i = 0;
+ i < sizeof(window->color_buffers)/sizeof(window->color_buffers[0]);
+ ++i) {
+ if (window->color_buffers[i].wl_buffer) {
+ wl_buffer_destroy(window->color_buffers[i].wl_buffer);
+ }
+ if (window->color_buffers[i].drm_sfc) {
+ vigs_drm_gem_unref(&window->color_buffers[i].drm_sfc->gem);
+ }
+ window->color_buffers[i].wl_buffer = NULL;
+ window->color_buffers[i].drm_sfc = NULL;
+ window->color_buffers[i].locked = 0;
+ }
+
+ if (window->frame_callback) {
+ wl_callback_destroy(window->frame_callback);
+ }
+
+ yagl_native_drawable_cleanup(drawable);
+
+ egl_window->resize_callback = NULL;
+ egl_window->user_data = NULL;
+
+ yagl_free(drawable);
+}
+
+struct yagl_native_drawable
+ *yagl_wayland_window_create(struct yagl_native_display *dpy,
+ yagl_os_window os_window)
+{
+ struct wl_egl_window *egl_window = YAGL_WAYLAND_WINDOW(os_window);
+ struct yagl_wayland_window *window;
+
+ YAGL_LOG_FUNC_SET(yagl_wayland_window_create);
+
+ if (egl_window->resize_callback || egl_window->user_data) {
+ YAGL_LOG_ERROR("wl_egl_window %p already wrapped", egl_window);
+ return NULL;
+ }
+
+ window = yagl_malloc0(sizeof(*window));
+
+ yagl_native_drawable_init(&window->base, dpy, os_window);
+
+ window->base.get_buffer = &yagl_wayland_window_get_buffer;
+ window->base.swap_buffers = &yagl_wayland_window_swap_buffers;
+ window->base.wait = &yagl_wayland_window_wait;
+ window->base.copy_to_pixmap = &yagl_wayland_window_copy_to_pixmap;
+ window->base.set_swap_interval = &yagl_wayland_window_set_swap_interval;
+ window->base.get_geometry = &yagl_wayland_window_get_geometry;
+ window->base.get_image = &yagl_wayland_window_get_image;
+ window->base.destroy = &yagl_wayland_window_destroy;
+
+ /*
+ * First comparison against real window
+ * dimensions must always fail.
+ */
+ window->width = -1;
+ window->height = -1;
+
+ egl_window->resize_callback = &yagl_wayland_window_resize;
+ egl_window->user_data = window;
+
+ return &window->base;
+}
diff --git a/EGL/wayland/yagl_wayland_window.h b/EGL/wayland/yagl_wayland_window.h
new file mode 100644
index 0000000..8ec4fc8
--- /dev/null
+++ b/EGL/wayland/yagl_wayland_window.h
@@ -0,0 +1,36 @@
+#ifndef _YAGL_WAYLAND_WINDOW_H_
+#define _YAGL_WAYLAND_WINDOW_H_
+
+#include "yagl_export.h"
+#include "yagl_native_drawable.h"
+#include <wayland-client.h>
+
+#define YAGL_WAYLAND_WINDOW(os_window) ((struct wl_egl_window*)(os_window))
+
+struct vigs_drm_surface;
+
+struct yagl_wayland_window
+{
+ struct yagl_native_drawable base;
+
+ struct
+ {
+ struct vigs_drm_surface *drm_sfc;
+ struct wl_buffer *wl_buffer;
+ int locked;
+ } color_buffers[3], *back, *front;
+
+ int width;
+ int height;
+
+ int dx;
+ int dy;
+
+ struct wl_callback *frame_callback;
+};
+
+struct yagl_native_drawable
+ *yagl_wayland_window_create(struct yagl_native_display *dpy,
+ yagl_os_drawable os_drawable);
+
+#endif
diff --git a/EGL/x11/yagl_x11_display.c b/EGL/x11/yagl_x11_display.c
index f92218f..5d6a03e 100644
--- a/EGL/x11/yagl_x11_display.c
+++ b/EGL/x11/yagl_x11_display.c
@@ -11,18 +11,31 @@
#include <stdio.h>
#include <stdlib.h>
-static int yagl_x11_display_dri2_init(Display *x_dpy)
+static int yagl_x11_display_dri2_authenticate(Display *x_dpy, uint32_t id)
+{
+ if (!yagl_DRI2Authenticate(x_dpy,
+ RootWindow(x_dpy, DefaultScreen(x_dpy)),
+ id)) {
+ fprintf(stderr, "Critical error! Failed to DRI2Authenticate on YaGL display, DRI2 not enabled ?\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static int yagl_x11_display_dri2_init(Display *x_dpy, char **dri_device)
{
int ret;
int event_base, error_base;
int dri_major, dri_minor;
char *dri_driver = NULL;
- char *dri_device = NULL;
int drm_fd = -1;
drm_magic_t magic;
YAGL_LOG_FUNC_SET(eglGetDisplay);
+ *dri_device = NULL;
+
if (!yagl_DRI2QueryExtension(x_dpy, &event_base, &error_base)) {
fprintf(stderr, "Critical error! Failed to DRI2QueryExtension on YaGL display, DRI2 not enabled ?\n");
goto fail;
@@ -42,18 +55,18 @@ static int yagl_x11_display_dri2_init(Display *x_dpy)
if (!yagl_DRI2Connect(x_dpy,
RootWindow(x_dpy, DefaultScreen(x_dpy)),
&dri_driver,
- &dri_device)) {
+ dri_device)) {
fprintf(stderr, "Critical error! Failed to DRI2Connect on YaGL display, DRI2 not enabled ?\n");
goto fail;
}
YAGL_LOG_TRACE("DRI2Connect returned %s %s",
- dri_driver, dri_device);
+ dri_driver, *dri_device);
- drm_fd = open(dri_device, O_RDWR);
+ drm_fd = open(*dri_device, O_RDWR);
if (drm_fd < 0) {
- fprintf(stderr, "Critical error! Failed to open(\"%s\"): %s\n", dri_device, strerror(errno));
+ fprintf(stderr, "Critical error! Failed to open(\"%s\"): %s\n", *dri_device, strerror(errno));
goto fail;
}
@@ -66,10 +79,7 @@ static int yagl_x11_display_dri2_init(Display *x_dpy)
goto fail;
}
- if (!yagl_DRI2Authenticate(x_dpy,
- RootWindow(x_dpy, DefaultScreen(x_dpy)),
- magic)) {
- fprintf(stderr, "Critical error! Failed to DRI2Authenticate on YaGL display, DRI2 not enabled ?\n");
+ if (!yagl_x11_display_dri2_authenticate(x_dpy, magic)) {
goto fail;
}
@@ -80,17 +90,25 @@ fail:
close(drm_fd);
drm_fd = -1;
}
+ if (*dri_device) {
+ Xfree(*dri_device);
+ }
out:
if (dri_driver) {
Xfree(dri_driver);
}
- if (dri_device) {
- Xfree(dri_device);
- }
return drm_fd;
}
+static int yagl_x11_display_authenticate(struct yagl_native_display *dpy,
+ uint32_t id)
+{
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+
+ return yagl_x11_display_dri2_authenticate(x_dpy, id);
+}
+
static struct yagl_native_drawable
*yagl_x11_display_wrap_window(struct yagl_native_display *dpy,
yagl_os_window os_window)
@@ -194,6 +212,7 @@ struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform
int xminor;
Bool pixmaps;
struct vigs_drm_device *drm_dev = NULL;
+ char *dri_device = NULL;
int ret;
YAGL_LOG_FUNC_SET(eglGetDisplay);
@@ -215,7 +234,7 @@ struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform
pixmaps);
if (enable_drm) {
- int drm_fd = yagl_x11_display_dri2_init(x_dpy);
+ int drm_fd = yagl_x11_display_dri2_init(x_dpy, &dri_device);
if (drm_fd < 0) {
yagl_free(dpy);
@@ -229,6 +248,7 @@ struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform
"Critical error! vigs_drm_device_create failed: %s\n",
strerror(-ret));
close(drm_fd);
+ Xfree(dri_device);
yagl_free(dpy);
return NULL;
}
@@ -237,8 +257,10 @@ struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform
yagl_native_display_init(&dpy->base,
platform,
os_dpy,
- drm_dev);
+ drm_dev,
+ dri_device);
+ dpy->base.authenticate = &yagl_x11_display_authenticate;
dpy->base.wrap_window = &yagl_x11_display_wrap_window;
dpy->base.wrap_pixmap = &yagl_x11_display_wrap_pixmap;
dpy->base.create_pixmap = &yagl_x11_display_create_pixmap;
@@ -246,5 +268,9 @@ struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform
dpy->base.get_visual = &yagl_x11_display_get_visual;
dpy->base.destroy = &yagl_x11_display_destroy;
+ if (dri_device) {
+ Xfree(dri_device);
+ }
+
return &dpy->base;
}
diff --git a/EGL/x11/yagl_x11_platform.c b/EGL/x11/yagl_x11_platform.c
index 6840adf..2633eda 100644
--- a/EGL/x11/yagl_x11_platform.c
+++ b/EGL/x11/yagl_x11_platform.c
@@ -50,6 +50,7 @@ static struct yagl_native_display
struct yagl_native_platform yagl_x11_platform =
{
+ .pixmaps_supported = 1,
.probe = yagl_x11_platform_probe,
.wrap_display = yagl_x11_wrap_display
};
diff --git a/EGL/yagl_backend.h b/EGL/yagl_backend.h
index d326ec6..f884f0b 100644
--- a/EGL/yagl_backend.h
+++ b/EGL/yagl_backend.h
@@ -11,6 +11,7 @@ struct yagl_surface;
struct yagl_image;
struct yagl_native_platform;
struct yagl_native_drawable;
+struct wl_resource;
struct yagl_backend
{
@@ -41,10 +42,15 @@ struct yagl_backend
/*
* Takes ownership of 'native_pixmap'.
*/
- struct yagl_image *(*create_image)(struct yagl_display */*dpy*/,
- yagl_host_handle /*host_context*/,
- struct yagl_native_drawable */*native_pixmap*/,
- const EGLint */*attrib_list*/);
+ struct yagl_image *(*create_image_pixmap)(struct yagl_display */*dpy*/,
+ yagl_host_handle /*host_context*/,
+ struct yagl_native_drawable */*native_pixmap*/,
+ const EGLint */*attrib_list*/);
+
+ struct yagl_image *(*create_image_wl_buffer)(struct yagl_display */*dpy*/,
+ yagl_host_handle /*host_context*/,
+ struct wl_resource */*buffer*/,
+ const EGLint */*attrib_list*/);
void (*destroy)(struct yagl_backend */*backend*/);
diff --git a/EGL/yagl_display.c b/EGL/yagl_display.c
index f2bcb27..d7f6561 100644
--- a/EGL/yagl_display.c
+++ b/EGL/yagl_display.c
@@ -6,9 +6,21 @@
#include "yagl_context.h"
#include "yagl_image.h"
#include "yagl_native_display.h"
+#include "yagl_native_platform.h"
+#include "yagl_malloc.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
+#include <string.h>
+
+#define YAGL_EGL_BASE_EXTENSIONS "EGL_KHR_image_base " \
+ "EGL_KHR_lock_surface "
+
+#define YAGL_EGL_PIXMAPS_EXTENSIONS "EGL_KHR_image " \
+ "EGL_KHR_image_pixmap " \
+ "EGL_NOK_texture_from_pixmap "
+
+#define YAGL_EGL_WL_BIND_WAYLAND_DISPLAY_EXTENSIONS "EGL_WL_bind_wayland_display "
static pthread_once_t g_displays_init = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_displays_mutex;
@@ -218,6 +230,43 @@ void yagl_display_terminate(struct yagl_display *dpy)
assert(yagl_list_empty(&tmp_list));
}
+const char *yagl_display_get_extensions(struct yagl_display *dpy)
+{
+ if (!dpy) {
+ return YAGL_EGL_BASE_EXTENSIONS;
+ }
+
+ pthread_mutex_lock(&dpy->mutex);
+
+ if (!dpy->extensions) {
+ uint32_t len = strlen(YAGL_EGL_BASE_EXTENSIONS);
+
+ if (dpy->native_dpy->platform->pixmaps_supported) {
+ len += strlen(YAGL_EGL_PIXMAPS_EXTENSIONS);
+ }
+
+ if (dpy->native_dpy->WL_bind_wayland_display_supported) {
+ len += strlen(YAGL_EGL_WL_BIND_WAYLAND_DISPLAY_EXTENSIONS);
+ }
+
+ dpy->extensions = yagl_malloc(len + 1);
+
+ strcpy(dpy->extensions, YAGL_EGL_BASE_EXTENSIONS);
+
+ if (dpy->native_dpy->platform->pixmaps_supported) {
+ strcat(dpy->extensions, YAGL_EGL_PIXMAPS_EXTENSIONS);
+ }
+
+ if (dpy->native_dpy->WL_bind_wayland_display_supported) {
+ strcat(dpy->extensions, YAGL_EGL_WL_BIND_WAYLAND_DISPLAY_EXTENSIONS);
+ }
+ }
+
+ pthread_mutex_unlock(&dpy->mutex);
+
+ return dpy->extensions;
+}
+
int yagl_display_surface_add(struct yagl_display *dpy,
struct yagl_surface *sfc)
{
@@ -335,12 +384,11 @@ int yagl_display_image_add(struct yagl_display *dpy,
struct yagl_image *image)
{
struct yagl_resource *res = NULL;
- EGLImageKHR handle = yagl_image_get_handle(image);
pthread_mutex_lock(&dpy->mutex);
yagl_list_for_each(struct yagl_resource, res, &dpy->images, list) {
- if (yagl_image_get_handle((struct yagl_image*)res) == handle) {
+ if (((struct yagl_image*)res)->client_handle == image->client_handle) {
pthread_mutex_unlock(&dpy->mutex);
return 0;
}
@@ -362,7 +410,7 @@ struct yagl_image *yagl_display_image_acquire(struct yagl_display *dpy,
pthread_mutex_lock(&dpy->mutex);
yagl_list_for_each(struct yagl_resource, res, &dpy->images, list) {
- if (yagl_image_get_handle((struct yagl_image*)res) == handle) {
+ if (((struct yagl_image*)res)->client_handle == handle) {
yagl_resource_acquire(res);
pthread_mutex_unlock(&dpy->mutex);
return (struct yagl_image*)res;
@@ -382,7 +430,7 @@ int yagl_display_image_remove(struct yagl_display *dpy,
pthread_mutex_lock(&dpy->mutex);
yagl_list_for_each(struct yagl_resource, res, &dpy->images, list) {
- if (yagl_image_get_handle((struct yagl_image*)res) == handle) {
+ if (((struct yagl_image*)res)->client_handle == handle) {
yagl_list_remove(&res->list);
yagl_resource_release(res);
pthread_mutex_unlock(&dpy->mutex);
diff --git a/EGL/yagl_display.h b/EGL/yagl_display.h
index dae320a..3c2903e 100644
--- a/EGL/yagl_display.h
+++ b/EGL/yagl_display.h
@@ -29,6 +29,8 @@ struct yagl_display
int prepared;
+ char *extensions;
+
struct yagl_list surfaces;
struct yagl_list contexts;
@@ -59,6 +61,11 @@ int yagl_display_is_prepared(struct yagl_display *dpy);
void yagl_display_terminate(struct yagl_display *dpy);
/*
+ * 'dpy' can be NULL here.
+ */
+const char *yagl_display_get_extensions(struct yagl_display *dpy);
+
+/*
* Surfaces.
* @{
*/
diff --git a/EGL/yagl_egl_calls.c b/EGL/yagl_egl_calls.c
index f9aac39..14b6613 100644
--- a/EGL/yagl_egl_calls.c
+++ b/EGL/yagl_egl_calls.c
@@ -202,13 +202,13 @@ out:
return ret;
}
-YAGL_API const char* eglQueryString(EGLDisplay dpy, EGLint name)
+YAGL_API const char* eglQueryString(EGLDisplay dpy_, EGLint name)
{
const char *str = NULL;
YAGL_LOG_FUNC_ENTER(eglQueryString,
"dpy = %u, name = %d",
- (yagl_host_handle)dpy,
+ (yagl_host_handle)dpy_,
name);
switch (name) {
@@ -222,11 +222,7 @@ YAGL_API const char* eglQueryString(EGLDisplay dpy, EGLint name)
str = "OpenGL_ES";
break;
case EGL_EXTENSIONS:
- str = "EGL_KHR_image_base "
- "EGL_KHR_image "
- "EGL_KHR_image_pixmap "
- "EGL_NOK_texture_from_pixmap "
- "EGL_KHR_lock_surface ";
+ str = yagl_display_get_extensions(yagl_display_get(dpy_));
break;
default:
YAGL_SET_ERR(EGL_BAD_PARAMETER);
@@ -362,10 +358,6 @@ YAGL_API EGLBoolean eglGetConfigAttrib( EGLDisplay dpy_,
}
switch (attribute) {
- case EGL_Y_INVERTED_NOK:
- *value = yagl_get_backend()->y_inverted;
- ret = EGL_TRUE;
- break;
case EGL_NATIVE_VISUAL_ID:
case EGL_NATIVE_VISUAL_TYPE:
if (!dpy->native_dpy->get_visual(dpy->native_dpy,
@@ -385,6 +377,13 @@ YAGL_API EGLBoolean eglGetConfigAttrib( EGLDisplay dpy_,
ret = EGL_TRUE;
break;
+ case EGL_Y_INVERTED_NOK:
+ if (dpy->native_dpy->platform->pixmaps_supported) {
+ *value = yagl_get_backend()->y_inverted;
+ ret = EGL_TRUE;
+ break;
+ }
+ /* Fall through. */
default:
do {
yagl_mem_probe_write_EGLint(value);
@@ -1357,6 +1356,7 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
struct yagl_display *dpy = NULL;
struct yagl_native_drawable *native_buffer = NULL;
struct yagl_image *image = NULL;
+ int i = 0;
YAGL_LOG_FUNC_ENTER(eglCreateImageKHR,
"dpy = %u, ctx = %u, target = %u, buffer = %p",
@@ -1365,11 +1365,6 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
target,
buffer);
- if (target != EGL_NATIVE_PIXMAP_KHR) {
- YAGL_SET_ERR(EGL_BAD_PARAMETER);
- goto out;
- }
-
if (!buffer) {
YAGL_SET_ERR(EGL_BAD_PARAMETER);
goto out;
@@ -1379,21 +1374,78 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
goto out;
}
- native_buffer = dpy->native_dpy->wrap_pixmap(dpy->native_dpy,
- (yagl_os_pixmap)buffer);
+ switch (target) {
+ case EGL_NATIVE_PIXMAP_KHR:
+ if (!dpy->native_dpy->platform->pixmaps_supported) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
- if (!native_buffer) {
- goto out;
- }
+ if (attrib_list) {
+ while (attrib_list[i] != EGL_NONE) {
+ switch (attrib_list[i]) {
+ case EGL_IMAGE_PRESERVED_KHR:
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+
+ i += 2;
+ }
+ }
+
+ native_buffer = dpy->native_dpy->wrap_pixmap(dpy->native_dpy,
+ (yagl_os_pixmap)buffer);
- image = yagl_get_backend()->create_image(dpy,
- (yagl_host_handle)ctx,
- native_buffer,
- attrib_list);
+ if (!native_buffer) {
+ goto out;
+ }
- if (!image) {
- native_buffer->destroy(native_buffer);
- native_buffer = NULL;
+ image = yagl_get_backend()->create_image_pixmap(dpy,
+ (yagl_host_handle)ctx,
+ native_buffer,
+ attrib_list);
+
+ if (!image) {
+ native_buffer->destroy(native_buffer);
+ goto out;
+ }
+
+ break;
+ case EGL_WAYLAND_BUFFER_WL:
+ if (!dpy->native_dpy->WL_bind_wayland_display_supported) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ if (attrib_list) {
+ while (attrib_list[i] != EGL_NONE) {
+ switch (attrib_list[i]) {
+ case EGL_IMAGE_PRESERVED_KHR:
+ case EGL_WAYLAND_PLANE_WL:
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_ATTRIBUTE);
+ goto out;
+ }
+
+ i += 2;
+ }
+ }
+
+ image = yagl_get_backend()->create_image_wl_buffer(dpy,
+ (yagl_host_handle)ctx,
+ (struct wl_resource*)buffer,
+ attrib_list);
+
+ if (!image) {
+ goto out;
+ }
+
+ break;
+ default:
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
goto out;
}
@@ -1406,7 +1458,7 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
goto out;
}
- ret = yagl_image_get_handle(image);
+ ret = image->client_handle;
out:
yagl_image_release(image);
@@ -1560,6 +1612,116 @@ out:
return res;
}
+#ifdef YAGL_PLATFORM_WAYLAND
+struct wl_display;
+struct wl_resource;
+
+YAGL_API EGLBoolean eglBindWaylandDisplayWL(EGLDisplay dpy_,
+ struct wl_display *display)
+{
+ EGLBoolean res = EGL_FALSE;
+ struct yagl_display *dpy = NULL;
+
+ YAGL_LOG_FUNC_ENTER(eglBindWaylandDisplayWL,
+ "dpy = %u, display = %p",
+ (yagl_host_handle)dpy_,
+ display);
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!display) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ if (!dpy->native_dpy->WL_bind_wayland_display_supported) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ res = yagl_native_display_bind_wl_display(dpy->native_dpy, display);
+
+out:
+ YAGL_LOG_FUNC_EXIT("%d", res);
+
+ return res;
+}
+
+YAGL_API EGLBoolean eglUnbindWaylandDisplayWL(EGLDisplay dpy_,
+ struct wl_display *display)
+{
+ EGLBoolean res = EGL_FALSE;
+ struct yagl_display *dpy = NULL;
+
+ YAGL_LOG_FUNC_ENTER(eglUnbindWaylandDisplayWL,
+ "dpy = %u, display = %p",
+ (yagl_host_handle)dpy_,
+ display);
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!display) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ if (!dpy->native_dpy->WL_bind_wayland_display_supported) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ res = yagl_native_display_unbind_wl_display(dpy->native_dpy);
+
+out:
+ YAGL_LOG_FUNC_EXIT("%d", res);
+
+ return res;
+}
+
+YAGL_API EGLBoolean eglQueryWaylandBufferWL(EGLDisplay dpy_,
+ struct wl_resource *buffer,
+ EGLint attribute,
+ EGLint *value)
+{
+ EGLBoolean res = EGL_FALSE;
+ struct yagl_display *dpy = NULL;
+
+ YAGL_LOG_FUNC_ENTER(eglQueryWaylandBufferWL,
+ "dpy = %u, buffer = %p, attribute = 0x%X",
+ (yagl_host_handle)dpy_,
+ buffer,
+ attribute);
+
+ if (!yagl_validate_display(dpy_, &dpy)) {
+ goto out;
+ }
+
+ if (!buffer) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ if (!dpy->native_dpy->WL_bind_wayland_display_supported) {
+ YAGL_SET_ERR(EGL_BAD_PARAMETER);
+ goto out;
+ }
+
+ res = yagl_native_display_query_wl_buffer(dpy->native_dpy,
+ buffer,
+ attribute,
+ value);
+
+out:
+ YAGL_LOG_FUNC_EXIT("%d", res);
+
+ return res;
+}
+#endif
+
static __eglMustCastToProperFunctionPointerType yagl_get_gles1_proc_address(const char* procname)
{
void *handle = dlopen("libGLESv1_CM.so.1", RTLD_NOW|RTLD_GLOBAL);
diff --git a/EGL/yagl_image.c b/EGL/yagl_image.c
index becbdca..6eee963 100644
--- a/EGL/yagl_image.c
+++ b/EGL/yagl_image.c
@@ -11,30 +11,23 @@ static void yagl_gles_image_update(struct yagl_gles_image *image)
void yagl_image_init(struct yagl_image *image,
yagl_ref_destroy_func destroy_func,
- yagl_host_handle handle,
+ yagl_host_handle host_handle,
struct yagl_display *dpy,
- struct yagl_native_drawable *native_pixmap)
+ EGLImageKHR client_handle)
{
- yagl_resource_init(&image->res, destroy_func, handle);
+ yagl_resource_init(&image->res, destroy_func, host_handle);
image->dpy = dpy;
- image->native_pixmap = native_pixmap;
- image->gles_image.host_image = handle;
+ image->client_handle = client_handle;
+ image->gles_image.host_image = host_handle;
image->gles_image.update = &yagl_gles_image_update;
}
void yagl_image_cleanup(struct yagl_image *image)
{
- image->native_pixmap->destroy(image->native_pixmap);
- image->native_pixmap = NULL;
yagl_resource_cleanup(&image->res);
}
-EGLImageKHR yagl_image_get_handle(struct yagl_image *image)
-{
- return (EGLImageKHR)image->native_pixmap->os_drawable;
-}
-
void yagl_image_acquire(struct yagl_image *image)
{
if (image) {
diff --git a/EGL/yagl_image.h b/EGL/yagl_image.h
index cb14c54..42e561d 100644
--- a/EGL/yagl_image.h
+++ b/EGL/yagl_image.h
@@ -11,7 +11,6 @@
#include "yagl_gles_image.h"
struct yagl_display;
-struct yagl_native_drawable;
struct yagl_image
{
@@ -19,26 +18,21 @@ struct yagl_image
struct yagl_display *dpy;
- struct yagl_native_drawable *native_pixmap;
+ EGLImageKHR client_handle;
struct yagl_gles_image gles_image;
void (*update)(struct yagl_image */*image*/);
};
-/*
- * Takes ownership of 'native_pixmap'.
- */
void yagl_image_init(struct yagl_image *image,
yagl_ref_destroy_func destroy_func,
- yagl_host_handle handle,
+ yagl_host_handle host_handle,
struct yagl_display *dpy,
- struct yagl_native_drawable *native_pixmap);
+ EGLImageKHR client_handle);
void yagl_image_cleanup(struct yagl_image *image);
-EGLImageKHR yagl_image_get_handle(struct yagl_image *image);
-
/*
* Passing NULL won't hurt, this is for convenience.
*/
diff --git a/EGL/yagl_native_display.c b/EGL/yagl_native_display.c
index 12739ef..d9a7da3 100644
--- a/EGL/yagl_native_display.c
+++ b/EGL/yagl_native_display.c
@@ -1,16 +1,137 @@
#include "yagl_native_display.h"
+#include "yagl_log.h"
+#ifdef YAGL_PLATFORM_WAYLAND
+#include "wayland-drm.h"
+#endif
+#include "vigs.h"
+#include <string.h>
+#include <stdlib.h>
void yagl_native_display_init(struct yagl_native_display *dpy,
struct yagl_native_platform *platform,
yagl_os_display os_dpy,
- struct vigs_drm_device *drm_dev)
+ struct vigs_drm_device *drm_dev,
+ const char *drm_dev_name)
{
dpy->platform = platform;
dpy->os_dpy = os_dpy;
dpy->drm_dev = drm_dev;
+ if (drm_dev) {
+ dpy->drm_dev_name = strdup(drm_dev_name);
+ } else {
+ dpy->drm_dev_name = NULL;
+ }
+#ifdef YAGL_PLATFORM_WAYLAND
+ dpy->WL_bind_wayland_display_supported = (drm_dev ? 1 : 0);
+#else
+ dpy->WL_bind_wayland_display_supported = 0;
+#endif
}
void yagl_native_display_cleanup(struct yagl_native_display *dpy)
{
dpy->drm_dev = NULL;
+ free(dpy->drm_dev_name);
+ dpy->drm_dev_name = NULL;
}
+
+#ifdef YAGL_PLATFORM_WAYLAND
+static int yagl_native_display_wl_authenticate(void *user_data,
+ uint32_t id)
+{
+ struct yagl_native_display *dpy = user_data;
+
+ return dpy->authenticate(dpy, id);
+}
+
+static struct vigs_drm_surface
+ *yagl_native_display_wl_acquire_buffer(void *user_data, uint32_t name)
+{
+ struct yagl_native_display *dpy = user_data;
+ struct vigs_drm_surface *drm_sfc;
+ int ret;
+
+ YAGL_LOG_FUNC_SET(yagl_native_display_wl_acquire_buffer);
+
+ ret = vigs_drm_surface_open(dpy->drm_dev, name, &drm_sfc);
+
+ if (ret != 0) {
+ YAGL_LOG_ERROR("vigs_drm_surface_open failed for name %u: %s",
+ name,
+ strerror(-ret));
+ return NULL;
+ }
+
+ return drm_sfc;
+}
+
+static struct wayland_drm_callbacks wl_drm_callbacks =
+{
+ .authenticate = yagl_native_display_wl_authenticate,
+ .acquire_buffer = yagl_native_display_wl_acquire_buffer,
+};
+
+int yagl_native_display_bind_wl_display(struct yagl_native_display *dpy,
+ struct wl_display *wl_dpy)
+{
+ if (dpy->wl_server_drm) {
+ return 0;
+ }
+
+ dpy->wl_server_drm = wayland_drm_create(wl_dpy,
+ dpy->drm_dev_name,
+ &wl_drm_callbacks,
+ dpy);
+
+ return dpy->wl_server_drm ? 1 : 0;
+}
+
+int yagl_native_display_unbind_wl_display(struct yagl_native_display *dpy)
+{
+ if (!dpy->wl_server_drm) {
+ return 0;
+ }
+
+ wayland_drm_destroy(dpy->wl_server_drm);
+ dpy->wl_server_drm = NULL;
+
+ return 1;
+}
+
+int yagl_native_display_query_wl_buffer(struct yagl_native_display *dpy,
+ struct wl_resource *buffer,
+ EGLint attribute,
+ EGLint *value)
+{
+ struct wl_drm_buffer *drm_buffer = wayland_drm_get_buffer(buffer);
+
+ if (!drm_buffer) {
+ return 0;
+ }
+
+ switch (attribute) {
+ case EGL_TEXTURE_FORMAT:
+ switch (drm_buffer->drm_sfc->format) {
+ case vigs_drm_surface_bgrx8888:
+ *value = EGL_TEXTURE_RGB;
+ break;
+ case vigs_drm_surface_bgra8888:
+ *value = EGL_TEXTURE_RGBA;
+ break;
+ default:
+ return 0;
+ }
+ break;
+ case EGL_WIDTH:
+ *value = drm_buffer->drm_sfc->width;
+ break;
+ case EGL_HEIGHT:
+ *value = drm_buffer->drm_sfc->height;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+#endif
diff --git a/EGL/yagl_native_display.h b/EGL/yagl_native_display.h
index 2b16507..a34ecb8 100644
--- a/EGL/yagl_native_display.h
+++ b/EGL/yagl_native_display.h
@@ -3,12 +3,19 @@
#include "yagl_export.h"
#include "yagl_native_types.h"
+#include "EGL/egl.h"
struct yagl_native_platform;
struct yagl_native_drawable;
struct yagl_native_image;
struct vigs_drm_device;
+#ifdef YAGL_PLATFORM_WAYLAND
+struct wl_display;
+struct wl_resource;
+struct wl_drm;
+#endif
+
struct yagl_native_display
{
struct yagl_native_platform *platform;
@@ -16,6 +23,15 @@ struct yagl_native_display
yagl_os_display os_dpy;
struct vigs_drm_device *drm_dev;
+ char *drm_dev_name;
+
+ int WL_bind_wayland_display_supported;
+
+#ifdef YAGL_PLATFORM_WAYLAND
+ struct wl_drm *wl_server_drm;
+#endif
+
+ int (*authenticate)(struct yagl_native_display */*dpy*/, uint32_t /*id*/);
struct yagl_native_drawable *(*wrap_window)(struct yagl_native_display */*dpy*/,
yagl_os_window /*os_window*/);
@@ -43,8 +59,21 @@ struct yagl_native_display
void yagl_native_display_init(struct yagl_native_display *dpy,
struct yagl_native_platform *platform,
yagl_os_display os_dpy,
- struct vigs_drm_device *drm_dev);
+ struct vigs_drm_device *drm_dev,
+ const char *drm_dev_name);
void yagl_native_display_cleanup(struct yagl_native_display *dpy);
+#ifdef YAGL_PLATFORM_WAYLAND
+int yagl_native_display_bind_wl_display(struct yagl_native_display *dpy,
+ struct wl_display *wl_dpy);
+
+int yagl_native_display_unbind_wl_display(struct yagl_native_display *dpy);
+
+int yagl_native_display_query_wl_buffer(struct yagl_native_display *dpy,
+ struct wl_resource *buffer,
+ EGLint attribute,
+ EGLint *value);
+#endif
+
#endif
diff --git a/EGL/yagl_native_platform.c b/EGL/yagl_native_platform.c
index 3fd8ada..18bda1d 100644
--- a/EGL/yagl_native_platform.c
+++ b/EGL/yagl_native_platform.c
@@ -5,6 +5,9 @@
#ifdef YAGL_PLATFORM_GBM
#include "gbm/yagl_gbm_platform.h"
#endif
+#ifdef YAGL_PLATFORM_WAYLAND
+#include "wayland/yagl_wayland_platform.h"
+#endif
#include "yagl_log.h"
#include <stdlib.h>
#include <string.h>
@@ -15,6 +18,9 @@ static struct
const char *name;
} g_platforms[] =
{
+#ifdef YAGL_PLATFORM_WAYLAND
+ {&yagl_wayland_platform, "wayland"},
+#endif
#ifdef YAGL_PLATFORM_GBM
{&yagl_gbm_platform, "gbm"},
#endif
diff --git a/EGL/yagl_native_platform.h b/EGL/yagl_native_platform.h
index b852e22..afb0f98 100644
--- a/EGL/yagl_native_platform.h
+++ b/EGL/yagl_native_platform.h
@@ -8,6 +8,8 @@ struct yagl_native_display;
struct yagl_native_platform
{
+ int pixmaps_supported;
+
int (*probe)(yagl_os_display /*os_dpy*/);
struct yagl_native_display *(*wrap_display)(yagl_os_display /*os_dpy*/,
diff --git a/EGL/yagl_offscreen.c b/EGL/yagl_offscreen.c
index 27c196a..37754b6 100644
--- a/EGL/yagl_offscreen.c
+++ b/EGL/yagl_offscreen.c
@@ -1,6 +1,6 @@
#include "yagl_offscreen.h"
#include "yagl_offscreen_surface.h"
-#include "yagl_offscreen_image.h"
+#include "yagl_offscreen_image_pixmap.h"
#include "yagl_display.h"
#include "yagl_backend.h"
#include "yagl_malloc.h"
@@ -69,20 +69,29 @@ static struct yagl_surface
}
static struct yagl_image
- *yagl_offscreen_create_image(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list)
+ *yagl_offscreen_create_image_pixmap(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list)
{
- struct yagl_offscreen_image *image =
- yagl_offscreen_image_create(dpy,
- host_context,
- native_pixmap,
- attrib_list);
+ struct yagl_offscreen_image_pixmap *image =
+ yagl_offscreen_image_pixmap_create(dpy,
+ host_context,
+ native_pixmap,
+ attrib_list);
return image ? &image->base : NULL;
}
+static struct yagl_image
+ *yagl_offscreen_create_image_wl_buffer(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct wl_resource *buffer,
+ const EGLint* attrib_list)
+{
+ return NULL;
+}
+
static void yagl_offscreen_destroy(struct yagl_backend *backend)
{
yagl_free(backend);
@@ -98,7 +107,8 @@ struct yagl_backend *yagl_offscreen_create()
backend->create_window_surface = &yagl_offscreen_create_window_surface;
backend->create_pixmap_surface = &yagl_offscreen_create_pixmap_surface;
backend->create_pbuffer_surface = &yagl_offscreen_create_pbuffer_surface;
- backend->create_image = &yagl_offscreen_create_image;
+ backend->create_image_pixmap = &yagl_offscreen_create_image_pixmap;
+ backend->create_image_wl_buffer = &yagl_offscreen_create_image_wl_buffer;
backend->destroy = &yagl_offscreen_destroy;
backend->y_inverted = 1;
diff --git a/EGL/yagl_offscreen_image.h b/EGL/yagl_offscreen_image.h
deleted file mode 100644
index 7dab5d6..0000000
--- a/EGL/yagl_offscreen_image.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _YAGL_OFFSCREEN_IMAGE_H_
-#define _YAGL_OFFSCREEN_IMAGE_H_
-
-#include "yagl_export.h"
-#include "yagl_types.h"
-#include "yagl_image.h"
-
-struct yagl_offscreen_image
-{
- struct yagl_image base;
-
- uint32_t width;
- uint32_t height;
-};
-
-struct yagl_offscreen_image
- *yagl_offscreen_image_create(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list);
-
-#endif
diff --git a/EGL/yagl_offscreen_image.c b/EGL/yagl_offscreen_image_pixmap.c
index e0505e3..d541555 100644
--- a/EGL/yagl_offscreen_image.c
+++ b/EGL/yagl_offscreen_image_pixmap.c
@@ -1,4 +1,4 @@
-#include "yagl_offscreen_image.h"
+#include "yagl_offscreen_image_pixmap.h"
#include "yagl_log.h"
#include "yagl_malloc.h"
#include "yagl_display.h"
@@ -9,16 +9,16 @@
#include "yagl_native_image.h"
#include <string.h>
-static void yagl_offscreen_image_update(struct yagl_image *image)
+static void yagl_offscreen_image_pixmap_update(struct yagl_image *image)
{
- struct yagl_offscreen_image *oimage = (struct yagl_offscreen_image*)image;
+ struct yagl_offscreen_image_pixmap *oimage = (struct yagl_offscreen_image_pixmap*)image;
struct yagl_native_image *native_image = NULL;
- YAGL_LOG_FUNC_SET(yagl_offscreen_image_update);
+ YAGL_LOG_FUNC_SET(yagl_offscreen_image_pixmap_update);
- native_image = image->native_pixmap->get_image(image->native_pixmap,
- oimage->width,
- oimage->height);
+ native_image = oimage->native_pixmap->get_image(oimage->native_pixmap,
+ oimage->width,
+ oimage->height);
if (!native_image) {
YAGL_LOG_ERROR("get_image failed for image %u", image->res.handle);
@@ -37,23 +37,26 @@ static void yagl_offscreen_image_update(struct yagl_image *image)
native_image->destroy(native_image);
}
-static void yagl_offscreen_image_destroy(struct yagl_ref *ref)
+static void yagl_offscreen_image_pixmap_destroy(struct yagl_ref *ref)
{
- struct yagl_image *image = (struct yagl_image*)ref;
+ struct yagl_offscreen_image_pixmap *image = (struct yagl_offscreen_image_pixmap*)ref;
- yagl_image_cleanup(image);
+ image->native_pixmap->destroy(image->native_pixmap);
+ image->native_pixmap = NULL;
+
+ yagl_image_cleanup(&image->base);
yagl_free(image);
}
-struct yagl_offscreen_image
- *yagl_offscreen_image_create(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list)
+struct yagl_offscreen_image_pixmap
+ *yagl_offscreen_image_pixmap_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list)
{
yagl_host_handle host_image = 0;
- struct yagl_offscreen_image *image;
+ struct yagl_offscreen_image_pixmap *image;
uint32_t depth;
do {
@@ -72,12 +75,14 @@ struct yagl_offscreen_image
image = yagl_malloc0(sizeof(*image));
yagl_image_init(&image->base,
- &yagl_offscreen_image_destroy,
+ &yagl_offscreen_image_pixmap_destroy,
host_image,
dpy,
- native_pixmap);
+ (EGLImageKHR)native_pixmap->os_drawable);
+
+ image->base.update = &yagl_offscreen_image_pixmap_update;
- image->base.update = &yagl_offscreen_image_update;
+ image->native_pixmap = native_pixmap;
native_pixmap->get_geometry(native_pixmap,
&image->width,
diff --git a/EGL/yagl_offscreen_image_pixmap.h b/EGL/yagl_offscreen_image_pixmap.h
new file mode 100644
index 0000000..64e9ad1
--- /dev/null
+++ b/EGL/yagl_offscreen_image_pixmap.h
@@ -0,0 +1,26 @@
+#ifndef _YAGL_OFFSCREEN_IMAGE_PIXMAP_H_
+#define _YAGL_OFFSCREEN_IMAGE_PIXMAP_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+#include "yagl_image.h"
+
+struct yagl_native_drawable;
+
+struct yagl_offscreen_image_pixmap
+{
+ struct yagl_image base;
+
+ struct yagl_native_drawable *native_pixmap;
+
+ uint32_t width;
+ uint32_t height;
+};
+
+struct yagl_offscreen_image_pixmap
+ *yagl_offscreen_image_pixmap_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list);
+
+#endif
diff --git a/EGL/yagl_onscreen.c b/EGL/yagl_onscreen.c
index 408c069..694e7ca 100644
--- a/EGL/yagl_onscreen.c
+++ b/EGL/yagl_onscreen.c
@@ -1,6 +1,9 @@
#include "yagl_onscreen.h"
#include "yagl_onscreen_surface.h"
-#include "yagl_onscreen_image.h"
+#include "yagl_onscreen_image_pixmap.h"
+#ifdef YAGL_PLATFORM_WAYLAND
+#include "yagl_onscreen_image_wl_buffer.h"
+#endif
#include "yagl_backend.h"
#include "yagl_malloc.h"
#include "yagl_display.h"
@@ -70,20 +73,39 @@ static struct yagl_surface
}
static struct yagl_image
- *yagl_onscreen_create_image(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list)
+ *yagl_onscreen_create_image_pixmap(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list)
{
- struct yagl_onscreen_image *image =
- yagl_onscreen_image_create(dpy,
- host_context,
- native_pixmap,
- attrib_list);
+ struct yagl_onscreen_image_pixmap *image =
+ yagl_onscreen_image_pixmap_create(dpy,
+ host_context,
+ native_pixmap,
+ attrib_list);
return image ? &image->base : NULL;
}
+static struct yagl_image
+ *yagl_onscreen_create_image_wl_buffer(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct wl_resource *buffer,
+ const EGLint* attrib_list)
+{
+#ifdef YAGL_PLATFORM_WAYLAND
+ struct yagl_onscreen_image_wl_buffer *image =
+ yagl_onscreen_image_wl_buffer_create(dpy,
+ host_context,
+ buffer,
+ attrib_list);
+
+ return image ? &image->base : NULL;
+#else
+ return NULL;
+#endif
+}
+
static void yagl_onscreen_destroy(struct yagl_backend *backend)
{
yagl_free(backend);
@@ -99,7 +121,8 @@ struct yagl_backend *yagl_onscreen_create()
backend->create_window_surface = &yagl_onscreen_create_window_surface;
backend->create_pixmap_surface = &yagl_onscreen_create_pixmap_surface;
backend->create_pbuffer_surface = &yagl_onscreen_create_pbuffer_surface;
- backend->create_image = &yagl_onscreen_create_image;
+ backend->create_image_pixmap = &yagl_onscreen_create_image_pixmap;
+ backend->create_image_wl_buffer = &yagl_onscreen_create_image_wl_buffer;
backend->destroy = &yagl_onscreen_destroy;
backend->y_inverted = 0;
diff --git a/EGL/yagl_onscreen_image.h b/EGL/yagl_onscreen_image.h
deleted file mode 100644
index 8316c7c..0000000
--- a/EGL/yagl_onscreen_image.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _YAGL_ONSCREEN_IMAGE_H_
-#define _YAGL_ONSCREEN_IMAGE_H_
-
-#include "yagl_export.h"
-#include "yagl_types.h"
-#include "yagl_image.h"
-
-struct yagl_onscreen_buffer;
-struct yagl_native_drawable;
-struct vigs_drm_surface;
-
-struct yagl_onscreen_image
-{
- struct yagl_image base;
-
- struct vigs_drm_surface *drm_sfc;
-};
-
-struct yagl_onscreen_image
- *yagl_onscreen_image_create(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list);
-
-#endif
diff --git a/EGL/yagl_onscreen_image.c b/EGL/yagl_onscreen_image_pixmap.c
index e5aaeb7..ee72db5 100644
--- a/EGL/yagl_onscreen_image.c
+++ b/EGL/yagl_onscreen_image_pixmap.c
@@ -1,4 +1,4 @@
-#include "yagl_onscreen_image.h"
+#include "yagl_onscreen_image_pixmap.h"
#include "yagl_onscreen_utils.h"
#include "yagl_display.h"
#include "yagl_log.h"
@@ -6,30 +6,34 @@
#include "yagl_host_egl_calls.h"
#include "yagl_mem_egl.h"
#include "yagl_egl_state.h"
+#include "yagl_native_drawable.h"
#include "vigs.h"
-static void yagl_onscreen_image_update(struct yagl_image *image)
+static void yagl_onscreen_image_pixmap_update(struct yagl_image *image)
{
}
-static void yagl_onscreen_image_destroy(struct yagl_ref *ref)
+static void yagl_onscreen_image_pixmap_destroy(struct yagl_ref *ref)
{
- struct yagl_onscreen_image *image = (struct yagl_onscreen_image*)ref;
+ struct yagl_onscreen_image_pixmap *image = (struct yagl_onscreen_image_pixmap*)ref;
vigs_drm_gem_unref(&image->drm_sfc->gem);
+ image->native_pixmap->destroy(image->native_pixmap);
+ image->native_pixmap = NULL;
+
yagl_image_cleanup(&image->base);
yagl_free(image);
}
-struct yagl_onscreen_image
- *yagl_onscreen_image_create(struct yagl_display *dpy,
- yagl_host_handle host_context,
- struct yagl_native_drawable *native_pixmap,
- const EGLint* attrib_list)
+struct yagl_onscreen_image_pixmap
+ *yagl_onscreen_image_pixmap_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list)
{
- struct yagl_onscreen_image *image;
+ struct yagl_onscreen_image_pixmap *image;
struct vigs_drm_surface *drm_sfc = NULL;
yagl_host_handle host_image = 0;
@@ -58,13 +62,14 @@ struct yagl_onscreen_image
}
yagl_image_init(&image->base,
- &yagl_onscreen_image_destroy,
+ &yagl_onscreen_image_pixmap_destroy,
host_image,
dpy,
- native_pixmap);
+ (EGLImageKHR)native_pixmap->os_drawable);
- image->base.update = &yagl_onscreen_image_update;
+ image->base.update = &yagl_onscreen_image_pixmap_update;
+ image->native_pixmap = native_pixmap;
image->drm_sfc = drm_sfc;
return image;
diff --git a/EGL/yagl_onscreen_image_pixmap.h b/EGL/yagl_onscreen_image_pixmap.h
new file mode 100644
index 0000000..3bd01b1
--- /dev/null
+++ b/EGL/yagl_onscreen_image_pixmap.h
@@ -0,0 +1,26 @@
+#ifndef _YAGL_ONSCREEN_IMAGE_PIXMAP_H_
+#define _YAGL_ONSCREEN_IMAGE_PIXMAP_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+#include "yagl_image.h"
+
+struct yagl_native_drawable;
+struct vigs_drm_surface;
+
+struct yagl_onscreen_image_pixmap
+{
+ struct yagl_image base;
+
+ struct yagl_native_drawable *native_pixmap;
+
+ struct vigs_drm_surface *drm_sfc;
+};
+
+struct yagl_onscreen_image_pixmap
+ *yagl_onscreen_image_pixmap_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint* attrib_list);
+
+#endif
diff --git a/EGL/yagl_onscreen_image_wl_buffer.c b/EGL/yagl_onscreen_image_wl_buffer.c
new file mode 100644
index 0000000..65d6cd5
--- /dev/null
+++ b/EGL/yagl_onscreen_image_wl_buffer.c
@@ -0,0 +1,74 @@
+#include "yagl_onscreen_image_wl_buffer.h"
+#include "yagl_display.h"
+#include "yagl_malloc.h"
+#include "yagl_host_egl_calls.h"
+#include "yagl_mem_egl.h"
+#include "yagl_egl_state.h"
+#include "wayland-drm.h"
+#include "vigs.h"
+
+static void yagl_onscreen_image_wl_buffer_update(struct yagl_image *image)
+{
+}
+
+static void yagl_onscreen_image_wl_buffer_destroy(struct yagl_ref *ref)
+{
+ struct yagl_onscreen_image_wl_buffer *image = (struct yagl_onscreen_image_wl_buffer*)ref;
+
+ yagl_image_cleanup(&image->base);
+
+ yagl_free(image);
+}
+
+struct yagl_onscreen_image_wl_buffer
+ *yagl_onscreen_image_wl_buffer_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct wl_resource *buffer,
+ const EGLint* attrib_list)
+{
+ struct yagl_onscreen_image_wl_buffer *image;
+ struct wl_drm_buffer *drm_buffer;
+ yagl_host_handle host_image = 0;
+
+ image = yagl_malloc0(sizeof(*image));
+
+ drm_buffer = wayland_drm_get_buffer(buffer);
+
+ if (!drm_buffer) {
+ /*
+ * Or is it some other error ?
+ */
+ yagl_set_error(EGL_BAD_NATIVE_PIXMAP);
+ goto fail;
+ }
+
+ do {
+ yagl_mem_probe_read_attrib_list(attrib_list);
+ } while (!yagl_host_eglCreateImageKHR(&host_image,
+ dpy->host_dpy,
+ host_context,
+ EGL_WAYLAND_BUFFER_WL,
+ drm_buffer->drm_sfc->id,
+ attrib_list));
+
+ if (!host_image) {
+ goto fail;
+ }
+
+ yagl_image_init(&image->base,
+ &yagl_onscreen_image_wl_buffer_destroy,
+ host_image,
+ dpy,
+ (EGLImageKHR)drm_buffer->drm_sfc->gem.name);
+
+ image->base.update = &yagl_onscreen_image_wl_buffer_update;
+
+ image->buffer = drm_buffer;
+
+ return image;
+
+fail:
+ yagl_free(image);
+
+ return NULL;
+}
diff --git a/EGL/yagl_onscreen_image_wl_buffer.h b/EGL/yagl_onscreen_image_wl_buffer.h
new file mode 100644
index 0000000..d07fb74
--- /dev/null
+++ b/EGL/yagl_onscreen_image_wl_buffer.h
@@ -0,0 +1,25 @@
+#ifndef _YAGL_ONSCREEN_IMAGE_WL_BUFFER_H_
+#define _YAGL_ONSCREEN_IMAGE_WL_BUFFER_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+#include "yagl_image.h"
+
+struct wl_resource;
+struct wl_drm_buffer;
+struct vigs_drm_surface;
+
+struct yagl_onscreen_image_wl_buffer
+{
+ struct yagl_image base;
+
+ struct wl_drm_buffer *buffer;
+};
+
+struct yagl_onscreen_image_wl_buffer
+ *yagl_onscreen_image_wl_buffer_create(struct yagl_display *dpy,
+ yagl_host_handle host_context,
+ struct wl_resource *buffer,
+ const EGLint* attrib_list);
+
+#endif
diff --git a/gbm/yagl_gbm.c b/gbm/yagl_gbm.c
index cb8a55c..2bf6720 100644
--- a/gbm/yagl_gbm.c
+++ b/gbm/yagl_gbm.c
@@ -7,21 +7,6 @@
#include <string.h>
#include <unistd.h>
-/*
- * Temporary, move this to libdrm!
- * @{
- */
-
-typedef enum
-{
- vigs_drm_surface_bgrx8888 = 0x0,
- vigs_drm_surface_bgra8888 = 0x1,
-} vigs_drm_surface_format;
-
-/*
- * @}
- */
-
struct yagl_gbm_bo
{
struct gbm_bo base;
diff --git a/include/EGL/eglext.h b/include/EGL/eglext.h
index a7ea2ea..1d68178 100644
--- a/include/EGL/eglext.h
+++ b/include/EGL/eglext.h
@@ -6,7 +6,7 @@ extern "C" {
#endif
/*
-** Copyright (c) 2007-2010 The Khronos Group Inc.
+** Copyright (c) 2007-2013 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -34,8 +34,8 @@ extern "C" {
/* Header file version number */
/* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 15052 $ on $Date: 2011-07-06 17:43:46 -0700 (Wed, 06 Jul 2011) $ */
-#define EGL_EGLEXT_VERSION 10
+/* $Revision: 21254 $ on $Date: 2013-04-25 03:11:55 -0700 (Thu, 25 Apr 2013) $ */
+#define EGL_EGLEXT_VERSION 16
#ifndef EGL_KHR_config_attribs
#define EGL_KHR_config_attribs 1
@@ -178,15 +178,15 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG
#ifndef EGL_NV_coverage_sample
#define EGL_NV_coverage_sample 1
-#define EGL_COVERAGE_BUFFERS_NV 0x30E0
-#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
#endif
#ifndef EGL_NV_depth_nonlinear
#define EGL_NV_depth_nonlinear 1
-#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NV 0x30E2
#define EGL_DEPTH_ENCODING_NONE_NV 0
-#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
#endif
#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */
@@ -208,12 +208,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG
typedef void* EGLSyncNV;
typedef khronos_utime_nanoseconds_t EGLTimeNV;
#ifdef EGL_EGLEXT_PROTOTYPES
-EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
-EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
-EGLBoolean eglFenceNV (EGLSyncNV sync);
-EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
-EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
-EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
@@ -250,7 +250,6 @@ struct EGLClientPixmapHI
EGLint iHeight;
EGLint iStride;
};
-
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap);
#endif /* EGL_EGLEXT_PROTOTYPES */
@@ -313,12 +312,10 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif
-#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
+#if KHRONOS_SUPPORT_INT64 /* EGLuint64NV requires 64-bit uint support */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1
-
typedef khronos_utime_nanoseconds_t EGLuint64NV;
-
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void);
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void);
@@ -328,10 +325,256 @@ typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
#endif
#endif
+#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void* EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#define EGL_STREAM_BIT_KHR 0x0800
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+/* reuse EGLTimeKHR */
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif
+
+#ifndef EGL_EXT_create_context_robustness
+#define EGL_EXT_create_context_robustness 1
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
+#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
+#endif
+
+#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
+#define EGL_ANGLE_d3d_share_handle_client_buffer 1
+/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
+#endif
+
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
+#endif
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+/* No tokens/entry points, just relaxes an error condition */
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif
+
+#ifndef EGL_EXT_multiview_window
+#define EGL_EXT_multiview_window 1
+#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
+#endif
+
+#ifndef EGL_KHR_wait_sync
+#define EGL_KHR_wait_sync 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif
+
+#ifndef EGL_NV_post_convert_rounding
+#define EGL_NV_post_convert_rounding 1
+/* No tokens or entry points, just relaxes behavior of SwapBuffers */
+#endif
+
+#ifndef EGL_NV_native_query
+#define EGL_NV_native_query 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV( EGLDisplay dpy, EGLNativeDisplayType* display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV( EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType* window);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV( EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType* pixmap);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC)(EGLDisplay dpy, EGLNativeDisplayType *display_id);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC)(EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
+#endif
+
+#ifndef EGL_NV_3dvision_surface
+#define EGL_NV_3dvision_surface 1
+#define EGL_AUTO_STEREO_NV 0x3136
+#endif
+
+#ifndef EGL_ANDROID_framebuffer_target
+#define EGL_ANDROID_framebuffer_target 1
+#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
+#endif
+
+#ifndef EGL_ANDROID_blob_cache
+#define EGL_ANDROID_blob_cache 1
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC)(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+#endif
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+#define EGL_NATIVE_BUFFER_ANDROID 0x3140
+#endif
+
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_ANDROID_native_fence_sync 1
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID( EGLDisplay dpy, EGLSyncKHR);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC)(EGLDisplay dpy, EGLSyncKHR);
+#endif
+
+#ifndef EGL_ANDROID_recordable
+#define EGL_ANDROID_recordable 1
+#define EGL_RECORDABLE_ANDROID 0x3142
+#endif
+
+#ifndef EGL_EXT_buffer_age
+#define EGL_EXT_buffer_age 1
+#define EGL_BUFFER_AGE_EXT 0x313D
+#endif
+
+#ifndef EGL_EXT_image_dma_buf_import
+#define EGL_EXT_image_dma_buf_import 1
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
+#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
+#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
+#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
+#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
+#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
+#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
+#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
+#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
+#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
+#define EGL_ITU_REC601_EXT 0x327F
+#define EGL_ITU_REC709_EXT 0x3280
+#define EGL_ITU_REC2020_EXT 0x3281
+#define EGL_YUV_FULL_RANGE_EXT 0x3282
+#define EGL_YUV_NARROW_RANGE_EXT 0x3283
+#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
+#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
+#endif
+
+#ifndef EGL_ARM_pixmap_multisample_discard
+#define EGL_ARM_pixmap_multisample_discard 1
+#define EGL_DISCARD_SAMPLES_ARM 0x3286
+#endif
+
+#ifndef EGL_EXT_swap_buffers_with_damage
+#define EGL_EXT_swap_buffers_with_damage 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT( EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC)(EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
+#endif
+
#include <EGL/eglmesaext.h>
#ifdef __cplusplus
}
#endif
-#endif
+#endif /* __eglext_h_ */
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index 52dd5b1..e0eae28 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -112,14 +112,24 @@ typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
#ifndef EGL_WL_bind_wayland_display
#define EGL_WL_bind_wayland_display 1
-#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
+#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
+#define EGL_WAYLAND_PLANE_WL 0x31D6 /* eglCreateImageKHR target */
+
+#define EGL_TEXTURE_Y_U_V_WL 0x31D7
+#define EGL_TEXTURE_Y_UV_WL 0x31D8
+#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
+
struct wl_display;
+struct wl_resource;
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
#endif
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
+
#endif
#ifndef EGL_NOK_swap_region
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
index 17fdc61..21b18fe 100644
--- a/include/EGL/eglplatform.h
+++ b/include/EGL/eglplatform.h
@@ -109,8 +109,8 @@ typedef void *EGLNativeDisplayType;
#ifdef MESA_EGL_NO_X11_HEADERS
typedef void *EGLNativeDisplayType;
-typedef khronos_uint32_t EGLNativePixmapType;
-typedef khronos_uint32_t EGLNativeWindowType;
+typedef khronos_uintptr_t EGLNativePixmapType;
+typedef khronos_uintptr_t EGLNativeWindowType;
#else
diff --git a/include/yagl_wayland_egl.h b/include/yagl_wayland_egl.h
new file mode 100644
index 0000000..348723f
--- /dev/null
+++ b/include/yagl_wayland_egl.h
@@ -0,0 +1,25 @@
+#ifndef _YAGL_WAYLAND_EGL_H_
+#define _YAGL_WAYLAND_EGL_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+#include <wayland-egl.h>
+
+struct wl_egl_window
+{
+ struct wl_surface *surface;
+
+ int width;
+ int height;
+ int dx;
+ int dy;
+
+ int attached_width;
+ int attached_height;
+
+ void *user_data;
+ void (*resize_callback)(struct wl_egl_window */*egl_window*/,
+ void */*user_data*/);
+};
+
+#endif
diff --git a/packaging/emulator-yagl.spec b/packaging/emulator-yagl.spec
index c75b953..837cdce 100644
--- a/packaging/emulator-yagl.spec
+++ b/packaging/emulator-yagl.spec
@@ -4,8 +4,7 @@ Name: emulator-yagl
Summary: YaGL - OpenGLES acceleration module for emulator
Version: 1.0
Release: 18
-Group: TO_BE/FILLED_IN
-License: TO_BE/FILLED_IN
+License: MIT
#URL: http://www.khronos.org
Source0: %{name}-%{version}.tar.gz
BuildRequires: cmake
@@ -17,6 +16,9 @@ BuildRequires: pkgconfig(dri2proto)
BuildRequires: pkgconfig(libdrm)
%if %{with wayland}
BuildRequires: pkgconfig(gbm)
+BuildRequires: pkgconfig(libudev)
+BuildRequires: pkgconfig(wayland-client)
+BuildRequires: pkgconfig(wayland-server)
%endif
%description
@@ -36,7 +38,7 @@ YaGL - OpenGLES acceleration module for emulator (devel)
%build
%if %{with wayland}
-cmake -DCMAKE_INSTALL_PREFIX=%{buildroot}/usr -DINSTALL_LIB_DIR=lib/yagl -DPLATFORM_GBM=1
+cmake -DCMAKE_INSTALL_PREFIX=%{buildroot}/usr -DINSTALL_LIB_DIR=lib/yagl -DPLATFORM_GBM=1 -DPLATFORM_WAYLAND=1
%else
cmake -DCMAKE_INSTALL_PREFIX=%{buildroot}/usr -DINSTALL_LIB_DIR=lib/yagl
%endif
diff --git a/wayland-egl/CMakeLists.txt b/wayland-egl/CMakeLists.txt
new file mode 100644
index 0000000..fe7ae74
--- /dev/null
+++ b/wayland-egl/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(SOURCES
+ yagl_wayland_egl.c
+)
+
+add_library(wayland-egl-yagl SHARED ${SOURCES})
+set_target_properties(wayland-egl-yagl PROPERTIES VERSION 1.0.0 SOVERSION 1)
+set_target_properties(wayland-egl-yagl PROPERTIES OUTPUT_NAME wayland-egl)
+
+target_link_libraries(wayland-egl-yagl ${CMAKE_THREAD_LIBS_INIT})
+
+install(
+ TARGETS wayland-egl-yagl
+ LIBRARY DESTINATION ${INSTALL_LIB_DIR}
+)
diff --git a/wayland-egl/yagl_wayland_egl.c b/wayland-egl/yagl_wayland_egl.c
new file mode 100644
index 0000000..844037c
--- /dev/null
+++ b/wayland-egl/yagl_wayland_egl.c
@@ -0,0 +1,54 @@
+#include "yagl_export.h"
+#include "yagl_wayland_egl.h"
+#include <stdlib.h>
+#include <string.h>
+
+YAGL_API struct wl_egl_window *wl_egl_window_create(struct wl_surface *surface,
+ int width, int height)
+{
+ struct wl_egl_window *egl_window;
+
+ egl_window = malloc(sizeof(*egl_window));
+
+ if (!egl_window) {
+ return NULL;
+ }
+
+ memset(egl_window, 0, sizeof(*egl_window));
+
+ egl_window->surface = surface;
+
+ wl_egl_window_resize(egl_window, width, height, 0, 0);
+
+ return egl_window;
+}
+
+YAGL_API void wl_egl_window_destroy(struct wl_egl_window *egl_window)
+{
+ free(egl_window);
+}
+
+YAGL_API void wl_egl_window_resize(struct wl_egl_window *egl_window,
+ int width, int height,
+ int dx, int dy)
+{
+ egl_window->width = width;
+ egl_window->height = height;
+ egl_window->dx = dx;
+ egl_window->dy = dy;
+
+ if (egl_window->resize_callback) {
+ egl_window->resize_callback(egl_window, egl_window->user_data);
+ }
+}
+
+YAGL_API void wl_egl_window_get_attached_size(struct wl_egl_window *egl_window,
+ int *width, int *height)
+{
+ if (width) {
+ *width = egl_window->attached_width;
+ }
+ if (height) {
+ *height = egl_window->attached_height;
+ }
+}