diff options
author | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2013-08-05 19:31:53 +0400 |
---|---|---|
committer | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2013-08-09 17:42:20 +0400 |
commit | ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530 (patch) | |
tree | 199b7899855fe3bdc233e48b6c982435aaedb523 | |
parent | 9ab05f88786e8dd79f7d868c62d286555343941d (diff) | |
download | emulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.tar.gz emulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.tar.bz2 emulator-yagl-ddaa9c34dbf4119f556fa64b16f7d7b52f0ea530.zip |
YaGL: wayland platform added
Change-Id: Ife2fa6fde03f956d7753987e7d09deda4cf1bff7
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; + } +} |