summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2013-07-29 18:29:07 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2013-08-01 14:12:21 +0400
commit7262ded6ba6abcfe57286a438e8610cf4d5072f5 (patch)
treef56273a273effdfce00053a51e64e6e732dcb263
parent5b9dd324588c5f969a9bb8f5fd00632a2c0ae3d8 (diff)
downloademulator-yagl-7262ded6ba6abcfe57286a438e8610cf4d5072f5.tar.gz
emulator-yagl-7262ded6ba6abcfe57286a438e8610cf4d5072f5.tar.bz2
emulator-yagl-7262ded6ba6abcfe57286a438e8610cf4d5072f5.zip
YaGL: Separated windowing system related stuff
Change-Id: I26b4dfbccd33e7c8ca89e5ef0bddb6d634220ad6
-rw-r--r--CMakeLists.txt4
-rw-r--r--EGL/CMakeLists.txt22
-rw-r--r--EGL/gbm/yagl_gbm_display.c0
-rw-r--r--EGL/gbm/yagl_gbm_display.h0
-rw-r--r--EGL/gbm/yagl_gbm_drawable.c0
-rw-r--r--EGL/gbm/yagl_gbm_drawable.h0
-rw-r--r--EGL/gbm/yagl_gbm_platform.c20
-rw-r--r--EGL/gbm/yagl_gbm_platform.h10
-rw-r--r--EGL/x11/yagl_dri2.c (renamed from EGL/yagl_dri2.c)11
-rw-r--r--EGL/x11/yagl_dri2.h (renamed from EGL/yagl_dri2.h)0
-rw-r--r--EGL/x11/yagl_x11_display.c235
-rw-r--r--EGL/x11/yagl_x11_display.h25
-rw-r--r--EGL/x11/yagl_x11_drawable.c309
-rw-r--r--EGL/x11/yagl_x11_drawable.h47
-rw-r--r--EGL/x11/yagl_x11_image.c275
-rw-r--r--EGL/x11/yagl_x11_image.h32
-rw-r--r--EGL/x11/yagl_x11_platform.c55
-rw-r--r--EGL/x11/yagl_x11_platform.h10
-rw-r--r--EGL/yagl_backend.h31
-rw-r--r--EGL/yagl_bimage.c208
-rw-r--r--EGL/yagl_bimage.h41
-rw-r--r--EGL/yagl_display.c71
-rw-r--r--EGL/yagl_display.h27
-rw-r--r--EGL/yagl_egl_calls.c77
-rw-r--r--EGL/yagl_egl_calls.in2
-rw-r--r--EGL/yagl_host_egl_calls.c2
-rw-r--r--EGL/yagl_host_egl_calls.h2
-rw-r--r--EGL/yagl_image.c9
-rw-r--r--EGL/yagl_image.h9
-rw-r--r--EGL/yagl_native_display.c16
-rw-r--r--EGL/yagl_native_display.h49
-rw-r--r--EGL/yagl_native_drawable.c14
-rw-r--r--EGL/yagl_native_drawable.h63
-rw-r--r--EGL/yagl_native_image.c21
-rw-r--r--EGL/yagl_native_image.h39
-rw-r--r--EGL/yagl_native_platform.c60
-rw-r--r--EGL/yagl_native_platform.h23
-rw-r--r--EGL/yagl_native_types.h18
-rw-r--r--EGL/yagl_offscreen.c35
-rw-r--r--EGL/yagl_offscreen_image.c78
-rw-r--r--EGL/yagl_offscreen_image.h2
-rw-r--r--EGL/yagl_offscreen_surface.c232
-rw-r--r--EGL/yagl_offscreen_surface.h11
-rw-r--r--EGL/yagl_onscreen.c58
-rw-r--r--EGL/yagl_onscreen_buffer.c64
-rw-r--r--EGL/yagl_onscreen_buffer.h27
-rw-r--r--EGL/yagl_onscreen_display.c172
-rw-r--r--EGL/yagl_onscreen_display.h24
-rw-r--r--EGL/yagl_onscreen_image.c25
-rw-r--r--EGL/yagl_onscreen_image.h7
-rw-r--r--EGL/yagl_onscreen_surface.c343
-rw-r--r--EGL/yagl_onscreen_surface.h33
-rw-r--r--EGL/yagl_surface.c16
-rw-r--r--EGL/yagl_surface.h20
-rw-r--r--GLES_common/yagl_gles_calls.c1
-rw-r--r--include/yagl_marshal_egl.h2
-rw-r--r--include/yagl_platform.h24
-rw-r--r--include/yagl_types.h21
-rw-r--r--include/yagl_version.h2
-rw-r--r--packaging/emulator-yagl.spec2
60 files changed, 1913 insertions, 1123 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ccd317..e61ed02 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,6 +40,10 @@ endif ()
set(YAGL_OUT_DIR ${YAGL_BINARY_DIR}/out)
+#define stuff
+
+add_definitions(-DMESA_EGL_NO_X11_HEADERS)
+
#set includes/libs
set(YAGL_INCLUDE_DIR "${YAGL_SOURCE_DIR}/include")
diff --git a/EGL/CMakeLists.txt b/EGL/CMakeLists.txt
index eee7514..afc59b7 100644
--- a/EGL/CMakeLists.txt
+++ b/EGL/CMakeLists.txt
@@ -1,5 +1,4 @@
set(SOURCES
- yagl_bimage.c
yagl_context.c
yagl_display.c
yagl_egl_calls.c
@@ -17,12 +16,17 @@ set(SOURCES
yagl_onscreen_display.c
yagl_onscreen_image.c
yagl_onscreen_surface.c
+ yagl_onscreen_buffer.c
yagl_ref.c
yagl_render.c
yagl_resource.c
yagl_state.c
yagl_surface.c
yagl_utils.c
+ yagl_native_platform.c
+ yagl_native_display.c
+ yagl_native_drawable.c
+ yagl_native_image.c
)
set(LIBRARIES
@@ -34,21 +38,35 @@ set(LIBRARIES
if (PLATFORM_X11)
set(SOURCES ${SOURCES}
- yagl_dri2.c
+ x11/yagl_dri2.c
+ x11/yagl_x11_platform.c
+ x11/yagl_x11_display.c
+ x11/yagl_x11_drawable.c
+ x11/yagl_x11_image.c
)
set(LIBRARIES ${LIBRARIES}
${X11_LIBRARIES}
${XEXT_LIBRARIES}
${XFIXES_LIBRARIES}
)
+ add_definitions(-DYAGL_PLATFORM_X11)
endif ()
if (PLATFORM_GBM)
+ set(SOURCES ${SOURCES}
+ gbm/yagl_gbm_platform.c
+ gbm/yagl_gbm_display.c
+ gbm/yagl_gbm_drawable.c
+ )
+ add_definitions(-DYAGL_PLATFORM_GBM)
endif ()
if (PLATFORM_WAYLAND)
+ add_definitions(-DYAGL_PLATFORM_WAYLAND)
endif ()
+include_directories(.)
+
add_library(EGL SHARED ${SOURCES})
set_target_properties(EGL PROPERTIES VERSION 1.0 SOVERSION 1)
diff --git a/EGL/gbm/yagl_gbm_display.c b/EGL/gbm/yagl_gbm_display.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_display.c
diff --git a/EGL/gbm/yagl_gbm_display.h b/EGL/gbm/yagl_gbm_display.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_display.h
diff --git a/EGL/gbm/yagl_gbm_drawable.c b/EGL/gbm/yagl_gbm_drawable.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_drawable.c
diff --git a/EGL/gbm/yagl_gbm_drawable.h b/EGL/gbm/yagl_gbm_drawable.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_drawable.h
diff --git a/EGL/gbm/yagl_gbm_platform.c b/EGL/gbm/yagl_gbm_platform.c
new file mode 100644
index 0000000..7afa63f
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_platform.c
@@ -0,0 +1,20 @@
+#include "yagl_gbm_platform.h"
+#include "yagl_native_platform.h"
+
+static int yagl_gbm_platform_probe(yagl_os_display os_dpy)
+{
+ return 0;
+}
+
+static struct yagl_native_display
+ *yagl_gbm_wrap_display(yagl_os_display os_dpy,
+ int enable_drm)
+{
+ return NULL;
+}
+
+struct yagl_native_platform yagl_gbm_platform =
+{
+ .probe = yagl_gbm_platform_probe,
+ .wrap_display = yagl_gbm_wrap_display
+};
diff --git a/EGL/gbm/yagl_gbm_platform.h b/EGL/gbm/yagl_gbm_platform.h
new file mode 100644
index 0000000..5c8b585
--- /dev/null
+++ b/EGL/gbm/yagl_gbm_platform.h
@@ -0,0 +1,10 @@
+#ifndef _YAGL_GBM_PLATFORM_H_
+#define _YAGL_GBM_PLATFORM_H_
+
+#include "yagl_export.h"
+
+struct yagl_native_platform;
+
+extern struct yagl_native_platform yagl_gbm_platform;
+
+#endif
diff --git a/EGL/yagl_dri2.c b/EGL/x11/yagl_dri2.c
index 743b761..ef7e524 100644
--- a/EGL/yagl_dri2.c
+++ b/EGL/x11/yagl_dri2.c
@@ -1,7 +1,8 @@
#include "yagl_dri2.h"
#include "yagl_display.h"
-#include "yagl_onscreen_surface.h"
+#include "yagl_surface.h"
#include "yagl_log.h"
+#include "yagl_native_drawable.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <X11/extensions/dri2proto.h>
@@ -65,7 +66,7 @@ static Bool DRI2WireToEvent(Display *x_dpy, XEvent *event, xEvent *wire)
#ifdef DRI2_InvalidateBuffers
case DRI2_InvalidateBuffers:
awire = (xDRI2InvalidateBuffers*)wire;
- dpy = yagl_display_get_x(x_dpy);
+ dpy = yagl_display_get_os((yagl_os_display)x_dpy);
if (!dpy) {
YAGL_LOG_ERROR("EGL display not found for X display 0x%X", x_dpy);
@@ -75,13 +76,11 @@ static Bool DRI2WireToEvent(Display *x_dpy, XEvent *event, xEvent *wire)
sfc = yagl_display_surface_acquire(dpy, (EGLSurface)awire->drawable);
if (sfc) {
- struct yagl_onscreen_surface *osfc =
- (struct yagl_onscreen_surface*)sfc;
if (sfc->type == EGL_WINDOW_BIT) {
- ++osfc->stamp;
+ ++sfc->native_drawable->stamp;
YAGL_LOG_DEBUG("EGL surface 0x%X invalidated, stamp = %u",
awire->drawable,
- osfc->stamp);
+ sfc->native_drawable->stamp);
} else {
YAGL_LOG_ERROR("EGL surface 0x%X is not a window surface",
awire->drawable);
diff --git a/EGL/yagl_dri2.h b/EGL/x11/yagl_dri2.h
index 4350e42..4350e42 100644
--- a/EGL/yagl_dri2.h
+++ b/EGL/x11/yagl_dri2.h
diff --git a/EGL/x11/yagl_x11_display.c b/EGL/x11/yagl_x11_display.c
new file mode 100644
index 0000000..6c067f3
--- /dev/null
+++ b/EGL/x11/yagl_x11_display.c
@@ -0,0 +1,235 @@
+#include "yagl_x11_display.h"
+#include "yagl_x11_drawable.h"
+#include "yagl_x11_image.h"
+#include "yagl_log.h"
+#include "yagl_malloc.h"
+#include "yagl_dri2.h"
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+#include <sys/fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int yagl_x11_display_dri2_init(Display *x_dpy)
+{
+ 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);
+
+ 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;
+ }
+
+ YAGL_LOG_TRACE("DRI2QueryExtension returned %d %d",
+ event_base, error_base);
+
+ if (!yagl_DRI2QueryVersion(x_dpy, &dri_major, &dri_minor)) {
+ fprintf(stderr, "Critical error! Failed to DRI2QueryVersion on YaGL display, DRI2 not enabled ?\n");
+ goto fail;
+ }
+
+ YAGL_LOG_TRACE("DRI2QueryVersion returned %d %d",
+ dri_major, dri_minor);
+
+ if (!yagl_DRI2Connect(x_dpy,
+ RootWindow(x_dpy, DefaultScreen(x_dpy)),
+ &dri_driver,
+ &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);
+
+ 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));
+ goto fail;
+ }
+
+ memset(&magic, 0, sizeof(magic));
+
+ ret = drmGetMagic(drm_fd, &magic);
+
+ if (ret != 0) {
+ fprintf(stderr, "Critical error! drmGetMagic failed: %s\n", strerror(-ret));
+ 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");
+ goto fail;
+ }
+
+ goto out;
+
+fail:
+ if (drm_fd >= 0) {
+ close(drm_fd);
+ drm_fd = -1;
+ }
+out:
+ if (dri_driver) {
+ Xfree(dri_driver);
+ }
+ if (dri_device) {
+ Xfree(dri_device);
+ }
+
+ return drm_fd;
+}
+
+static struct yagl_native_drawable
+ *yagl_x11_display_wrap_window(struct yagl_native_display *dpy,
+ yagl_os_window os_window)
+{
+ return yagl_x11_drawable_create(dpy, os_window, 0, 0);
+}
+
+static struct yagl_native_drawable
+ *yagl_x11_display_wrap_pixmap(struct yagl_native_display *dpy,
+ yagl_os_pixmap os_pixmap)
+{
+ return yagl_x11_drawable_create(dpy, os_pixmap, 0, 1);
+}
+
+static struct yagl_native_drawable
+ *yagl_x11_display_create_pixmap(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ struct yagl_native_drawable *drawable;
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+ Pixmap x_pixmap = XCreatePixmap(x_dpy,
+ RootWindow(x_dpy, DefaultScreen(x_dpy)),
+ width, height, depth);
+
+ if (!x_pixmap) {
+ return NULL;
+ }
+
+ drawable = yagl_x11_drawable_create(dpy, (yagl_os_pixmap)x_pixmap, 1, 1);
+
+ if (!drawable) {
+ XFreePixmap(x_dpy, x_pixmap);
+ return NULL;
+ }
+
+ return drawable;
+}
+
+static struct yagl_native_image
+ *yagl_x11_display_create_image(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ return yagl_x11_image_create(dpy, width, height, depth);
+}
+
+static int yagl_x11_display_get_visual(struct yagl_native_display *dpy,
+ int *visual_id,
+ int *visual_type)
+{
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+ int screen;
+ XVisualInfo vi;
+
+ screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(x_dpy));
+
+ /*
+ * 24-bit is the highest supported by soft framebuffer.
+ */
+ if (!XMatchVisualInfo(x_dpy, screen, 24, TrueColor, &vi)) {
+ return 0;
+ }
+
+ *visual_id = XVisualIDFromVisual(vi.visual);
+ *visual_type = TrueColor;
+
+ return 1;
+}
+
+static void yagl_x11_display_destroy(struct yagl_native_display *dpy)
+{
+ struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+
+ if (x11_dpy->own_dpy) {
+ XCloseDisplay(x_dpy);
+ }
+
+ if (dpy->drm_fd >= 0) {
+ close(dpy->drm_fd);
+ }
+
+ yagl_native_display_cleanup(dpy);
+
+ yagl_free(x11_dpy);
+}
+
+struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
+ int own_dpy,
+ int enable_drm)
+{
+ Display *x_dpy = YAGL_X11_DPY(os_dpy);
+ struct yagl_x11_display *dpy;
+ int xmajor;
+ int xminor;
+ Bool pixmaps;
+ int drm_fd = -1;
+
+ YAGL_LOG_FUNC_SET(eglGetDisplay);
+
+ dpy = yagl_malloc0(sizeof(*dpy));
+
+ dpy->own_dpy = own_dpy;
+
+ dpy->xshm_images_supported = XShmQueryVersion(x_dpy,
+ &xmajor,
+ &xminor,
+ &pixmaps);
+ dpy->xshm_pixmaps_supported = pixmaps;
+
+ YAGL_LOG_DEBUG("XShm images are%s supported, version %d, %d (pixmaps = %d)",
+ (dpy->xshm_images_supported ? "" : " NOT"),
+ xmajor,
+ xminor,
+ pixmaps);
+
+ if (enable_drm) {
+ drm_fd = yagl_x11_display_dri2_init(x_dpy);
+
+ if (drm_fd < 0) {
+ yagl_free(dpy);
+ return NULL;
+ }
+ }
+
+ yagl_native_display_init(&dpy->base,
+ platform,
+ os_dpy,
+ drm_fd);
+
+ 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;
+ dpy->base.create_image = &yagl_x11_display_create_image;
+ dpy->base.get_visual = &yagl_x11_display_get_visual;
+ dpy->base.destroy = &yagl_x11_display_destroy;
+
+ return &dpy->base;
+}
diff --git a/EGL/x11/yagl_x11_display.h b/EGL/x11/yagl_x11_display.h
new file mode 100644
index 0000000..7aeb90d
--- /dev/null
+++ b/EGL/x11/yagl_x11_display.h
@@ -0,0 +1,25 @@
+#ifndef _YAGL_X11_DISPLAY_H_
+#define _YAGL_X11_DISPLAY_H_
+
+#include "yagl_export.h"
+#include "yagl_native_display.h"
+
+#define YAGL_X11_DPY(os_dpy) ((Display*)(os_dpy))
+
+struct yagl_x11_display
+{
+ struct yagl_native_display base;
+
+ int own_dpy;
+
+ int xshm_images_supported;
+
+ int xshm_pixmaps_supported;
+};
+
+struct yagl_native_display *yagl_x11_display_create(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
+ int own_dpy,
+ int enable_drm);
+
+#endif
diff --git a/EGL/x11/yagl_x11_drawable.c b/EGL/x11/yagl_x11_drawable.c
new file mode 100644
index 0000000..b946495
--- /dev/null
+++ b/EGL/x11/yagl_x11_drawable.c
@@ -0,0 +1,309 @@
+#include "yagl_x11_drawable.h"
+#include "yagl_x11_display.h"
+#include "yagl_x11_image.h"
+#include "yagl_malloc.h"
+#include "yagl_dri2.h"
+#include "yagl_utils.h"
+#include "yagl_log.h"
+#include <X11/Xutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static uint32_t yagl_x11_drawable_get_buffer(struct yagl_native_drawable *drawable,
+ yagl_native_attachment attachment)
+{
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ unsigned int attachments[1];
+ yagl_DRI2Buffer *buffer;
+ int tmp_width, tmp_height, num_buffers;
+ uint32_t name;
+
+ YAGL_LOG_FUNC_SET(yagl_x11_drawable_get_buffer);
+
+ if (drawable->dpy->drm_fd < 0) {
+ fprintf(stderr, "Asking for DRI2 buffer when DRI2 not enabled!\n");
+ return 0;
+ }
+
+ switch (attachment) {
+ case yagl_native_attachment_front:
+ attachments[0] = DRI2BufferFrontLeft;
+ break;
+ case yagl_native_attachment_back:
+ attachments[0] = DRI2BufferBackLeft;
+ break;
+ default:
+ YAGL_LOG_ERROR("Bad attachment %u", attachment);
+ return 0;
+ }
+
+ buffer = yagl_DRI2GetBuffers(x_dpy, x_drawable,
+ &tmp_width, &tmp_height,
+ &attachments[0],
+ sizeof(attachments)/sizeof(attachments[0]),
+ &num_buffers);
+
+ if (!buffer) {
+ return 0;
+ }
+
+ name = buffer->name;
+
+ Xfree(buffer);
+
+ return name;
+}
+
+static void yagl_x11_drawable_swap_buffers(struct yagl_native_drawable *drawable)
+{
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ CARD64 count = 0;
+
+ if (drawable->dpy->drm_fd < 0) {
+ return;
+ }
+
+ yagl_DRI2SwapBuffers(x_dpy,
+ x_drawable, 0, 0, 0,
+ &count);
+}
+
+static void yagl_x11_drawable_wait(struct yagl_native_drawable *drawable,
+ uint32_t width,
+ uint32_t height)
+{
+ struct yagl_x11_drawable *x11_drawable = (struct yagl_x11_drawable*)drawable;
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ XRectangle xrect;
+ XserverRegion region;
+
+ if (!x11_drawable->is_pixmap || (drawable->dpy->drm_fd < 0)) {
+ return;
+ }
+
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = width;
+ xrect.height = height;
+
+ region = XFixesCreateRegion(x_dpy, &xrect, 1);
+ yagl_DRI2CopyRegion(x_dpy,
+ x_drawable,
+ region,
+ DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+ XFixesDestroyRegion(x_dpy, region);
+}
+
+static void yagl_x11_drawable_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)
+{
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ Pixmap x_pixmap = YAGL_X11_DRAWABLE(os_pixmap);
+ GC x_gc;
+
+ x_gc = XCreateGC(x_dpy, x_pixmap, 0, NULL);
+
+ if (x_gc) {
+ XCopyArea(x_dpy,
+ x_drawable,
+ x_pixmap,
+ x_gc,
+ from_x, from_y,
+ width,
+ height,
+ to_x, to_y);
+
+ XFreeGC(x_dpy, x_gc);
+
+ XSync(x_dpy, 0);
+ }
+}
+
+static void yagl_x11_drawable_set_swap_interval(struct yagl_native_drawable *drawable,
+ int interval)
+{
+ struct yagl_x11_drawable *x11_drawable = (struct yagl_x11_drawable*)drawable;
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+
+ if (x11_drawable->is_pixmap || (drawable->dpy->drm_fd < 0)) {
+ return;
+ }
+
+ yagl_DRI2SwapInterval(x_dpy, x_drawable, interval);
+}
+
+static void yagl_x11_drawable_get_geometry(struct yagl_native_drawable *drawable,
+ uint32_t *width,
+ uint32_t *height,
+ uint32_t *depth)
+{
+ struct yagl_x11_drawable *x11_drawable = (struct yagl_x11_drawable*)drawable;
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ union { Window w; int i; unsigned int ui; } tmp_geom;
+
+ if (x11_drawable->is_pixmap) {
+ pthread_mutex_lock(&x11_drawable->mtx);
+
+ if (!x11_drawable->is_geom_acquired) {
+ XGetGeometry(x_dpy,
+ x_drawable,
+ &tmp_geom.w,
+ &tmp_geom.i,
+ &tmp_geom.i,
+ &x11_drawable->width,
+ &x11_drawable->height,
+ &tmp_geom.ui,
+ &x11_drawable->depth);
+
+ x11_drawable->is_geom_acquired = 1;
+ }
+
+ pthread_mutex_unlock(&x11_drawable->mtx);
+
+ *width = x11_drawable->width;
+ *height = x11_drawable->height;
+ *depth = x11_drawable->depth;
+ } else {
+ XGetGeometry(x_dpy,
+ x_drawable,
+ &tmp_geom.w,
+ &tmp_geom.i,
+ &tmp_geom.i,
+ width,
+ height,
+ &tmp_geom.ui,
+ depth);
+ }
+}
+
+static struct yagl_native_image
+ *yagl_x11_drawable_get_image(struct yagl_native_drawable *drawable,
+ uint32_t width,
+ uint32_t height)
+{
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ XImage *x_image;
+ struct yagl_native_image *image;
+
+ YAGL_LOG_FUNC_SET(yagl_x11_drawable_get_image);
+
+ x_image = XGetImage(x_dpy,
+ x_drawable,
+ 0,
+ 0,
+ width,
+ height,
+ AllPlanes,
+ ZPixmap);
+
+ if (!x_image) {
+ YAGL_LOG_ERROR("XGetImage failed for drawable %p",
+ drawable->os_drawable);
+ return NULL;
+ }
+
+ image = yagl_x11_image_wrap(drawable->dpy, x_image);
+
+ if (!image) {
+ YAGL_LOG_ERROR("yagl_x11_image_wrap failed for drawable %p",
+ drawable->os_drawable);
+ XDestroyImage(x_image);
+ return NULL;
+ }
+
+ return image;
+}
+
+static void yagl_x11_drawable_destroy(struct yagl_native_drawable *drawable)
+{
+ struct yagl_x11_drawable *x11_drawable = (struct yagl_x11_drawable*)drawable;
+ Display *x_dpy = YAGL_X11_DPY(drawable->dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+
+ if (x11_drawable->x_gc) {
+ XFreeGC(x_dpy, x11_drawable->x_gc);
+ }
+
+ if (drawable->dpy->drm_fd >= 0) {
+ yagl_DRI2DestroyDrawable(x_dpy, x_drawable);
+ }
+
+ pthread_mutex_destroy(&x11_drawable->mtx);
+
+ if (x11_drawable->own_drawable) {
+ if (x11_drawable->is_pixmap) {
+ XFreePixmap(x_dpy, x_drawable);
+ } else {
+ XDestroyWindow(x_dpy, x_drawable);
+ }
+ }
+
+ yagl_native_drawable_cleanup(drawable);
+
+ yagl_free(x11_drawable);
+}
+
+struct yagl_native_drawable *yagl_x11_drawable_create(struct yagl_native_display *dpy,
+ yagl_os_drawable os_drawable,
+ int own_drawable,
+ int is_pixmap)
+{
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(os_drawable);
+ struct yagl_x11_drawable *drawable;
+
+ drawable = yagl_malloc0(sizeof(*drawable));
+
+ yagl_native_drawable_init(&drawable->base,
+ dpy,
+ os_drawable);
+
+ drawable->base.get_buffer = &yagl_x11_drawable_get_buffer;
+ drawable->base.swap_buffers = &yagl_x11_drawable_swap_buffers;
+ drawable->base.wait = &yagl_x11_drawable_wait;
+ drawable->base.copy_to_pixmap = &yagl_x11_drawable_copy_to_pixmap;
+ drawable->base.set_swap_interval = &yagl_x11_drawable_set_swap_interval;
+ drawable->base.get_geometry = &yagl_x11_drawable_get_geometry;
+ drawable->base.get_image = &yagl_x11_drawable_get_image;
+ drawable->base.destroy = &yagl_x11_drawable_destroy;
+
+ drawable->own_drawable = own_drawable;
+ drawable->is_pixmap = is_pixmap;
+ yagl_mutex_init(&drawable->mtx);
+
+ if (dpy->drm_fd >= 0) {
+ yagl_DRI2CreateDrawable(x_dpy, x_drawable);
+ }
+
+ return &drawable->base;
+}
+
+GC yagl_x11_drawable_get_gc(struct yagl_x11_drawable *drawable)
+{
+ pthread_mutex_lock(&drawable->mtx);
+
+ if (!drawable->x_gc) {
+ Display *x_dpy = YAGL_X11_DPY(drawable->base.dpy->os_dpy);
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->base.os_drawable);
+
+ drawable->x_gc = XCreateGC(x_dpy, x_drawable, 0, NULL);
+ }
+
+ pthread_mutex_unlock(&drawable->mtx);
+
+ return drawable->x_gc;
+}
diff --git a/EGL/x11/yagl_x11_drawable.h b/EGL/x11/yagl_x11_drawable.h
new file mode 100644
index 0000000..07862a8
--- /dev/null
+++ b/EGL/x11/yagl_x11_drawable.h
@@ -0,0 +1,47 @@
+#ifndef _YAGL_X11_DRAWABLE_H_
+#define _YAGL_X11_DRAWABLE_H_
+
+#include "yagl_export.h"
+#include "yagl_native_drawable.h"
+#include <X11/Xlib.h>
+#include <pthread.h>
+
+#define YAGL_X11_DRAWABLE(os_drawable) ((Drawable)(os_drawable))
+
+struct yagl_x11_drawable
+{
+ struct yagl_native_drawable base;
+
+ int own_drawable;
+
+ int is_pixmap;
+
+ pthread_mutex_t mtx;
+
+ /*
+ * Allocated on first request.
+ */
+ GC x_gc;
+
+ /*
+ * For pixmaps only, filled on first request.
+ * @{
+ */
+ int is_geom_acquired;
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+ /*
+ * @}
+ */
+};
+
+struct yagl_native_drawable
+ *yagl_x11_drawable_create(struct yagl_native_display *dpy,
+ yagl_os_drawable os_drawable,
+ int own_drawable,
+ int is_pixmap);
+
+GC yagl_x11_drawable_get_gc(struct yagl_x11_drawable *drawable);
+
+#endif
diff --git a/EGL/x11/yagl_x11_image.c b/EGL/x11/yagl_x11_image.c
new file mode 100644
index 0000000..c5dfe95
--- /dev/null
+++ b/EGL/x11/yagl_x11_image.c
@@ -0,0 +1,275 @@
+#include "yagl_x11_image.h"
+#include "yagl_x11_display.h"
+#include "yagl_x11_drawable.h"
+#include "yagl_malloc.h"
+#include "yagl_log.h"
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void yagl_x11_image_draw_internal(struct yagl_x11_image *image,
+ Drawable target,
+ GC x_gc)
+{
+ Display *x_dpy = YAGL_X11_DPY(image->base.dpy->os_dpy);
+
+ if (image->x_shm.shmid != -1) {
+ XShmPutImage(x_dpy, target, x_gc, image->x_image,
+ 0, 0, 0, 0, image->base.width, image->base.height, 0);
+ } else {
+ XPutImage(x_dpy, target, x_gc, image->x_image,
+ 0, 0, 0, 0, image->base.width, image->base.height);
+ }
+
+ XFlush(x_dpy);
+}
+
+static void yagl_x11_image_draw(struct yagl_native_image *image,
+ struct yagl_native_drawable *drawable)
+{
+ struct yagl_x11_image *x11_image = (struct yagl_x11_image*)image;
+ struct yagl_x11_drawable *x11_drawable = (struct yagl_x11_drawable*)drawable;
+ Drawable x_drawable = YAGL_X11_DRAWABLE(drawable->os_drawable);
+ GC x_gc = yagl_x11_drawable_get_gc(x11_drawable);
+
+ if (x_gc) {
+ yagl_x11_image_draw_internal(x11_image, x_drawable, x_gc);
+ }
+}
+
+static void yagl_x11_image_draw_to_pixmap(struct yagl_native_image *image,
+ yagl_os_pixmap os_pixmap)
+{
+ struct yagl_x11_image *x11_image = (struct yagl_x11_image*)image;
+ Display *x_dpy = YAGL_X11_DPY(image->dpy->os_dpy);
+ Pixmap x_pixmap = YAGL_X11_DRAWABLE(os_pixmap);
+ GC x_gc = XCreateGC(x_dpy, x_pixmap, 0, NULL);
+
+ if (x_gc) {
+ yagl_x11_image_draw_internal(x11_image, x_pixmap, x_gc);
+ XFreeGC(x_dpy, x_gc);
+ }
+}
+
+static void yagl_x11_image_destroy(struct yagl_native_image *image)
+{
+ struct yagl_x11_image *x11_image = (struct yagl_x11_image*)image;
+
+ if (x11_image->is_wrapped) {
+ XDestroyImage(x11_image->x_image);
+ x11_image->x_image = NULL;
+ } else {
+ Display *x_dpy = YAGL_X11_DPY(image->dpy->os_dpy);
+
+ if (x11_image->x_shm.shmid != -1) {
+ XShmDetach(x_dpy, &x11_image->x_shm);
+
+ shmdt(x11_image->x_shm.shmaddr);
+ x11_image->x_shm.shmaddr = (char*)-1;
+
+ shmctl(x11_image->x_shm.shmid, IPC_RMID, 0);
+ x11_image->x_shm.shmid = -1;
+
+ XDestroyImage(x11_image->x_image);
+ x11_image->x_image = NULL;
+ } else {
+ yagl_free(x11_image->x_image);
+ x11_image->x_image = NULL;
+
+ yagl_free(image->pixels);
+ }
+ }
+
+ yagl_native_image_cleanup(image);
+
+ yagl_free(x11_image);
+}
+
+struct yagl_native_image
+ *yagl_x11_image_create(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ struct yagl_x11_display *x11_dpy = (struct yagl_x11_display*)dpy;
+ Display *x_dpy = YAGL_X11_DPY(dpy->os_dpy);
+ struct yagl_x11_image *image;
+ XPixmapFormatValues *pfs;
+ int i, num_formats;
+ Visual visual;
+ unsigned int image_bytes = 0;
+ void *pixels = NULL;
+ uint32_t bpp = 0;
+
+ YAGL_LOG_FUNC_ENTER(yagl_x11_image_create,
+ "width = %u, height = %u, depth = %u",
+ width, height, depth);
+
+ image = yagl_malloc0(sizeof(*image));
+
+ pfs = XListPixmapFormats(x_dpy, &num_formats);
+
+ if (!pfs) {
+ YAGL_LOG_ERROR("XListPixmapFormats failed");
+
+ goto fail;
+ }
+
+ for (i = 0; i < num_formats; ++i) {
+ if (pfs[i].depth == (int)depth) {
+ bpp = (pfs[i].bits_per_pixel / 8);
+ break;
+ }
+ }
+
+ XFree(pfs);
+ pfs = NULL;
+
+ if (i == num_formats) {
+ YAGL_LOG_ERROR("No suitable pixmap format found for depth %u", depth);
+
+ goto fail;
+ }
+
+ if (x11_dpy->xshm_images_supported) {
+ image->x_image = XShmCreateImage(x_dpy,
+ &visual,
+ depth,
+ ZPixmap,
+ NULL,
+ &image->x_shm,
+ width,
+ height);
+ if (image->x_image) {
+ image_bytes = image->x_image->bytes_per_line * image->x_image->height;
+
+ image->x_shm.shmid = shmget(IPC_PRIVATE,
+ image_bytes,
+ IPC_CREAT | 0777);
+
+ if (image->x_shm.shmid != -1) {
+ image->x_shm.shmaddr = shmat(image->x_shm.shmid, 0, 0);
+
+ if (image->x_shm.shmaddr != (char*)-1) {
+ if (XShmAttach(x_dpy, &image->x_shm)) {
+ pixels = image->x_image->data = image->x_shm.shmaddr;
+
+ goto allocated;
+ } else {
+ YAGL_LOG_ERROR("XShmAttach failed");
+ }
+
+ shmdt(image->x_shm.shmaddr);
+ image->x_shm.shmaddr = (char*)-1;
+ } else {
+ YAGL_LOG_ERROR("shmat failed");
+ }
+
+ shmctl(image->x_shm.shmid, IPC_RMID, 0);
+ image->x_shm.shmid = -1;
+ } else {
+ YAGL_LOG_ERROR("shmget failed");
+ }
+
+ XDestroyImage(image->x_image);
+ image->x_image = NULL;
+ } else {
+ YAGL_LOG_ERROR("XShmCreateImage failed");
+ }
+ }
+
+allocated:
+ if (!image->x_image) {
+ image->x_shm.shmid = -1;
+
+ image_bytes = width * height * bpp;
+
+ pixels = yagl_malloc(image_bytes);
+
+ image->x_image = yagl_malloc0(sizeof(*image->x_image));
+
+ image->x_image->width = width;
+ image->x_image->height = height;
+ image->x_image->xoffset = 0;
+ image->x_image->format = ZPixmap;
+ image->x_image->data = pixels;
+ image->x_image->byte_order = LSBFirst;
+ image->x_image->bitmap_unit = bpp * 8;
+ image->x_image->bitmap_pad = 8;
+ image->x_image->depth = depth;
+ image->x_image->bytes_per_line = width * bpp;
+ image->x_image->bits_per_pixel = bpp * 8;
+
+ if (!XInitImage(image->x_image)) {
+ YAGL_LOG_ERROR("XInitImage failed");
+
+ yagl_free(image->x_image);
+ image->x_image = NULL;
+
+ yagl_free(pixels);
+ pixels = NULL;
+
+ goto fail;
+ }
+ }
+
+ XSync(x_dpy, 0);
+
+ yagl_native_image_init(&image->base,
+ dpy,
+ width,
+ height,
+ depth,
+ bpp,
+ pixels);
+
+ image->base.draw = &yagl_x11_image_draw;
+ image->base.draw_to_pixmap = &yagl_x11_image_draw_to_pixmap;
+ image->base.destroy = &yagl_x11_image_destroy;
+
+ image->is_wrapped = 0;
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return &image->base;
+
+fail:
+ yagl_free(image);
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return NULL;
+}
+
+struct yagl_native_image
+ *yagl_x11_image_wrap(struct yagl_native_display *dpy,
+ XImage *x_image)
+{
+ struct yagl_x11_image *image;
+
+ image = yagl_malloc0(sizeof(*image));
+
+ yagl_native_image_init(&image->base,
+ dpy,
+ x_image->width,
+ x_image->height,
+ x_image->depth,
+ (x_image->bits_per_pixel / 8),
+ x_image->data);
+
+ image->base.draw = &yagl_x11_image_draw;
+ image->base.draw_to_pixmap = &yagl_x11_image_draw_to_pixmap;
+ image->base.destroy = &yagl_x11_image_destroy;
+
+ image->x_image = x_image;
+ image->x_shm.shmid = -1;
+ image->is_wrapped = 1;
+
+ return &image->base;
+}
diff --git a/EGL/x11/yagl_x11_image.h b/EGL/x11/yagl_x11_image.h
new file mode 100644
index 0000000..f6853a8
--- /dev/null
+++ b/EGL/x11/yagl_x11_image.h
@@ -0,0 +1,32 @@
+#ifndef _YAGL_X11_IMAGE_H_
+#define _YAGL_X11_IMAGE_H_
+
+#include "yagl_export.h"
+#include "yagl_native_image.h"
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+struct yagl_x11_image
+{
+ struct yagl_native_image base;
+
+ XImage *x_image; /* X11 image */
+ XShmSegmentInfo x_shm; /* X11 shared memory segment */
+
+ int is_wrapped;
+};
+
+struct yagl_native_image
+ *yagl_x11_image_create(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth);
+
+/*
+ * Takes ownership of 'x_image'.
+ */
+struct yagl_native_image
+ *yagl_x11_image_wrap(struct yagl_native_display *dpy,
+ XImage *x_image);
+
+#endif
diff --git a/EGL/x11/yagl_x11_platform.c b/EGL/x11/yagl_x11_platform.c
new file mode 100644
index 0000000..6840adf
--- /dev/null
+++ b/EGL/x11/yagl_x11_platform.c
@@ -0,0 +1,55 @@
+#include "yagl_x11_platform.h"
+#include "yagl_x11_display.h"
+#include "yagl_native_platform.h"
+#include "yagl_log.h"
+#include "EGL/egl.h"
+#include <X11/Xlib.h>
+
+static int yagl_x11_platform_probe(yagl_os_display os_dpy)
+{
+ /*
+ * Can't probe for X11, so assume probe passed.
+ */
+
+ return 1;
+}
+
+static struct yagl_native_display
+ *yagl_x11_wrap_display(yagl_os_display os_dpy,
+ int enable_drm)
+{
+ struct yagl_native_display *dpy;
+
+ YAGL_LOG_FUNC_SET(eglGetDisplay);
+
+ if (os_dpy == (yagl_os_display)EGL_DEFAULT_DISPLAY) {
+ Display *x_dpy = XOpenDisplay(0);
+
+ if (!x_dpy) {
+ YAGL_LOG_ERROR("unable to open display 0");
+ return NULL;
+ }
+
+ dpy = yagl_x11_display_create(&yagl_x11_platform,
+ (yagl_os_display)x_dpy,
+ 1,
+ enable_drm);
+
+ if (!dpy) {
+ XCloseDisplay(x_dpy);
+ }
+ } else {
+ dpy = yagl_x11_display_create(&yagl_x11_platform,
+ os_dpy,
+ 0,
+ enable_drm);
+ }
+
+ return dpy;
+}
+
+struct yagl_native_platform yagl_x11_platform =
+{
+ .probe = yagl_x11_platform_probe,
+ .wrap_display = yagl_x11_wrap_display
+};
diff --git a/EGL/x11/yagl_x11_platform.h b/EGL/x11/yagl_x11_platform.h
new file mode 100644
index 0000000..e167ffd
--- /dev/null
+++ b/EGL/x11/yagl_x11_platform.h
@@ -0,0 +1,10 @@
+#ifndef _YAGL_X11_PLATFORM_H_
+#define _YAGL_X11_PLATFORM_H_
+
+#include "yagl_export.h"
+
+struct yagl_native_platform;
+
+extern struct yagl_native_platform yagl_x11_platform;
+
+#endif
diff --git a/EGL/yagl_backend.h b/EGL/yagl_backend.h
index 6207869..d326ec6 100644
--- a/EGL/yagl_backend.h
+++ b/EGL/yagl_backend.h
@@ -3,37 +3,48 @@
#include "yagl_export.h"
#include "yagl_types.h"
-#include <X11/X.h>
+#include "yagl_native_types.h"
#include "EGL/egl.h"
struct yagl_display;
struct yagl_surface;
struct yagl_image;
+struct yagl_native_platform;
+struct yagl_native_drawable;
struct yagl_backend
{
- struct yagl_display *(*create_display)(EGLNativeDisplayType /*display_id*/,
- Display */*x_dpy*/,
+ struct yagl_display *(*create_display)(struct yagl_native_platform */*platform*/,
+ yagl_os_display /*os_dpy*/,
yagl_host_handle /*host_dpy*/);
+ /*
+ * Takes ownership of 'native_window'.
+ */
struct yagl_surface *(*create_window_surface)(struct yagl_display */*dpy*/,
yagl_host_handle /*host_config*/,
- Window /*x_win*/,
- const EGLint* /*attrib_list*/);
+ struct yagl_native_drawable */*native_window*/,
+ const EGLint */*attrib_list*/);
+ /*
+ * Takes ownership of 'native_pixmap'.
+ */
struct yagl_surface *(*create_pixmap_surface)(struct yagl_display */*dpy*/,
yagl_host_handle /*host_config*/,
- Pixmap /*x_pixmap*/,
- const EGLint* /*attrib_list*/);
+ struct yagl_native_drawable */*native_pixmap*/,
+ const EGLint */*attrib_list*/);
struct yagl_surface *(*create_pbuffer_surface)(struct yagl_display */*dpy*/,
yagl_host_handle /*host_config*/,
- const EGLint* /*attrib_list*/);
+ const EGLint */*attrib_list*/);
+ /*
+ * Takes ownership of 'native_pixmap'.
+ */
struct yagl_image *(*create_image)(struct yagl_display */*dpy*/,
yagl_host_handle /*host_context*/,
- Pixmap /*x_pixmap*/,
- const EGLint* /*attrib_list*/);
+ struct yagl_native_drawable */*native_pixmap*/,
+ const EGLint */*attrib_list*/);
void (*destroy)(struct yagl_backend */*backend*/);
diff --git a/EGL/yagl_bimage.c b/EGL/yagl_bimage.c
deleted file mode 100644
index 1265deb..0000000
--- a/EGL/yagl_bimage.c
+++ /dev/null
@@ -1,208 +0,0 @@
-#include "yagl_bimage.h"
-#include "yagl_log.h"
-#include "yagl_malloc.h"
-#include "yagl_display.h"
-#include "yagl_mem.h"
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/time.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct yagl_bimage *yagl_bimage_create(struct yagl_display *dpy,
- uint32_t width,
- uint32_t height,
- uint32_t depth)
-{
- struct yagl_bimage *res = NULL;
- XPixmapFormatValues *pfs;
- int i, num_formats;
- Visual visual;
- unsigned int image_bytes = 0;
-
- YAGL_LOG_FUNC_ENTER(yagl_bimage_create,
- "width = %u, height = %u, depth = %u",
- width, height, depth);
-
- res = yagl_malloc0(sizeof(*res));
-
- res->width = width;
- res->height = height;
- res->depth = depth;
- res->dpy = dpy;
-
- pfs = XListPixmapFormats(dpy->x_dpy, &num_formats);
-
- if (!pfs) {
- YAGL_LOG_ERROR("XListPixmapFormats failed");
-
- goto fail;
- }
-
- for (i = 0; i < num_formats; ++i) {
- if (pfs[i].depth == (int)depth) {
- res->bpp = (pfs[i].bits_per_pixel / 8);
- break;
- }
- }
-
- XFree(pfs);
- pfs = NULL;
-
- if (i == num_formats) {
- YAGL_LOG_ERROR("No suitable pixmap format found for depth %u", depth);
-
- goto fail;
- }
-
- if (dpy->xshm_images_supported) {
- res->x_image = XShmCreateImage(dpy->x_dpy,
- &visual,
- depth,
- ZPixmap,
- NULL,
- &res->x_shm,
- width,
- height);
- if (res->x_image) {
- image_bytes = res->x_image->bytes_per_line * res->x_image->height;
-
- res->x_shm.shmid = shmget(IPC_PRIVATE, image_bytes, IPC_CREAT | 0777);
-
- if (res->x_shm.shmid != -1) {
- res->x_shm.shmaddr = shmat(res->x_shm.shmid, 0, 0);
-
- if (res->x_shm.shmaddr != (char*)-1) {
- if (XShmAttach(dpy->x_dpy, &res->x_shm)) {
- res->pixels = res->x_image->data = res->x_shm.shmaddr;
-
- goto allocated;
- } else {
- YAGL_LOG_ERROR("XShmAttach failed");
- }
-
- shmdt(res->x_shm.shmaddr);
- res->x_shm.shmaddr = (char*)-1;
- } else {
- YAGL_LOG_ERROR("shmat failed");
- }
-
- shmctl(res->x_shm.shmid, IPC_RMID, 0);
- res->x_shm.shmid = -1;
- } else {
- YAGL_LOG_ERROR("shmget failed");
- }
-
- XDestroyImage(res->x_image);
- res->x_image = NULL;
- } else {
- YAGL_LOG_ERROR("XShmCreateImage failed");
- }
- }
-
-allocated:
- if (!dpy->xshm_images_supported || !res->x_image) {
- image_bytes = width * height * res->bpp;
-
- res->pixels = yagl_malloc(image_bytes);
-
- res->x_image = yagl_malloc0(sizeof(*res->x_image));
-
- res->x_image->width = res->width;
- res->x_image->height = res->height;
- res->x_image->xoffset = 0;
- res->x_image->format = ZPixmap;
- res->x_image->data = res->pixels;
- res->x_image->byte_order = LSBFirst;
- res->x_image->bitmap_unit = res->bpp * 8;
- res->x_image->bitmap_pad = 8;
- res->x_image->depth = res->depth;
- res->x_image->bytes_per_line = res->width * res->bpp;
- res->x_image->bits_per_pixel = res->bpp * 8;
-
- if (!XInitImage(res->x_image)) {
- YAGL_LOG_ERROR("XInitImage failed");
-
- yagl_free(res->x_image);
- res->x_image = NULL;
-
- yagl_free(res->pixels);
- res->pixels = NULL;
-
- goto fail;
- }
- }
-
- XSync(dpy->x_dpy, 0);
-
- if (mlock(res->pixels, res->width * res->height * res->bpp) == -1)
- {
- fprintf(stderr, "Critical error! Unable to lock YaGL bimage memory: %s!\n", strerror(errno));
- exit(1);
- }
-
- /*
- * Probe in immediately.
- */
-
- yagl_mem_probe_write(res->pixels, res->width * res->height * res->bpp);
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return res;
-
-fail:
- yagl_free(res);
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return NULL;
-}
-
-void yagl_bimage_destroy(struct yagl_bimage *bi)
-{
- if (munlock(bi->pixels, bi->width * bi->height * bi->bpp) == -1)
- {
- fprintf(stderr, "Critical error! Unable to unlock YaGL bimage memory: %s!\n", strerror(errno));
- exit(1);
- }
-
- if (bi->x_shm.shmid != -1) {
- XShmDetach(bi->dpy->x_dpy, &bi->x_shm);
-
- shmdt(bi->x_shm.shmaddr);
- bi->x_shm.shmaddr = (char*)-1;
-
- shmctl(bi->x_shm.shmid, IPC_RMID, 0);
- bi->x_shm.shmid = -1;
-
- XDestroyImage(bi->x_image);
- bi->x_image = NULL;
-
- bi->pixels = NULL;
- } else {
- yagl_free(bi->x_image);
- bi->x_image = NULL;
-
- yagl_free(bi->pixels);
- bi->pixels = NULL;
- }
-
- yagl_free(bi);
-}
-
-void yagl_bimage_draw(struct yagl_bimage *bi, Drawable target, GC gc)
-{
- if (bi->x_shm.shmid != -1) {
- XShmPutImage(bi->dpy->x_dpy, target, gc, bi->x_image,
- 0, 0, 0, 0, bi->width, bi->height, 0);
- } else {
- XPutImage(bi->dpy->x_dpy, target, gc, bi->x_image,
- 0, 0, 0, 0, bi->width, bi->height);
- }
-
- XFlush(bi->dpy->x_dpy);
-}
diff --git a/EGL/yagl_bimage.h b/EGL/yagl_bimage.h
deleted file mode 100644
index 98ee5d0..0000000
--- a/EGL/yagl_bimage.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _YAGL_BIMAGE_H_
-#define _YAGL_BIMAGE_H_
-
-#include "yagl_export.h"
-#include "yagl_types.h"
-#include "EGL/egl.h"
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
-
-/*
- * Backing image for offscreen surfaces.
- */
-
-struct yagl_display;
-
-struct yagl_bimage
-{
- uint32_t width;
- uint32_t height;
- uint32_t depth; /* bit-depth. e.g.: 24 */
-
- uint32_t bpp; /* bytes-per-pixel. e.g.: 3 */
- void *pixels; /* pixel data */
-
- struct yagl_display *dpy; /* The owning display */
- XShmSegmentInfo x_shm; /* X11 shared memory segment */
- XImage* x_image; /* X11 image */
-};
-
-struct yagl_bimage *yagl_bimage_create(struct yagl_display *dpy,
- uint32_t width,
- uint32_t height,
- uint32_t depth);
-
-void yagl_bimage_destroy(struct yagl_bimage *bi);
-
-void yagl_bimage_draw(struct yagl_bimage *bi, Drawable target, GC gc);
-
-#endif
diff --git a/EGL/yagl_display.c b/EGL/yagl_display.c
index 543c13b..f2bcb27 100644
--- a/EGL/yagl_display.c
+++ b/EGL/yagl_display.c
@@ -5,8 +5,7 @@
#include "yagl_surface.h"
#include "yagl_context.h"
#include "yagl_image.h"
-#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
+#include "yagl_native_display.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -31,19 +30,13 @@ static void yagl_displays_init(void)
}
void yagl_display_init(struct yagl_display *dpy,
- EGLNativeDisplayType display_id,
- Display *x_dpy,
+ yagl_os_display display_id,
+ struct yagl_native_display *native_dpy,
yagl_host_handle host_dpy)
{
- int xmajor;
- int xminor;
- Bool pixmaps;
-
- YAGL_LOG_FUNC_SET(eglGetDisplay);
-
yagl_list_init(&dpy->list);
dpy->display_id = display_id;
- dpy->x_dpy = x_dpy;
+ dpy->native_dpy = native_dpy;
dpy->host_dpy = host_dpy;
/*
* Need recursive mutex here,
@@ -51,35 +44,15 @@ void yagl_display_init(struct yagl_display *dpy,
*/
yagl_recursive_mutex_init(&dpy->mutex);
dpy->prepared = 0;
- dpy->xshm_images_supported = XShmQueryVersion(dpy->x_dpy,
- &xmajor,
- &xminor,
- &pixmaps);
- dpy->xshm_pixmaps_supported = pixmaps;
-
- YAGL_LOG_DEBUG("XShm images are%s supported, version %d, %d (pixmaps = %d)",
- (dpy->xshm_images_supported ? "" : " NOT"),
- xmajor,
- xminor,
- pixmaps);
yagl_list_init(&dpy->surfaces);
yagl_list_init(&dpy->contexts);
yagl_list_init(&dpy->images);
}
-void yagl_display_cleanup(struct yagl_display *dpy)
-{
- assert(yagl_list_empty(&dpy->images));
- assert(yagl_list_empty(&dpy->contexts));
- assert(yagl_list_empty(&dpy->surfaces));
- pthread_mutex_destroy(&dpy->mutex);
- assert(yagl_list_empty(&dpy->list));
-}
-
-struct yagl_display *yagl_display_get(EGLDisplay native_dpy)
+struct yagl_display *yagl_display_get(EGLDisplay handle)
{
- yagl_host_handle host_dpy = (yagl_host_handle)native_dpy;
+ yagl_host_handle host_dpy = (yagl_host_handle)handle;
struct yagl_display *dpy;
yagl_displays_init();
@@ -99,7 +72,7 @@ struct yagl_display *yagl_display_get(EGLDisplay native_dpy)
return NULL;
}
-struct yagl_display *yagl_display_get_x(Display *x_dpy)
+struct yagl_display *yagl_display_get_os(yagl_os_display os_dpy)
{
struct yagl_display *dpy;
@@ -108,7 +81,7 @@ struct yagl_display *yagl_display_get_x(Display *x_dpy)
pthread_mutex_lock(&g_displays_mutex);
yagl_list_for_each(struct yagl_display, dpy, &g_displays, list) {
- if (dpy->x_dpy == x_dpy) {
+ if (dpy->native_dpy->os_dpy == os_dpy) {
pthread_mutex_unlock(&g_displays_mutex);
return dpy;
@@ -120,11 +93,11 @@ struct yagl_display *yagl_display_get_x(Display *x_dpy)
return NULL;
}
-struct yagl_display *yagl_display_add(EGLNativeDisplayType display_id,
+struct yagl_display *yagl_display_add(struct yagl_native_platform *platform,
+ yagl_os_display display_id,
yagl_host_handle host_dpy)
{
struct yagl_display *dpy;
- Display *x_dpy;
YAGL_LOG_FUNC_SET(eglGetDisplay);
@@ -150,29 +123,9 @@ struct yagl_display *yagl_display_add(EGLNativeDisplayType display_id,
}
}
- if (display_id == EGL_DEFAULT_DISPLAY) {
- x_dpy = XOpenDisplay(0);
-
- if (!x_dpy) {
- pthread_mutex_unlock(&g_displays_mutex);
-
- YAGL_LOG_ERROR("unable to open display 0");
-
- return NULL;
- }
- } else {
- x_dpy = display_id;
- }
-
- dpy = yagl_get_backend()->create_display(display_id,
- x_dpy,
- host_dpy);
+ dpy = yagl_get_backend()->create_display(platform, display_id, host_dpy);
if (!dpy) {
- if (display_id == EGL_DEFAULT_DISPLAY) {
- XCloseDisplay(x_dpy);
- }
-
pthread_mutex_unlock(&g_displays_mutex);
return NULL;
@@ -266,7 +219,7 @@ void yagl_display_terminate(struct yagl_display *dpy)
}
int yagl_display_surface_add(struct yagl_display *dpy,
- struct yagl_surface *sfc)
+ struct yagl_surface *sfc)
{
struct yagl_resource *res = NULL;
EGLSurface handle = yagl_surface_get_handle(sfc);
diff --git a/EGL/yagl_display.h b/EGL/yagl_display.h
index 00855ff..dae320a 100644
--- a/EGL/yagl_display.h
+++ b/EGL/yagl_display.h
@@ -4,6 +4,7 @@
#include "yagl_export.h"
#include "yagl_types.h"
#include "yagl_list.h"
+#include "yagl_native_types.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include <pthread.h>
@@ -11,21 +12,19 @@
struct yagl_surface;
struct yagl_context;
struct yagl_image;
+struct yagl_native_platform;
+struct yagl_native_display;
struct yagl_display
{
struct yagl_list list;
- EGLNativeDisplayType display_id;
+ yagl_os_display display_id;
- Display *x_dpy;
+ struct yagl_native_display *native_dpy;
yagl_host_handle host_dpy;
- int xshm_images_supported;
-
- int xshm_pixmaps_supported;
-
pthread_mutex_t mutex;
int prepared;
@@ -37,18 +36,20 @@ struct yagl_display
struct yagl_list images;
};
+/*
+ * Takes ownership of 'native_dpy'.
+ */
void yagl_display_init(struct yagl_display *dpy,
- EGLNativeDisplayType display_id,
- Display *x_dpy,
+ yagl_os_display display_id,
+ struct yagl_native_display *native_dpy,
yagl_host_handle host_dpy);
-void yagl_display_cleanup(struct yagl_display *dpy);
-
-struct yagl_display *yagl_display_get(EGLDisplay native_dpy);
+struct yagl_display *yagl_display_get(EGLDisplay handle);
-struct yagl_display *yagl_display_get_x(Display *x_dpy);
+struct yagl_display *yagl_display_get_os(yagl_os_display os_dpy);
-struct yagl_display *yagl_display_add(EGLNativeDisplayType display_id,
+struct yagl_display *yagl_display_add(struct yagl_native_platform *platform,
+ yagl_os_display display_id,
yagl_host_handle host_dpy);
void yagl_display_prepare(struct yagl_display *dpy);
diff --git a/EGL/yagl_egl_calls.c b/EGL/yagl_egl_calls.c
index 8c3a417..f9aac39 100644
--- a/EGL/yagl_egl_calls.c
+++ b/EGL/yagl_egl_calls.c
@@ -10,6 +10,9 @@
#include "yagl_mem_egl.h"
#include "yagl_backend.h"
#include "yagl_render.h"
+#include "yagl_native_platform.h"
+#include "yagl_native_display.h"
+#include "yagl_native_drawable.h"
#include "EGL/eglext.h"
#include <stdio.h>
#include <string.h>
@@ -97,24 +100,33 @@ YAGL_API EGLint eglGetError()
YAGL_API EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
{
+ struct yagl_native_platform *platform;
yagl_host_handle host_dpy;
struct yagl_display *dpy;
EGLDisplay ret = EGL_NO_DISPLAY;
YAGL_LOG_FUNC_ENTER_SPLIT1(eglGetDisplay, EGLNativeDisplayType, display_id);
+ platform = yagl_guess_platform((yagl_os_display)display_id);
+
+ if (!platform) {
+ goto out;
+ }
+
YAGL_HOST_CALL_ASSERT(yagl_host_eglGetDisplay(&host_dpy, display_id));
if (!host_dpy) {
- YAGL_LOG_ERROR("unable to get host display for %p", display_id);
+ YAGL_LOG_ERROR("unable to get host display for %p",
+ (yagl_os_display)display_id);
goto out;
}
- dpy = yagl_display_add(display_id, host_dpy);
+ dpy = yagl_display_add(platform, (yagl_os_display)display_id, host_dpy);
if (!dpy) {
YAGL_SET_ERR(EGL_BAD_DISPLAY);
- YAGL_LOG_ERROR("unable to add display %p, %u", display_id, host_dpy);
+ YAGL_LOG_ERROR("unable to add display %p, %u",
+ (yagl_os_display)display_id, host_dpy);
goto out;
}
@@ -231,7 +243,7 @@ YAGL_API EGLBoolean eglGetConfigs( EGLDisplay dpy_,
EGLint* num_config )
{
EGLBoolean retval = EGL_FALSE;
- yagl_host_handle* configs = NULL;
+ yagl_host_handle *configs = NULL;
EGLint i;
YAGL_LOG_FUNC_ENTER(eglGetConfigs,
@@ -285,7 +297,7 @@ YAGL_API EGLBoolean eglChooseConfig( EGLDisplay dpy,
EGLint* num_config )
{
EGLBoolean retval = EGL_FALSE;
- yagl_host_handle* configs = NULL;
+ yagl_host_handle *configs = NULL;
EGLint i;
YAGL_LOG_FUNC_ENTER(eglChooseConfig, "dpy = %u", (yagl_host_handle)dpy);
@@ -337,8 +349,7 @@ YAGL_API EGLBoolean eglGetConfigAttrib( EGLDisplay dpy_,
{
struct yagl_display *dpy = NULL;
EGLBoolean ret = EGL_FALSE;
- int screen;
- XVisualInfo vi;
+ int visual_id = 0, visual_type = 0;
YAGL_LOG_FUNC_ENTER(eglGetConfigAttrib,
"dpy = %u, config = %u, attribute = 0x%X",
@@ -357,22 +368,18 @@ YAGL_API EGLBoolean eglGetConfigAttrib( EGLDisplay dpy_,
break;
case EGL_NATIVE_VISUAL_ID:
case EGL_NATIVE_VISUAL_TYPE:
- screen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(dpy->x_dpy));
-
- /*
- * 24-bit is the highest supported by soft framebuffer.
- */
- if (!XMatchVisualInfo(dpy->x_dpy, screen, 24, TrueColor, &vi))
- {
+ if (!dpy->native_dpy->get_visual(dpy->native_dpy,
+ &visual_id,
+ &visual_type)) {
YAGL_SET_ERR(EGL_BAD_CONFIG);
- YAGL_LOG_ERROR("XMatchVisualInfo failed");
+ YAGL_LOG_ERROR("get_visual failed");
goto fail;
}
if (attribute == EGL_NATIVE_VISUAL_ID) {
- *value = XVisualIDFromVisual(vi.visual);
+ *value = visual_id;
} else {
- *value = TrueColor;
+ *value = visual_type;
}
ret = EGL_TRUE;
@@ -410,6 +417,7 @@ YAGL_API EGLSurface eglCreateWindowSurface( EGLDisplay dpy_,
const EGLint* attrib_list)
{
struct yagl_display *dpy = NULL;
+ struct yagl_native_drawable *native_win = NULL;
struct yagl_surface *surface = NULL;
YAGL_LOG_FUNC_ENTER(eglCreateWindowSurface,
@@ -421,12 +429,21 @@ YAGL_API EGLSurface eglCreateWindowSurface( EGLDisplay dpy_,
goto fail;
}
+ native_win = dpy->native_dpy->wrap_window(dpy->native_dpy,
+ (yagl_os_window)win);
+
+ if (!native_win) {
+ goto fail;
+ }
+
surface = yagl_get_backend()->create_window_surface(dpy,
(yagl_host_handle)config,
- win,
+ native_win,
attrib_list);
if (!surface) {
+ native_win->destroy(native_win);
+ native_win = NULL;
goto fail;
}
@@ -506,6 +523,7 @@ YAGL_API EGLSurface eglCreatePixmapSurface( EGLDisplay dpy_,
const EGLint* attrib_list )
{
struct yagl_display *dpy = NULL;
+ struct yagl_native_drawable *native_pixmap = NULL;
struct yagl_surface *surface = NULL;
YAGL_LOG_FUNC_ENTER(eglCreatePixmapSurface,
@@ -517,12 +535,21 @@ YAGL_API EGLSurface eglCreatePixmapSurface( EGLDisplay dpy_,
goto fail;
}
+ native_pixmap = dpy->native_dpy->wrap_pixmap(dpy->native_dpy,
+ (yagl_os_pixmap)pixmap);
+
+ if (!native_pixmap) {
+ goto fail;
+ }
+
surface = yagl_get_backend()->create_pixmap_surface(dpy,
(yagl_host_handle)config,
- pixmap,
+ native_pixmap,
attrib_list);
if (!surface) {
+ native_pixmap->destroy(native_pixmap);
+ native_pixmap = NULL;
goto fail;
}
@@ -1328,6 +1355,7 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
{
EGLImageKHR ret = EGL_NO_IMAGE_KHR;
struct yagl_display *dpy = NULL;
+ struct yagl_native_drawable *native_buffer = NULL;
struct yagl_image *image = NULL;
YAGL_LOG_FUNC_ENTER(eglCreateImageKHR,
@@ -1351,12 +1379,21 @@ YAGL_API EGLImageKHR eglCreateImageKHR( EGLDisplay dpy_,
goto out;
}
+ native_buffer = dpy->native_dpy->wrap_pixmap(dpy->native_dpy,
+ (yagl_os_pixmap)buffer);
+
+ if (!native_buffer) {
+ goto out;
+ }
+
image = yagl_get_backend()->create_image(dpy,
(yagl_host_handle)ctx,
- (Pixmap)buffer,
+ native_buffer,
attrib_list);
if (!image) {
+ native_buffer->destroy(native_buffer);
+ native_buffer = NULL;
goto out;
}
diff --git a/EGL/yagl_egl_calls.in b/EGL/yagl_egl_calls.in
index 29b02d3..6bd93e9 100644
--- a/EGL/yagl_egl_calls.in
+++ b/EGL/yagl_egl_calls.in
@@ -1,5 +1,5 @@
EGLint, eglGetError
-EGLDisplay^, eglGetDisplay, Display* display_id
+EGLDisplay^, eglGetDisplay, void* display_id
EGLBoolean, eglInitialize, EGLDisplay^ dpy, EGLint* major, EGLint* minor
EGLBoolean, eglTerminate, EGLDisplay^ dpy
EGLBoolean, eglGetConfigs, EGLDisplay^ dpy, EGLConfig^* configs, EGLint config_size, EGLint* num_config
diff --git a/EGL/yagl_host_egl_calls.c b/EGL/yagl_host_egl_calls.c
index 68e6f73..bcb150a 100644
--- a/EGL/yagl_host_egl_calls.c
+++ b/EGL/yagl_host_egl_calls.c
@@ -31,7 +31,7 @@ int yagl_host_eglGetError(EGLint* retval)
/*
* eglGetDisplay wrapper. id = 2
*/
-int yagl_host_eglGetDisplay(yagl_host_handle* retval, Display* display_id)
+int yagl_host_eglGetDisplay(yagl_host_handle* retval, void* display_id)
{
uint8_t* base = yagl_batch_get_marshal();
yagl_marshal_put_uint32(&base, yagl_api_id_egl);
diff --git a/EGL/yagl_host_egl_calls.h b/EGL/yagl_host_egl_calls.h
index 9b3baa1..ef0cba5 100644
--- a/EGL/yagl_host_egl_calls.h
+++ b/EGL/yagl_host_egl_calls.h
@@ -16,7 +16,7 @@ int yagl_host_eglGetError(EGLint* retval);
/*
* eglGetDisplay wrapper. id = 2
*/
-int yagl_host_eglGetDisplay(yagl_host_handle* retval, Display* display_id);
+int yagl_host_eglGetDisplay(yagl_host_handle* retval, void* display_id);
/*
* eglInitialize wrapper. id = 3
diff --git a/EGL/yagl_image.c b/EGL/yagl_image.c
index 2927560..becbdca 100644
--- a/EGL/yagl_image.c
+++ b/EGL/yagl_image.c
@@ -1,4 +1,5 @@
#include "yagl_image.h"
+#include "yagl_native_drawable.h"
static void yagl_gles_image_update(struct yagl_gles_image *image)
{
@@ -12,24 +13,26 @@ void yagl_image_init(struct yagl_image *image,
yagl_ref_destroy_func destroy_func,
yagl_host_handle handle,
struct yagl_display *dpy,
- Pixmap x_pixmap)
+ struct yagl_native_drawable *native_pixmap)
{
yagl_resource_init(&image->res, destroy_func, handle);
image->dpy = dpy;
- image->x_pixmap = x_pixmap;
+ image->native_pixmap = native_pixmap;
image->gles_image.host_image = 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->x_pixmap;
+ return (EGLImageKHR)image->native_pixmap->os_drawable;
}
void yagl_image_acquire(struct yagl_image *image)
diff --git a/EGL/yagl_image.h b/EGL/yagl_image.h
index d87ec84..cb14c54 100644
--- a/EGL/yagl_image.h
+++ b/EGL/yagl_image.h
@@ -4,7 +4,6 @@
#include "yagl_export.h"
#include "yagl_types.h"
#include "yagl_resource.h"
-#include <X11/X.h>
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "GLES2/gl2.h"
@@ -12,6 +11,7 @@
#include "yagl_gles_image.h"
struct yagl_display;
+struct yagl_native_drawable;
struct yagl_image
{
@@ -19,18 +19,21 @@ struct yagl_image
struct yagl_display *dpy;
- Pixmap x_pixmap;
+ struct yagl_native_drawable *native_pixmap;
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,
struct yagl_display *dpy,
- Pixmap x_pixmap);
+ struct yagl_native_drawable *native_pixmap);
void yagl_image_cleanup(struct yagl_image *image);
diff --git a/EGL/yagl_native_display.c b/EGL/yagl_native_display.c
new file mode 100644
index 0000000..8323b57
--- /dev/null
+++ b/EGL/yagl_native_display.c
@@ -0,0 +1,16 @@
+#include "yagl_native_display.h"
+
+void yagl_native_display_init(struct yagl_native_display *dpy,
+ struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
+ int drm_fd)
+{
+ dpy->platform = platform;
+ dpy->os_dpy = os_dpy;
+ dpy->drm_fd = drm_fd;
+}
+
+void yagl_native_display_cleanup(struct yagl_native_display *dpy)
+{
+ dpy->drm_fd = -1;
+}
diff --git a/EGL/yagl_native_display.h b/EGL/yagl_native_display.h
new file mode 100644
index 0000000..4d9be66
--- /dev/null
+++ b/EGL/yagl_native_display.h
@@ -0,0 +1,49 @@
+#ifndef _YAGL_NATIVE_DISPLAY_H_
+#define _YAGL_NATIVE_DISPLAY_H_
+
+#include "yagl_export.h"
+#include "yagl_native_types.h"
+
+struct yagl_native_platform;
+struct yagl_native_drawable;
+struct yagl_native_image;
+
+struct yagl_native_display
+{
+ struct yagl_native_platform *platform;
+
+ yagl_os_display os_dpy;
+
+ int drm_fd;
+
+ struct yagl_native_drawable *(*wrap_window)(struct yagl_native_display */*dpy*/,
+ yagl_os_window /*os_window*/);
+
+ struct yagl_native_drawable *(*wrap_pixmap)(struct yagl_native_display */*dpy*/,
+ yagl_os_pixmap /*os_pixmap*/);
+
+ struct yagl_native_drawable *(*create_pixmap)(struct yagl_native_display */*dpy*/,
+ uint32_t /*width*/,
+ uint32_t /*height*/,
+ uint32_t /*depth*/);
+
+ struct yagl_native_image *(*create_image)(struct yagl_native_display */*dpy*/,
+ uint32_t /*width*/,
+ uint32_t /*height*/,
+ uint32_t /*depth*/);
+
+ int (*get_visual)(struct yagl_native_display */*dpy*/,
+ int */*visual_id*/,
+ int */*visual_type*/);
+
+ void (*destroy)(struct yagl_native_display */*dpy*/);
+};
+
+void yagl_native_display_init(struct yagl_native_display *dpy,
+ struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
+ int drm_fd);
+
+void yagl_native_display_cleanup(struct yagl_native_display *dpy);
+
+#endif
diff --git a/EGL/yagl_native_drawable.c b/EGL/yagl_native_drawable.c
new file mode 100644
index 0000000..b926261
--- /dev/null
+++ b/EGL/yagl_native_drawable.c
@@ -0,0 +1,14 @@
+#include "yagl_native_drawable.h"
+
+void yagl_native_drawable_init(struct yagl_native_drawable *drawable,
+ struct yagl_native_display *dpy,
+ yagl_os_drawable os_drawable)
+{
+ drawable->dpy = dpy;
+ drawable->os_drawable = os_drawable;
+ drawable->stamp = 0;
+}
+
+void yagl_native_drawable_cleanup(struct yagl_native_drawable *drawable)
+{
+}
diff --git a/EGL/yagl_native_drawable.h b/EGL/yagl_native_drawable.h
new file mode 100644
index 0000000..f8d7dfc
--- /dev/null
+++ b/EGL/yagl_native_drawable.h
@@ -0,0 +1,63 @@
+#ifndef _YAGL_NATIVE_DRAWABLE_H_
+#define _YAGL_NATIVE_DRAWABLE_H_
+
+#include "yagl_export.h"
+#include "yagl_native_types.h"
+
+struct yagl_native_image;
+
+struct yagl_native_drawable
+{
+ struct yagl_native_display *dpy;
+
+ yagl_os_drawable os_drawable;
+
+ /*
+ * This gets incremented in drawable invalidate handler.
+ */
+ uint32_t stamp;
+
+ uint32_t (*get_buffer)(struct yagl_native_drawable */*drawable*/,
+ yagl_native_attachment /*attachment*/);
+
+ void (*swap_buffers)(struct yagl_native_drawable */*drawable*/);
+
+ /*
+ * 'width' and 'height' are here only because of DRI2.
+ * DRI2 requires width and height to be passed to DRI2CopyRegion.
+ */
+ void (*wait)(struct yagl_native_drawable */*drawable*/,
+ uint32_t /*width*/,
+ uint32_t /*height*/);
+
+ void (*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*/);
+
+ void (*set_swap_interval)(struct yagl_native_drawable */*drawable*/,
+ int /*interval*/);
+
+ void (*get_geometry)(struct yagl_native_drawable */*drawable*/,
+ uint32_t */*width*/,
+ uint32_t */*height*/,
+ uint32_t */*depth*/);
+
+ struct yagl_native_image *(*get_image)(struct yagl_native_drawable */*drawable*/,
+ uint32_t /*width*/,
+ uint32_t /*height*/);
+
+ void (*destroy)(struct yagl_native_drawable */*drawable*/);
+};
+
+void yagl_native_drawable_init(struct yagl_native_drawable *drawable,
+ struct yagl_native_display *dpy,
+ yagl_os_drawable os_drawable);
+
+void yagl_native_drawable_cleanup(struct yagl_native_drawable *drawable);
+
+#endif
diff --git a/EGL/yagl_native_image.c b/EGL/yagl_native_image.c
new file mode 100644
index 0000000..d567616
--- /dev/null
+++ b/EGL/yagl_native_image.c
@@ -0,0 +1,21 @@
+#include "yagl_native_image.h"
+
+void yagl_native_image_init(struct yagl_native_image *image,
+ struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth,
+ uint32_t bpp,
+ void *pixels)
+{
+ image->dpy = dpy;
+ image->width = width;
+ image->height = height;
+ image->depth = depth;
+ image->bpp = bpp;
+ image->pixels = pixels;
+}
+
+void yagl_native_image_cleanup(struct yagl_native_image *image)
+{
+}
diff --git a/EGL/yagl_native_image.h b/EGL/yagl_native_image.h
new file mode 100644
index 0000000..193a77b
--- /dev/null
+++ b/EGL/yagl_native_image.h
@@ -0,0 +1,39 @@
+#ifndef _YAGL_NATIVE_IMAGE_H_
+#define _YAGL_NATIVE_IMAGE_H_
+
+#include "yagl_export.h"
+#include "yagl_native_types.h"
+
+struct yagl_native_drawable;
+
+struct yagl_native_image
+{
+ struct yagl_native_display *dpy;
+
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth; /* bit-depth. e.g.: 24 */
+
+ uint32_t bpp; /* bytes-per-pixel. e.g.: 3 */
+ void *pixels; /* pixel data */
+
+ void (*draw)(struct yagl_native_image */*image*/,
+ struct yagl_native_drawable */*drawable*/);
+
+ void (*draw_to_pixmap)(struct yagl_native_image */*image*/,
+ yagl_os_pixmap /*os_pixmap*/);
+
+ void (*destroy)(struct yagl_native_image */*image*/);
+};
+
+void yagl_native_image_init(struct yagl_native_image *image,
+ struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth,
+ uint32_t bpp,
+ void *pixels);
+
+void yagl_native_image_cleanup(struct yagl_native_image *image);
+
+#endif
diff --git a/EGL/yagl_native_platform.c b/EGL/yagl_native_platform.c
new file mode 100644
index 0000000..3fd8ada
--- /dev/null
+++ b/EGL/yagl_native_platform.c
@@ -0,0 +1,60 @@
+#include "yagl_native_platform.h"
+#ifdef YAGL_PLATFORM_X11
+#include "x11/yagl_x11_platform.h"
+#endif
+#ifdef YAGL_PLATFORM_GBM
+#include "gbm/yagl_gbm_platform.h"
+#endif
+#include "yagl_log.h"
+#include <stdlib.h>
+#include <string.h>
+
+static struct
+{
+ struct yagl_native_platform *platform;
+ const char *name;
+} g_platforms[] =
+{
+#ifdef YAGL_PLATFORM_GBM
+ {&yagl_gbm_platform, "gbm"},
+#endif
+#ifdef YAGL_PLATFORM_X11
+ {&yagl_x11_platform, "x11"},
+#endif
+};
+
+struct yagl_native_platform *yagl_guess_platform(yagl_os_display os_dpy)
+{
+ const char *platform_name = NULL;
+ uint32_t i;
+
+ YAGL_LOG_FUNC_SET(yagl_guess_platform);
+
+ platform_name = getenv("EGL_PLATFORM");
+
+ if (!platform_name || !platform_name[0]) {
+ platform_name = getenv("EGL_DISPLAY");
+ }
+
+ if (platform_name && platform_name[0]) {
+ for (i = 0; i < sizeof(g_platforms)/sizeof(g_platforms[0]); ++i) {
+ if (strcmp(g_platforms[i].name, platform_name) == 0) {
+ YAGL_LOG_INFO("EGL platform %s chosen by environment variable",
+ g_platforms[i].name);
+ return g_platforms[i].platform;
+ }
+ }
+ }
+
+ for (i = 0; i < sizeof(g_platforms)/sizeof(g_platforms[0]); ++i) {
+ if (g_platforms[i].platform->probe(os_dpy)) {
+ YAGL_LOG_INFO("EGL platform %s chosen by probing",
+ g_platforms[i].name);
+ return g_platforms[i].platform;
+ }
+ }
+
+ YAGL_LOG_ERROR("No EGL platform chosen");
+
+ return NULL;
+}
diff --git a/EGL/yagl_native_platform.h b/EGL/yagl_native_platform.h
new file mode 100644
index 0000000..b852e22
--- /dev/null
+++ b/EGL/yagl_native_platform.h
@@ -0,0 +1,23 @@
+#ifndef _YAGL_NATIVE_PLATFORM_H_
+#define _YAGL_NATIVE_PLATFORM_H_
+
+#include "yagl_export.h"
+#include "yagl_native_types.h"
+
+struct yagl_native_display;
+
+struct yagl_native_platform
+{
+ int (*probe)(yagl_os_display /*os_dpy*/);
+
+ struct yagl_native_display *(*wrap_display)(yagl_os_display /*os_dpy*/,
+ int /*enable_drm*/);
+};
+
+/*
+ * Attempts to guess the platform based on 'os_dpy'.
+ * Returns NULL if unsuccessful.
+ */
+struct yagl_native_platform *yagl_guess_platform(yagl_os_display os_dpy);
+
+#endif
diff --git a/EGL/yagl_native_types.h b/EGL/yagl_native_types.h
new file mode 100644
index 0000000..54ea0f3
--- /dev/null
+++ b/EGL/yagl_native_types.h
@@ -0,0 +1,18 @@
+#ifndef _YAGL_NATIVE_TYPES_H_
+#define _YAGL_NATIVE_TYPES_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+
+typedef uintptr_t yagl_os_display;
+typedef uintptr_t yagl_os_drawable;
+typedef uintptr_t yagl_os_window;
+typedef uintptr_t yagl_os_pixmap;
+
+typedef enum
+{
+ yagl_native_attachment_front,
+ yagl_native_attachment_back,
+} yagl_native_attachment;
+
+#endif
diff --git a/EGL/yagl_offscreen.c b/EGL/yagl_offscreen.c
index 012297d..27c196a 100644
--- a/EGL/yagl_offscreen.c
+++ b/EGL/yagl_offscreen.c
@@ -4,17 +4,25 @@
#include "yagl_display.h"
#include "yagl_backend.h"
#include "yagl_malloc.h"
+#include "yagl_native_platform.h"
static struct yagl_display
- *yagl_offscreen_create_display(EGLNativeDisplayType display_id,
- Display *x_dpy,
+ *yagl_offscreen_create_display(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
yagl_host_handle host_dpy)
{
struct yagl_display *dpy;
+ struct yagl_native_display *native_dpy;
+
+ native_dpy = platform->wrap_display(os_dpy, 0);
+
+ if (!native_dpy) {
+ return NULL;
+ }
dpy = yagl_malloc0(sizeof(*dpy));
- yagl_display_init(dpy, display_id, x_dpy, host_dpy);
+ yagl_display_init(dpy, os_dpy, native_dpy, host_dpy);
return dpy;
}
@@ -22,11 +30,14 @@ static struct yagl_display
static struct yagl_surface
*yagl_offscreen_create_window_surface(struct yagl_display *dpy,
yagl_host_handle host_config,
- Window x_win,
+ struct yagl_native_drawable *native_window,
const EGLint* attrib_list)
{
struct yagl_offscreen_surface *sfc =
- yagl_offscreen_surface_create_window(dpy, host_config, x_win, attrib_list);
+ yagl_offscreen_surface_create_window(dpy,
+ host_config,
+ native_window,
+ attrib_list);
return sfc ? &sfc->base : NULL;
}
@@ -34,11 +45,14 @@ static struct yagl_surface
static struct yagl_surface
*yagl_offscreen_create_pixmap_surface(struct yagl_display *dpy,
yagl_host_handle host_config,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_offscreen_surface *sfc =
- yagl_offscreen_surface_create_pixmap(dpy, host_config, x_pixmap, attrib_list);
+ yagl_offscreen_surface_create_pixmap(dpy,
+ host_config,
+ native_pixmap,
+ attrib_list);
return sfc ? &sfc->base : NULL;
}
@@ -57,11 +71,14 @@ static struct yagl_surface
static struct yagl_image
*yagl_offscreen_create_image(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_offscreen_image *image =
- yagl_offscreen_image_create(dpy, host_context, x_pixmap, attrib_list);
+ yagl_offscreen_image_create(dpy,
+ host_context,
+ native_pixmap,
+ attrib_list);
return image ? &image->base : NULL;
}
diff --git a/EGL/yagl_offscreen_image.c b/EGL/yagl_offscreen_image.c
index 8cfd7ec..e0505e3 100644
--- a/EGL/yagl_offscreen_image.c
+++ b/EGL/yagl_offscreen_image.c
@@ -5,46 +5,43 @@
#include "yagl_state.h"
#include "yagl_host_egl_calls.h"
#include "yagl_mem_egl.h"
+#include "yagl_native_drawable.h"
+#include "yagl_native_image.h"
#include <string.h>
static void yagl_offscreen_image_update(struct yagl_image *image)
{
struct yagl_offscreen_image *oimage = (struct yagl_offscreen_image*)image;
- XImage *x_image = NULL;
+ struct yagl_native_image *native_image = NULL;
YAGL_LOG_FUNC_SET(yagl_offscreen_image_update);
- x_image = XGetImage(image->dpy->x_dpy,
- image->x_pixmap,
- 0,
- 0,
- oimage->width,
- oimage->height,
- AllPlanes,
- ZPixmap);
-
- if (!x_image) {
- YAGL_LOG_ERROR("XGetImage failed for image %u", image->res.handle);
+ native_image = image->native_pixmap->get_image(image->native_pixmap,
+ oimage->width,
+ oimage->height);
+
+ if (!native_image) {
+ YAGL_LOG_ERROR("get_image failed for image %u", image->res.handle);
return;
}
while (!yagl_host_eglUpdateOffscreenImageYAGL(image->dpy->host_dpy,
image->res.handle,
- oimage->width,
- oimage->height,
- (x_image->bits_per_pixel / 8),
- yagl_batch_put(x_image->data, (oimage->width *
- oimage->height *
- (x_image->bits_per_pixel / 8))))) {}
-
- XDestroyImage(x_image);
+ native_image->width,
+ native_image->height,
+ native_image->bpp,
+ yagl_batch_put(native_image->pixels, (native_image->width *
+ native_image->height *
+ native_image->bpp)))) {}
+
+ native_image->destroy(native_image);
}
static void yagl_offscreen_image_destroy(struct yagl_ref *ref)
{
- struct yagl_offscreen_image *image = (struct yagl_offscreen_image*)ref;
+ struct yagl_image *image = (struct yagl_image*)ref;
- yagl_image_cleanup(&image->base);
+ yagl_image_cleanup(image);
yagl_free(image);
}
@@ -52,15 +49,12 @@ static void yagl_offscreen_image_destroy(struct yagl_ref *ref)
struct yagl_offscreen_image
*yagl_offscreen_image_create(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
- struct yagl_offscreen_image *image;
- unsigned int depth = 0;
- union { Window w; int i; unsigned int ui; } tmp_geom;
yagl_host_handle host_image = 0;
-
- image = yagl_malloc0(sizeof(*image));
+ struct yagl_offscreen_image *image;
+ uint32_t depth;
do {
yagl_mem_probe_read_attrib_list(attrib_list);
@@ -68,37 +62,27 @@ struct yagl_offscreen_image
dpy->host_dpy,
host_context,
EGL_NATIVE_PIXMAP_KHR,
- x_pixmap,
+ 0,
attrib_list));
if (!host_image) {
- goto fail;
+ return NULL;
}
- memset(&tmp_geom, 0, sizeof(tmp_geom));
-
- XGetGeometry(dpy->x_dpy,
- x_pixmap,
- &tmp_geom.w,
- &tmp_geom.i,
- &tmp_geom.i,
- &image->width,
- &image->height,
- &tmp_geom.ui,
- &depth);
+ image = yagl_malloc0(sizeof(*image));
yagl_image_init(&image->base,
&yagl_offscreen_image_destroy,
host_image,
dpy,
- x_pixmap);
+ native_pixmap);
image->base.update = &yagl_offscreen_image_update;
- return image;
+ native_pixmap->get_geometry(native_pixmap,
+ &image->width,
+ &image->height,
+ &depth);
-fail:
- yagl_free(image);
-
- return NULL;
+ return image;
}
diff --git a/EGL/yagl_offscreen_image.h b/EGL/yagl_offscreen_image.h
index 6c01193..7dab5d6 100644
--- a/EGL/yagl_offscreen_image.h
+++ b/EGL/yagl_offscreen_image.h
@@ -16,7 +16,7 @@ struct yagl_offscreen_image
struct yagl_offscreen_image
*yagl_offscreen_image_create(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list);
#endif
diff --git a/EGL/yagl_offscreen_surface.c b/EGL/yagl_offscreen_surface.c
index 6e90a5e..f1c348a 100644
--- a/EGL/yagl_offscreen_surface.c
+++ b/EGL/yagl_offscreen_surface.c
@@ -1,25 +1,67 @@
#include "yagl_offscreen_surface.h"
#include "yagl_host_egl_calls.h"
#include "yagl_egl_state.h"
-#include "yagl_bimage.h"
#include "yagl_malloc.h"
#include "yagl_log.h"
#include "yagl_display.h"
#include "yagl_mem_egl.h"
+#include "yagl_native_display.h"
+#include "yagl_native_drawable.h"
+#include "yagl_native_image.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+static struct yagl_native_image
+ *yagl_offscreen_surface_create_bi(struct yagl_native_display *dpy,
+ uint32_t width,
+ uint32_t height,
+ uint32_t depth)
+{
+ struct yagl_native_image *bi = dpy->create_image(dpy,
+ width,
+ height,
+ depth);
+
+ if (!bi) {
+ return NULL;
+ }
+
+ if (mlock(bi->pixels, bi->width * bi->height * bi->bpp) == -1) {
+ fprintf(stderr, "Critical error! Unable to lock YaGL bi memory: %s!\n", strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Probe in immediately.
+ */
+
+ yagl_mem_probe_write(bi->pixels, bi->width * bi->height * bi->bpp);
+
+ return bi;
+}
+
+static void yagl_offscreen_surface_destroy_bi(struct yagl_native_image *bi)
+{
+ if (munlock(bi->pixels, bi->width * bi->height * bi->bpp) == -1) {
+ fprintf(stderr, "Critical error! Unable to unlock YaGL bi memory: %s!\n", strerror(errno));
+ exit(1);
+ }
+
+ bi->destroy(bi);
+}
static int yagl_offscreen_surface_resize(struct yagl_offscreen_surface *surface)
{
int res = 0;
EGLBoolean retval = EGL_FALSE;
- unsigned int width = 0;
- unsigned int height = 0;
- unsigned int depth = 0;
- union { Window w; int i; unsigned int ui; } tmp_geom;
- struct yagl_bimage *bi = NULL;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t depth = 0;
+ struct yagl_native_image *bi = NULL;
YAGL_LOG_FUNC_SET(yagl_offscreen_surface_resize);
@@ -27,17 +69,10 @@ static int yagl_offscreen_surface_resize(struct yagl_offscreen_surface *surface)
return 1;
}
- memset(&tmp_geom, 0, sizeof(tmp_geom));
-
- XGetGeometry(surface->base.dpy->x_dpy,
- surface->base.x_drawable.win,
- &tmp_geom.w,
- &tmp_geom.i,
- &tmp_geom.i,
- &width,
- &height,
- &tmp_geom.ui,
- &depth);
+ surface->base.native_drawable->get_geometry(surface->base.native_drawable,
+ &width,
+ &height,
+ &depth);
if ((width != surface->bi->width) ||
(height != surface->bi->height) ||
@@ -50,17 +85,17 @@ static int yagl_offscreen_surface_resize(struct yagl_offscreen_surface *surface)
* First of all, create new backing image.
*/
- bi = yagl_bimage_create(surface->base.dpy, width, height, depth);
+ bi = yagl_offscreen_surface_create_bi(surface->base.dpy->native_dpy,
+ width, height, depth);
if (!bi) {
- YAGL_LOG_ERROR("yagl_bimage_create failed");
+ YAGL_LOG_ERROR("create_bi failed");
yagl_set_error(EGL_BAD_ALLOC);
goto out;
}
/*
* Tell the host that it should use new backing image from now on.
- * No need to probe in 'bi->pixels', it's already 'mlock'ed.
*/
YAGL_HOST_CALL_ASSERT(yagl_host_eglResizeOffscreenSurfaceYAGL(&retval,
@@ -82,7 +117,7 @@ static int yagl_offscreen_surface_resize(struct yagl_offscreen_surface *surface)
* we can safely replace surface's backing image with a new one.
*/
- yagl_bimage_destroy(surface->bi);
+ yagl_offscreen_surface_destroy_bi(surface->bi);
surface->bi = bi;
bi = NULL;
}
@@ -91,7 +126,7 @@ static int yagl_offscreen_surface_resize(struct yagl_offscreen_surface *surface)
out:
if (bi) {
- yagl_bimage_destroy(bi);
+ yagl_offscreen_surface_destroy_bi(bi);
}
return res;
@@ -129,37 +164,28 @@ static int yagl_offscreen_surface_swap_buffers(struct yagl_surface *sfc)
* Host has updated our image, update the window.
*/
- yagl_bimage_draw(osfc->bi, sfc->x_drawable.win, osfc->x_gc);
+ osfc->bi->draw(osfc->bi, sfc->native_drawable);
return 1;
}
static int yagl_offscreen_surface_copy_buffers(struct yagl_surface *sfc,
- Pixmap target)
+ yagl_os_pixmap target)
{
struct yagl_offscreen_surface *osfc = (struct yagl_offscreen_surface*)sfc;
EGLBoolean retval = EGL_FALSE;
- GC x_gc;
YAGL_LOG_FUNC_SET(eglCopyBuffers);
if (sfc->type == EGL_WINDOW_BIT) {
- unsigned int width = 0;
- unsigned int height = 0;
- unsigned int depth = 0;
- union { Window w; int i; unsigned int ui; } tmp_geom;
-
- memset(&tmp_geom, 0, sizeof(tmp_geom));
-
- XGetGeometry(sfc->dpy->x_dpy,
- sfc->x_drawable.win,
- &tmp_geom.w,
- &tmp_geom.i,
- &tmp_geom.i,
- &width,
- &height,
- &tmp_geom.ui,
- &depth);
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t depth = 0;
+
+ sfc->native_drawable->get_geometry(sfc->native_drawable,
+ &width,
+ &height,
+ &depth);
if ((width != osfc->bi->width) ||
(height != osfc->bi->height) ||
@@ -186,20 +212,12 @@ static int yagl_offscreen_surface_copy_buffers(struct yagl_surface *sfc,
}
/*
- * Host has updated our image, update the surface.
+ * Host has updated our image, update the target.
*/
- x_gc = XCreateGC(sfc->dpy->x_dpy, target, 0, NULL);
+ osfc->bi->draw_to_pixmap(osfc->bi, target);
- if (x_gc) {
- yagl_bimage_draw(osfc->bi, target, x_gc);
- XFreeGC(sfc->dpy->x_dpy, x_gc);
- } else {
- YAGL_LOG_ERROR("XCreateGC failed");
- yagl_set_error(EGL_BAD_ALLOC);
- }
-
- return x_gc ? 1 : 0;
+ return 1;
}
static void yagl_offscreen_surface_wait_x(struct yagl_surface *sfc)
@@ -244,10 +262,8 @@ static void yagl_offscreen_surface_unmap(struct yagl_surface *sfc)
case EGL_PBUFFER_BIT:
break;
case EGL_WINDOW_BIT:
- yagl_bimage_draw(osfc->bi, sfc->x_drawable.win, osfc->x_gc);
- break;
case EGL_PIXMAP_BIT:
- yagl_bimage_draw(osfc->bi, sfc->x_drawable.pixmap, osfc->x_gc);
+ osfc->bi->draw(osfc->bi, sfc->native_drawable);
break;
default:
assert(0);
@@ -264,12 +280,7 @@ static void yagl_offscreen_surface_destroy(struct yagl_ref *ref)
{
struct yagl_offscreen_surface *sfc = (struct yagl_offscreen_surface*)ref;
- if (sfc->x_gc) {
- XFreeGC(sfc->base.dpy->x_dpy, sfc->x_gc);
- sfc->x_gc = 0;
- }
-
- yagl_bimage_destroy(sfc->bi);
+ yagl_offscreen_surface_destroy_bi(sfc->bi);
sfc->bi = NULL;
yagl_surface_cleanup(&sfc->base);
@@ -280,37 +291,29 @@ static void yagl_offscreen_surface_destroy(struct yagl_ref *ref)
struct yagl_offscreen_surface
*yagl_offscreen_surface_create_window(struct yagl_display *dpy,
yagl_host_handle host_config,
- Window x_win,
+ struct yagl_native_drawable *native_window,
const EGLint* attrib_list)
{
struct yagl_offscreen_surface *sfc;
- XWindowAttributes x_wa;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t depth = 0;
yagl_host_handle host_surface = 0;
- struct yagl_bimage *bi = NULL;
- GC x_gc = NULL;
+ struct yagl_native_image *bi = NULL;
YAGL_LOG_FUNC_SET(eglCreateWindowSurface);
sfc = yagl_malloc0(sizeof(*sfc));
- if (!XGetWindowAttributes(dpy->x_dpy, x_win, &x_wa)) {
- YAGL_LOG_ERROR("XGetWindowAttributes failed");
- yagl_set_error(EGL_BAD_NATIVE_WINDOW);
- goto fail;
- }
+ native_window->get_geometry(native_window,
+ &width,
+ &height,
+ &depth);
- bi = yagl_bimage_create(dpy, x_wa.width, x_wa.height, x_wa.depth);
+ bi = yagl_offscreen_surface_create_bi(dpy->native_dpy, width, height, depth);
if (!bi) {
- YAGL_LOG_ERROR("yagl_bimage_create failed");
- yagl_set_error(EGL_BAD_ALLOC);
- goto fail;
- }
-
- x_gc = XCreateGC(dpy->x_dpy, x_win, 0, NULL);
-
- if (!x_gc) {
- YAGL_LOG_ERROR("XCreateGC failed");
+ YAGL_LOG_ERROR("create_bi failed");
yagl_set_error(EGL_BAD_ALLOC);
goto fail;
}
@@ -334,7 +337,7 @@ struct yagl_offscreen_surface
&yagl_offscreen_surface_destroy,
host_surface,
dpy,
- x_win);
+ native_window);
sfc->base.invalidate = &yagl_offscreen_surface_invalidate;
sfc->base.finish = &yagl_offscreen_surface_finish;
@@ -347,17 +350,15 @@ struct yagl_offscreen_surface
sfc->base.set_swap_interval = &yagl_offscreen_surface_set_swap_interval;
sfc->bi = bi;
- sfc->x_gc = x_gc;
return sfc;
fail:
if (bi) {
- yagl_bimage_destroy(bi);
- }
- if (x_gc) {
- XFreeGC(dpy->x_dpy, x_gc);
+ yagl_offscreen_surface_destroy_bi(bi);
+ bi = NULL;
}
+
yagl_free(sfc);
return NULL;
@@ -366,46 +367,29 @@ fail:
struct yagl_offscreen_surface
*yagl_offscreen_surface_create_pixmap(struct yagl_display *dpy,
yagl_host_handle host_config,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_offscreen_surface *sfc;
- unsigned int width = 0;
- unsigned int height = 0;
- unsigned int depth = 0;
- union { Window w; int i; unsigned int ui; } tmp_geom;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t depth = 0;
yagl_host_handle host_surface = 0;
- struct yagl_bimage *bi = NULL;
- GC x_gc = NULL;
+ struct yagl_native_image *bi = NULL;
YAGL_LOG_FUNC_SET(eglCreatePixmapSurface);
sfc = yagl_malloc0(sizeof(*sfc));
- memset(&tmp_geom, 0, sizeof(tmp_geom));
+ native_pixmap->get_geometry(native_pixmap,
+ &width,
+ &height,
+ &depth);
- XGetGeometry(dpy->x_dpy,
- x_pixmap,
- &tmp_geom.w,
- &tmp_geom.i,
- &tmp_geom.i,
- &width,
- &height,
- &tmp_geom.ui,
- &depth);
-
- bi = yagl_bimage_create(dpy, width, height, depth);
+ bi = yagl_offscreen_surface_create_bi(dpy->native_dpy, width, height, depth);
if (!bi) {
- YAGL_LOG_ERROR("yagl_bimage_create failed");
- yagl_set_error(EGL_BAD_ALLOC);
- goto fail;
- }
-
- x_gc = XCreateGC(dpy->x_dpy, x_pixmap, 0, NULL);
-
- if (!x_gc) {
- YAGL_LOG_ERROR("XCreateGC failed");
+ YAGL_LOG_ERROR("create_bi failed");
yagl_set_error(EGL_BAD_ALLOC);
goto fail;
}
@@ -429,7 +413,7 @@ struct yagl_offscreen_surface
&yagl_offscreen_surface_destroy,
host_surface,
dpy,
- x_pixmap);
+ native_pixmap);
sfc->base.invalidate = &yagl_offscreen_surface_invalidate;
sfc->base.finish = &yagl_offscreen_surface_finish;
@@ -442,17 +426,15 @@ struct yagl_offscreen_surface
sfc->base.set_swap_interval = &yagl_offscreen_surface_set_swap_interval;
sfc->bi = bi;
- sfc->x_gc = x_gc;
return sfc;
fail:
if (bi) {
- yagl_bimage_destroy(bi);
- }
- if (x_gc) {
- XFreeGC(dpy->x_dpy, x_gc);
+ yagl_offscreen_surface_destroy_bi(bi);
+ bi = NULL;
}
+
yagl_free(sfc);
return NULL;
@@ -467,7 +449,7 @@ struct yagl_offscreen_surface
uint32_t width = 0;
uint32_t height = 0;
yagl_host_handle host_surface = 0;
- struct yagl_bimage *bi = NULL;
+ struct yagl_native_image *bi = NULL;
int i = 0;
YAGL_LOG_FUNC_SET(eglCreatePbufferSurface);
@@ -491,10 +473,10 @@ struct yagl_offscreen_surface
}
}
- bi = yagl_bimage_create(dpy, width, height, 24);
+ bi = yagl_offscreen_surface_create_bi(dpy->native_dpy, width, height, 24);
if (!bi) {
- YAGL_LOG_ERROR("yagl_bimage_create failed");
+ YAGL_LOG_ERROR("create_bi failed");
yagl_set_error(EGL_BAD_ALLOC);
goto fail;
}
@@ -535,8 +517,10 @@ struct yagl_offscreen_surface
fail:
if (bi) {
- yagl_bimage_destroy(bi);
+ yagl_offscreen_surface_destroy_bi(bi);
+ bi = NULL;
}
+
yagl_free(sfc);
return NULL;
diff --git a/EGL/yagl_offscreen_surface.h b/EGL/yagl_offscreen_surface.h
index df29e89..035022c 100644
--- a/EGL/yagl_offscreen_surface.h
+++ b/EGL/yagl_offscreen_surface.h
@@ -5,27 +5,26 @@
#include "yagl_types.h"
#include "yagl_surface.h"
-struct yagl_bimage;
+struct yagl_native_image;
+struct yagl_native_drawable;
struct yagl_offscreen_surface
{
struct yagl_surface base;
- struct yagl_bimage *bi;
-
- GC x_gc;
+ struct yagl_native_image *bi;
};
struct yagl_offscreen_surface
*yagl_offscreen_surface_create_window(struct yagl_display *dpy,
yagl_host_handle host_config,
- Window x_win,
+ struct yagl_native_drawable *native_window,
const EGLint* attrib_list);
struct yagl_offscreen_surface
*yagl_offscreen_surface_create_pixmap(struct yagl_display *dpy,
yagl_host_handle host_config,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list);
struct yagl_offscreen_surface
diff --git a/EGL/yagl_onscreen.c b/EGL/yagl_onscreen.c
index 18d67f9..edcd5ef 100644
--- a/EGL/yagl_onscreen.c
+++ b/EGL/yagl_onscreen.c
@@ -4,46 +4,67 @@
#include "yagl_onscreen_image.h"
#include "yagl_backend.h"
#include "yagl_malloc.h"
+#include "yagl_native_platform.h"
+#include "yagl_native_display.h"
static struct yagl_display
- *yagl_onscreen_create_display(EGLNativeDisplayType display_id,
- Display *x_dpy,
+ *yagl_onscreen_create_display(struct yagl_native_platform *platform,
+ yagl_os_display os_dpy,
yagl_host_handle host_dpy)
{
- struct yagl_onscreen_display *dpy =
- yagl_onscreen_display_create(display_id, x_dpy, host_dpy);
+ struct yagl_native_display *native_dpy;
+ struct yagl_onscreen_display *dpy;
- return dpy ? &dpy->base : NULL;
+ native_dpy = platform->wrap_display(os_dpy, 1);
+
+ if (!native_dpy) {
+ return NULL;
+ }
+
+ dpy = yagl_onscreen_display_create(os_dpy, native_dpy, host_dpy);
+
+ if (dpy) {
+ return &dpy->base;
+ } else {
+ native_dpy->destroy(native_dpy);
+ return NULL;
+ }
}
static struct yagl_surface
*yagl_onscreen_create_window_surface(struct yagl_display *dpy,
- yagl_host_handle host_config,
- Window x_win,
- const EGLint* attrib_list)
+ yagl_host_handle host_config,
+ struct yagl_native_drawable *native_window,
+ const EGLint *attrib_list)
{
struct yagl_onscreen_surface *sfc =
- yagl_onscreen_surface_create_window(dpy, host_config, x_win, attrib_list);
+ yagl_onscreen_surface_create_window(dpy,
+ host_config,
+ native_window,
+ attrib_list);
return sfc ? &sfc->base : NULL;
}
static struct yagl_surface
*yagl_onscreen_create_pixmap_surface(struct yagl_display *dpy,
- yagl_host_handle host_config,
- Pixmap x_pixmap,
- const EGLint* attrib_list)
+ yagl_host_handle host_config,
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint *attrib_list)
{
struct yagl_onscreen_surface *sfc =
- yagl_onscreen_surface_create_pixmap(dpy, host_config, x_pixmap, attrib_list);
+ yagl_onscreen_surface_create_pixmap(dpy,
+ host_config,
+ native_pixmap,
+ attrib_list);
return sfc ? &sfc->base : NULL;
}
static struct yagl_surface
*yagl_onscreen_create_pbuffer_surface(struct yagl_display *dpy,
- yagl_host_handle host_config,
- const EGLint* attrib_list)
+ yagl_host_handle host_config,
+ const EGLint *attrib_list)
{
struct yagl_onscreen_surface *sfc =
yagl_onscreen_surface_create_pbuffer(dpy, host_config, attrib_list);
@@ -54,11 +75,14 @@ static struct yagl_surface
static struct yagl_image
*yagl_onscreen_create_image(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_onscreen_image *image =
- yagl_onscreen_image_create(dpy, host_context, x_pixmap, attrib_list);
+ yagl_onscreen_image_create(dpy,
+ host_context,
+ native_pixmap,
+ attrib_list);
return image ? &image->base : NULL;
}
diff --git a/EGL/yagl_onscreen_buffer.c b/EGL/yagl_onscreen_buffer.c
new file mode 100644
index 0000000..381a106
--- /dev/null
+++ b/EGL/yagl_onscreen_buffer.c
@@ -0,0 +1,64 @@
+#include "yagl_onscreen_buffer.h"
+#include "yagl_onscreen_display.h"
+#include "yagl_native_display.h"
+#include "yagl_native_drawable.h"
+#include "yagl_log.h"
+#include "yagl_malloc.h"
+#include "vigs.h"
+#include <string.h>
+
+struct yagl_onscreen_buffer
+ *yagl_onscreen_buffer_create(struct yagl_onscreen_display *dpy,
+ struct yagl_native_drawable *native_drawable,
+ yagl_native_attachment attachment,
+ uint32_t check_name)
+{
+ int ret;
+ uint32_t name;
+ struct vigs_drm_surface *drm_sfc;
+ struct yagl_onscreen_buffer *buffer;
+
+ YAGL_LOG_FUNC_ENTER(yagl_onscreen_buffer_create,
+ "dpy = %p, d = %p, attachment = %u, check_name = %u",
+ native_drawable->dpy->os_dpy,
+ native_drawable->os_drawable,
+ attachment,
+ check_name);
+
+ name = native_drawable->get_buffer(native_drawable, attachment);
+
+ if (!name) {
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return NULL;
+ }
+
+ if (name == check_name) {
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return NULL;
+ }
+
+ ret = vigs_drm_surface_open(dpy->drm_dev, name, &drm_sfc);
+
+ if (ret != 0) {
+ YAGL_LOG_ERROR("vigs_drm_surface_open failed for drawable %p: %s",
+ native_drawable->os_drawable,
+ strerror(-ret));
+ YAGL_LOG_FUNC_EXIT(NULL);
+ return NULL;
+ }
+
+ buffer = yagl_malloc0(sizeof(*buffer));
+
+ buffer->name = name;
+ buffer->drm_sfc = drm_sfc;
+
+ YAGL_LOG_FUNC_EXIT(NULL);
+
+ return buffer;
+}
+
+void yagl_onscreen_buffer_destroy(struct yagl_onscreen_buffer *buffer)
+{
+ vigs_drm_gem_unref(&buffer->drm_sfc->gem);
+ yagl_free(buffer);
+}
diff --git a/EGL/yagl_onscreen_buffer.h b/EGL/yagl_onscreen_buffer.h
new file mode 100644
index 0000000..4873eec
--- /dev/null
+++ b/EGL/yagl_onscreen_buffer.h
@@ -0,0 +1,27 @@
+#ifndef _YAGL_ONSCREEN_BUFFER_H_
+#define _YAGL_ONSCREEN_BUFFER_H_
+
+#include "yagl_export.h"
+#include "yagl_types.h"
+#include "yagl_native_types.h"
+
+struct vigs_drm_surface;
+struct yagl_onscreen_display;
+struct yagl_native_drawable;
+
+struct yagl_onscreen_buffer
+{
+ uint32_t name;
+
+ struct vigs_drm_surface *drm_sfc;
+};
+
+struct yagl_onscreen_buffer
+ *yagl_onscreen_buffer_create(struct yagl_onscreen_display *dpy,
+ struct yagl_native_drawable *native_drawable,
+ yagl_native_attachment attachment,
+ uint32_t check_name);
+
+void yagl_onscreen_buffer_destroy(struct yagl_onscreen_buffer *buffer);
+
+#endif
diff --git a/EGL/yagl_onscreen_display.c b/EGL/yagl_onscreen_display.c
index 80677c4..4179b91 100644
--- a/EGL/yagl_onscreen_display.c
+++ b/EGL/yagl_onscreen_display.c
@@ -1,182 +1,32 @@
#include "yagl_onscreen_display.h"
-#include "yagl_log.h"
#include "yagl_malloc.h"
-#include <sys/fcntl.h>
+#include "yagl_native_display.h"
+#include "vigs.h"
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
struct yagl_onscreen_display
- *yagl_onscreen_display_create(EGLNativeDisplayType display_id,
- Display *x_dpy,
+ *yagl_onscreen_display_create(yagl_os_display display_id,
+ struct yagl_native_display *native_dpy,
yagl_host_handle host_dpy)
{
- struct yagl_onscreen_display *tmp_dpy;
- struct yagl_onscreen_display *dpy = NULL;
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;
struct vigs_drm_device *drm_dev = NULL;
+ struct yagl_onscreen_display *dpy = NULL;
- YAGL_LOG_FUNC_SET(eglGetDisplay);
-
- tmp_dpy = yagl_malloc0(sizeof(*dpy));
-
- yagl_display_init(&tmp_dpy->base, display_id, x_dpy, host_dpy);
-
- if (!yagl_DRI2QueryExtension(x_dpy, &event_base, &error_base)) {
- fprintf(stderr, "Critical error! Failed to DRI2QueryExtension on YaGL display, DRI2 not enabled ?\n");
- goto out;
- }
-
- YAGL_LOG_TRACE("DRI2QueryExtension returned %d %d",
- event_base, error_base);
-
- if (!yagl_DRI2QueryVersion(x_dpy, &dri_major, &dri_minor)) {
- fprintf(stderr, "Critical error! Failed to DRI2QueryVersion on YaGL display, DRI2 not enabled ?\n");
- goto out;
- }
-
- YAGL_LOG_TRACE("DRI2QueryVersion returned %d %d",
- dri_major, dri_minor);
-
- if (!yagl_DRI2Connect(x_dpy,
- RootWindow(x_dpy, DefaultScreen(x_dpy)),
- &dri_driver,
- &dri_device)) {
- fprintf(stderr, "Critical error! Failed to DRI2Connect on YaGL display, DRI2 not enabled ?\n");
- goto out;
- }
-
- YAGL_LOG_TRACE("DRI2Connect returned %s %s",
- dri_driver, dri_device);
-
- 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));
- goto fail;
- }
-
- memset(&magic, 0, sizeof(magic));
-
- ret = drmGetMagic(drm_fd, &magic);
-
- if (ret != 0) {
- fprintf(stderr, "Critical error! drmGetMagic failed: %s\n", strerror(-ret));
- 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");
- goto fail;
- }
-
- ret = vigs_drm_device_create(drm_fd, &drm_dev);
+ ret = vigs_drm_device_create(native_dpy->drm_fd, &drm_dev);
if (ret != 0) {
fprintf(stderr, "Critical error! vigs_drm_device_create failed: %s\n", strerror(-ret));
- goto fail;
- }
-
- tmp_dpy->drm_fd = drm_fd;
- tmp_dpy->drm_dev = drm_dev;
-
- dpy = tmp_dpy;
- tmp_dpy = NULL;
-
- goto out;
-
-fail:
- if (drm_dev) {
- vigs_drm_device_destroy(drm_dev);
- }
- if (drm_fd >= 0) {
- close(drm_fd);
- }
-out:
- if (dri_driver) {
- Xfree(dri_driver);
- }
- if (dri_device) {
- Xfree(dri_device);
- }
- if (tmp_dpy) {
- yagl_display_cleanup(&tmp_dpy->base);
- yagl_free(tmp_dpy);
- }
-
- return dpy;
-}
-
-struct yagl_onscreen_buffer
- *yagl_onscreen_display_create_buffer(struct yagl_onscreen_display* dpy,
- Drawable d,
- unsigned int attachment,
- uint32_t check_name)
-{
- int ret;
- unsigned int attachments[1] =
- {
- attachment
- };
- yagl_DRI2Buffer *tmp_buffer;
- int tmp_width, tmp_height, num_buffers;
- struct vigs_drm_surface *drm_sfc;
- struct yagl_onscreen_buffer *buffer;
-
- YAGL_LOG_FUNC_ENTER(yagl_onscreen_display_create_buffer,
- "dpy = %p, d = 0x%X, attachment = %u",
- dpy,
- d,
- attachment);
-
- tmp_buffer = yagl_DRI2GetBuffers(dpy->base.x_dpy, d,
- &tmp_width, &tmp_height,
- &attachments[0],
- sizeof(attachments)/sizeof(attachments[0]),
- &num_buffers);
- if (!tmp_buffer) {
- YAGL_LOG_ERROR("DRI2GetBuffers failed for drawable 0x%X", d);
- YAGL_LOG_FUNC_EXIT(NULL);
- return NULL;
- }
-
- if (tmp_buffer->name == check_name) {
- Xfree(tmp_buffer);
- YAGL_LOG_FUNC_EXIT(NULL);
return NULL;
}
- ret = vigs_drm_surface_open(dpy->drm_dev, tmp_buffer->name, &drm_sfc);
+ dpy = yagl_malloc0(sizeof(*dpy));
- if (ret != 0) {
- YAGL_LOG_ERROR("vigs_drm_surface_open failed for drawable 0x%X: %s",
- d,
- strerror(-ret));
- Xfree(tmp_buffer);
- YAGL_LOG_FUNC_EXIT(NULL);
- return NULL;
- }
+ yagl_display_init(&dpy->base, display_id, native_dpy, host_dpy);
- buffer = yagl_malloc0(sizeof(*buffer));
+ dpy->drm_dev = drm_dev;
- buffer->dri2_buffer = tmp_buffer;
- buffer->drm_sfc = drm_sfc;
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return buffer;
-}
-
-void yagl_onscreen_display_destroy_buffer(struct yagl_onscreen_buffer *buffer)
-{
- Xfree(buffer->dri2_buffer);
- vigs_drm_gem_unref(&buffer->drm_sfc->gem);
- yagl_free(buffer);
+ return dpy;
}
diff --git a/EGL/yagl_onscreen_display.h b/EGL/yagl_onscreen_display.h
index f58046e..1ed4205 100644
--- a/EGL/yagl_onscreen_display.h
+++ b/EGL/yagl_onscreen_display.h
@@ -4,35 +4,19 @@
#include "yagl_export.h"
#include "yagl_types.h"
#include "yagl_display.h"
-#include "yagl_dri2.h"
-#include "vigs.h"
+
+struct vigs_drm_device;
struct yagl_onscreen_display
{
struct yagl_display base;
- int drm_fd;
struct vigs_drm_device *drm_dev;
};
-struct yagl_onscreen_buffer
-{
- yagl_DRI2Buffer *dri2_buffer;
-
- struct vigs_drm_surface *drm_sfc;
-};
-
struct yagl_onscreen_display
- *yagl_onscreen_display_create(EGLNativeDisplayType display_id,
- Display *x_dpy,
+ *yagl_onscreen_display_create(yagl_os_display display_id,
+ struct yagl_native_display *native_dpy,
yagl_host_handle host_dpy);
-struct yagl_onscreen_buffer
- *yagl_onscreen_display_create_buffer(struct yagl_onscreen_display* dpy,
- Drawable d,
- unsigned int attachment,
- uint32_t check_name);
-
-void yagl_onscreen_display_destroy_buffer(struct yagl_onscreen_buffer *buffer);
-
#endif
diff --git a/EGL/yagl_onscreen_image.c b/EGL/yagl_onscreen_image.c
index 616390f..43aa1cb 100644
--- a/EGL/yagl_onscreen_image.c
+++ b/EGL/yagl_onscreen_image.c
@@ -1,10 +1,13 @@
#include "yagl_onscreen_image.h"
+#include "yagl_onscreen_buffer.h"
+#include "yagl_onscreen_display.h"
#include "yagl_display.h"
#include "yagl_log.h"
#include "yagl_malloc.h"
#include "yagl_host_egl_calls.h"
#include "yagl_mem_egl.h"
#include "yagl_egl_state.h"
+#include "vigs.h"
static void yagl_onscreen_image_update(struct yagl_image *image)
{
@@ -14,10 +17,7 @@ static void yagl_onscreen_image_destroy(struct yagl_ref *ref)
{
struct yagl_onscreen_image *image = (struct yagl_onscreen_image*)ref;
- yagl_onscreen_display_destroy_buffer(image->buffer);
-
- yagl_DRI2DestroyDrawable(image->base.dpy->x_dpy,
- image->base.x_pixmap);
+ yagl_onscreen_buffer_destroy(image->buffer);
yagl_image_cleanup(&image->base);
@@ -27,7 +27,7 @@ static void yagl_onscreen_image_destroy(struct yagl_ref *ref)
struct yagl_onscreen_image
*yagl_onscreen_image_create(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_onscreen_display *odpy = (struct yagl_onscreen_display*)dpy;
@@ -37,12 +37,10 @@ struct yagl_onscreen_image
image = yagl_malloc0(sizeof(*image));
- yagl_DRI2CreateDrawable(dpy->x_dpy, x_pixmap);
-
- new_buffer = yagl_onscreen_display_create_buffer(odpy,
- x_pixmap,
- DRI2BufferFrontLeft,
- 0);
+ new_buffer = yagl_onscreen_buffer_create(odpy,
+ native_pixmap,
+ yagl_native_attachment_front,
+ 0);
if (!new_buffer) {
yagl_set_error(EGL_BAD_NATIVE_PIXMAP);
@@ -66,7 +64,7 @@ struct yagl_onscreen_image
&yagl_onscreen_image_destroy,
host_image,
dpy,
- x_pixmap);
+ native_pixmap);
image->base.update = &yagl_onscreen_image_update;
@@ -76,8 +74,7 @@ struct yagl_onscreen_image
fail:
if (new_buffer) {
- yagl_onscreen_display_destroy_buffer(new_buffer);
- yagl_DRI2DestroyDrawable(dpy->x_dpy, x_pixmap);
+ yagl_onscreen_buffer_destroy(new_buffer);
}
yagl_free(image);
diff --git a/EGL/yagl_onscreen_image.h b/EGL/yagl_onscreen_image.h
index bcee944..8b597fa 100644
--- a/EGL/yagl_onscreen_image.h
+++ b/EGL/yagl_onscreen_image.h
@@ -4,8 +4,9 @@
#include "yagl_export.h"
#include "yagl_types.h"
#include "yagl_image.h"
-#include "yagl_dri2.h"
-#include "yagl_onscreen_display.h"
+
+struct yagl_onscreen_buffer;
+struct yagl_native_drawable;
struct yagl_onscreen_image
{
@@ -17,7 +18,7 @@ struct yagl_onscreen_image
struct yagl_onscreen_image
*yagl_onscreen_image_create(struct yagl_display *dpy,
yagl_host_handle host_context,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list);
#endif
diff --git a/EGL/yagl_onscreen_surface.c b/EGL/yagl_onscreen_surface.c
index fdc03b8..bf78ac1 100644
--- a/EGL/yagl_onscreen_surface.c
+++ b/EGL/yagl_onscreen_surface.c
@@ -1,70 +1,19 @@
#include "yagl_onscreen_surface.h"
+#include "yagl_onscreen_buffer.h"
+#include "yagl_onscreen_display.h"
#include "yagl_host_egl_calls.h"
#include "yagl_egl_state.h"
#include "yagl_log.h"
#include "yagl_mem_egl.h"
#include "yagl_utils.h"
#include "yagl_malloc.h"
+#include "yagl_native_display.h"
+#include "yagl_native_drawable.h"
+#include "vigs.h"
#include <assert.h>
#include <stdio.h>
-
-/*
- * When this is defined EGL pixmap surface will behave more like pbuffer
- * surface, i.e. it'll allocate additional pixmap and all OpenGL rendering
- * will go there. eglCopyBuffers will be the only way to get the rendering
- * results.
- *
- * This is a temporary workaround for Tizen, because it currently
- * behaves like if pixmap surfaces were pbuffer surfaces.
- *
- * One of the examples is WebKit, it renders WebGL like this:
- * + sfc = eglCreatePixmapSurface(... pixmap_id ...)
- * + eglMakeCurrent(... sfc ...);
- * + (render step)
- * + async: XGetImage(pixmap_id)
- * + eglCopyBuffers(... pixmap_id ...)
- *
- * I.e. it makes asynchronous calls to XGetImage for the pixmap which is
- * being rendered to. It doesn't call eglWaitX/glFlush/glFinish, thus, it
- * assumes that the image stored in 'pixmap_id' is complete and won't have any
- * intermediate rendering results and this is only possible if this pixmap
- * surface is a pbuffer surface. A eglCopyBuffers call at the end copies
- * the rendering results to the pixmap itself, which is really stupid thing
- * to do... unless this is a pbuffer surface...
- */
-//#define YAGL_FAKE_PIXMAP_SURFACE
-
-static void yagl_onscreen_surface_copy_drawable(struct yagl_onscreen_surface *sfc,
- int src, int dest)
-{
- XRectangle xrect;
- XserverRegion region;
-
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = sfc->buffer->drm_sfc->width;
- xrect.height = sfc->buffer->drm_sfc->height;
-
- region = XFixesCreateRegion(sfc->base.dpy->x_dpy, &xrect, 1);
- switch (sfc->base.type) {
- case EGL_PBUFFER_BIT:
- yagl_DRI2CopyRegion(sfc->base.dpy->x_dpy, sfc->tmp_pixmap,
- region, dest, src);
- break;
- case EGL_PIXMAP_BIT:
- yagl_DRI2CopyRegion(sfc->base.dpy->x_dpy, sfc->base.x_drawable.pixmap,
- region, dest, src);
- break;
- case EGL_WINDOW_BIT:
- yagl_DRI2CopyRegion(sfc->base.dpy->x_dpy, sfc->base.x_drawable.win,
- region, dest, src);
- break;
- default:
- assert(0);
- break;
- }
- XFixesDestroyRegion(sfc->base.dpy->x_dpy, region);
-}
+#include <stdlib.h>
+#include <string.h>
static void yagl_onscreen_surface_invalidate(struct yagl_surface *sfc)
{
@@ -72,28 +21,28 @@ static void yagl_onscreen_surface_invalidate(struct yagl_surface *sfc)
struct yagl_onscreen_display *dpy = (struct yagl_onscreen_display*)sfc->dpy;
struct yagl_onscreen_buffer *new_buffer;
- if (osfc->last_stamp == osfc->stamp) {
+ if (osfc->last_stamp == sfc->native_drawable->stamp) {
return;
}
assert(sfc->type == EGL_WINDOW_BIT);
- osfc->last_stamp = osfc->stamp;
+ osfc->last_stamp = sfc->native_drawable->stamp;
/*
* We only process new buffer if it's different from
* the current one.
*/
- new_buffer = yagl_onscreen_display_create_buffer(dpy,
- sfc->x_drawable.win,
- DRI2BufferBackLeft,
- osfc->buffer->dri2_buffer->name);
+ new_buffer = yagl_onscreen_buffer_create(dpy,
+ sfc->native_drawable,
+ yagl_native_attachment_back,
+ osfc->buffer->name);
if (!new_buffer) {
return;
}
- yagl_onscreen_display_destroy_buffer(osfc->buffer);
+ yagl_onscreen_buffer_destroy(osfc->buffer);
osfc->buffer = new_buffer;
YAGL_HOST_CALL_ASSERT(yagl_host_eglInvalidateOnscreenSurfaceYAGL(
@@ -118,7 +67,6 @@ static void yagl_onscreen_surface_finish(struct yagl_surface *sfc)
static int yagl_onscreen_surface_swap_buffers(struct yagl_surface *sfc)
{
EGLBoolean retval = EGL_FALSE;
- CARD64 count = 0;
YAGL_LOG_FUNC_SET(eglSwapBuffers);
@@ -133,19 +81,16 @@ static int yagl_onscreen_surface_swap_buffers(struct yagl_surface *sfc)
yagl_onscreen_surface_finish(sfc);
- yagl_DRI2SwapBuffers(sfc->dpy->x_dpy,
- sfc->x_drawable.win, 0, 0, 0,
- &count);
+ sfc->native_drawable->swap_buffers(sfc->native_drawable);
return 1;
}
static int yagl_onscreen_surface_copy_buffers(struct yagl_surface *sfc,
- Pixmap target)
+ yagl_os_pixmap target)
{
struct yagl_onscreen_surface *osfc = (struct yagl_onscreen_surface*)sfc;
EGLBoolean retval = EGL_FALSE;
- GC x_gc;
YAGL_LOG_FUNC_SET(eglCopyBuffers);
@@ -160,62 +105,10 @@ static int yagl_onscreen_surface_copy_buffers(struct yagl_surface *sfc,
yagl_onscreen_surface_finish(sfc);
- x_gc = XCreateGC(sfc->dpy->x_dpy, target, 0, NULL);
-
- if (x_gc) {
- switch (sfc->type) {
- case EGL_PBUFFER_BIT:
- XCopyArea(sfc->dpy->x_dpy,
- osfc->tmp_pixmap,
- target,
- x_gc,
- 0, 0,
- osfc->buffer->drm_sfc->width,
- osfc->buffer->drm_sfc->height,
- 0, 0);
- break;
- case EGL_PIXMAP_BIT:
-#ifdef YAGL_FAKE_PIXMAP_SURFACE
- XCopyArea(sfc->dpy->x_dpy,
- osfc->tmp_pixmap,
- target,
- x_gc,
- 0, 0,
- osfc->buffer->drm_sfc->width,
- osfc->buffer->drm_sfc->height,
- 0, 0);
-#else
- XCopyArea(sfc->dpy->x_dpy,
- sfc->x_drawable.pixmap,
- target,
- x_gc,
- 0, 0,
- osfc->buffer->drm_sfc->width,
- osfc->buffer->drm_sfc->height,
- 0, 0);
-#endif
- break;
- case EGL_WINDOW_BIT:
- XCopyArea(sfc->dpy->x_dpy,
- sfc->x_drawable.win,
- target,
- x_gc,
- 0, 0,
- osfc->buffer->drm_sfc->width,
- osfc->buffer->drm_sfc->height,
- 0, 0);
- break;
- default:
- assert(0);
- YAGL_LOG_ERROR("Bad surface type");
- }
- } else {
- YAGL_LOG_ERROR("XCreateGC failed");
- }
-
- XFreeGC(sfc->dpy->x_dpy, x_gc);
-
- XSync(sfc->dpy->x_dpy, 0);
+ sfc->native_drawable->copy_to_pixmap(sfc->native_drawable,
+ target, 0, 0, 0, 0,
+ osfc->buffer->drm_sfc->width,
+ osfc->buffer->drm_sfc->height);
return 1;
}
@@ -233,11 +126,9 @@ static void yagl_onscreen_surface_wait_x(struct yagl_surface *sfc)
*/
break;
case EGL_PIXMAP_BIT:
-#ifndef YAGL_FAKE_PIXMAP_SURFACE
- yagl_onscreen_surface_copy_drawable(osfc,
- DRI2BufferFrontLeft,
- DRI2BufferFakeFrontLeft);
-#endif
+ sfc->native_drawable->wait(sfc->native_drawable,
+ osfc->buffer->drm_sfc->width,
+ osfc->buffer->drm_sfc->height);
break;
default:
assert(0);
@@ -250,7 +141,6 @@ static void yagl_onscreen_surface_wait_gl(struct yagl_surface *sfc)
EGLBoolean retval;
/*
- * There used to be DRI2CopyRegion call here, but it's not needed.
* This call must not be distinguishable from glFinish, so just do
* the stuff glFinish does here and not more.
*/
@@ -311,36 +201,18 @@ static void yagl_onscreen_surface_set_swap_interval(struct yagl_surface *sfc,
{
assert(sfc->type == EGL_WINDOW_BIT);
- yagl_DRI2SwapInterval(sfc->dpy->x_dpy, sfc->x_drawable.win, interval);
+ sfc->native_drawable->set_swap_interval(sfc->native_drawable, interval);
}
static void yagl_onscreen_surface_destroy(struct yagl_ref *ref)
{
struct yagl_onscreen_surface *sfc = (struct yagl_onscreen_surface*)ref;
- yagl_onscreen_display_destroy_buffer(sfc->buffer);
- switch (sfc->base.type) {
- case EGL_PBUFFER_BIT:
- yagl_DRI2DestroyDrawable(sfc->base.dpy->x_dpy,
- sfc->tmp_pixmap);
- break;
- case EGL_PIXMAP_BIT:
- yagl_DRI2DestroyDrawable(sfc->base.dpy->x_dpy,
- sfc->base.x_drawable.pixmap);
- break;
- case EGL_WINDOW_BIT:
- yagl_DRI2DestroyDrawable(sfc->base.dpy->x_dpy,
- sfc->base.x_drawable.win);
- break;
- default:
- assert(0);
- break;
- }
+ yagl_onscreen_buffer_destroy(sfc->buffer);
if (sfc->tmp_pixmap) {
- XFreePixmap(sfc->base.dpy->x_dpy,
- sfc->tmp_pixmap);
- sfc->tmp_pixmap = 0;
+ sfc->tmp_pixmap->destroy(sfc->tmp_pixmap);
+ sfc->tmp_pixmap = NULL;
}
yagl_surface_cleanup(&sfc->base);
@@ -351,7 +223,7 @@ static void yagl_onscreen_surface_destroy(struct yagl_ref *ref)
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_window(struct yagl_display *dpy,
yagl_host_handle host_config,
- Window x_win,
+ struct yagl_native_drawable *native_window,
const EGLint* attrib_list)
{
struct yagl_onscreen_display *odpy = (struct yagl_onscreen_display*)dpy;
@@ -361,12 +233,10 @@ struct yagl_onscreen_surface
sfc = yagl_malloc0(sizeof(*sfc));
- yagl_DRI2CreateDrawable(dpy->x_dpy, x_win);
-
- new_buffer = yagl_onscreen_display_create_buffer(odpy,
- x_win,
- DRI2BufferBackLeft,
- 0);
+ new_buffer = yagl_onscreen_buffer_create(odpy,
+ native_window,
+ yagl_native_attachment_back,
+ 0);
if (!new_buffer) {
yagl_set_error(EGL_BAD_NATIVE_WINDOW);
@@ -389,7 +259,7 @@ struct yagl_onscreen_surface
&yagl_onscreen_surface_destroy,
host_surface,
dpy,
- x_win);
+ native_window);
sfc->base.invalidate = &yagl_onscreen_surface_invalidate;
sfc->base.finish = &yagl_onscreen_surface_finish;
@@ -407,119 +277,17 @@ struct yagl_onscreen_surface
fail:
if (new_buffer) {
- yagl_onscreen_display_destroy_buffer(new_buffer);
- yagl_DRI2DestroyDrawable(dpy->x_dpy, x_win);
+ yagl_onscreen_buffer_destroy(new_buffer);
}
yagl_free(sfc);
return NULL;
}
-#ifdef YAGL_FAKE_PIXMAP_SURFACE
-struct yagl_onscreen_surface
- *yagl_onscreen_surface_create_pixmap(struct yagl_display *dpy,
- yagl_host_handle host_config,
- Pixmap x_pixmap,
- const EGLint* attrib_list)
-{
- struct yagl_onscreen_display *odpy = (struct yagl_onscreen_display*)dpy;
- struct yagl_onscreen_surface *sfc;
- uint32_t width = 0;
- uint32_t height = 0;
- unsigned int depth = 0;
- union { Window w; int i; unsigned int ui; } tmp_geom;
- struct yagl_onscreen_buffer *new_buffer = NULL;
- yagl_host_handle host_surface = 0;
-
- YAGL_LOG_FUNC_SET(eglCreatePixmapSurface);
-
- memset(&tmp_geom, 0, sizeof(tmp_geom));
-
- XGetGeometry(dpy->x_dpy,
- x_pixmap,
- &tmp_geom.w,
- &tmp_geom.i,
- &tmp_geom.i,
- &width,
- &height,
- &tmp_geom.ui,
- &depth);
-
- sfc = yagl_malloc0(sizeof(*sfc));
-
- sfc->tmp_pixmap = XCreatePixmap(dpy->x_dpy,
- RootWindow(dpy->x_dpy, DefaultScreen(dpy->x_dpy)),
- width, height, depth);
-
- if (!sfc->tmp_pixmap) {
- YAGL_LOG_ERROR("XCreatePixmap(%u,%u) failed", width, height);
- yagl_set_error(EGL_BAD_ALLOC);
- goto fail;
- }
-
- yagl_DRI2CreateDrawable(dpy->x_dpy, sfc->tmp_pixmap);
-
- new_buffer = yagl_onscreen_display_create_buffer(odpy,
- sfc->tmp_pixmap,
- DRI2BufferFrontLeft,
- 0);
-
- if (!new_buffer) {
- yagl_set_error(EGL_BAD_NATIVE_PIXMAP);
- goto fail;
- }
-
- do {
- yagl_mem_probe_read_attrib_list(attrib_list);
- } while (!yagl_host_eglCreatePixmapSurfaceOnscreenYAGL(&host_surface,
- dpy->host_dpy,
- host_config,
- new_buffer->drm_sfc->id,
- attrib_list));
-
- if (!host_surface) {
- goto fail;
- }
-
- yagl_surface_init_pixmap(&sfc->base,
- &yagl_onscreen_surface_destroy,
- host_surface,
- dpy,
- x_pixmap);
-
- sfc->base.invalidate = &yagl_onscreen_surface_invalidate;
- sfc->base.finish = &yagl_onscreen_surface_finish;
- sfc->base.swap_buffers = &yagl_onscreen_surface_swap_buffers;
- sfc->base.copy_buffers = &yagl_onscreen_surface_copy_buffers;
- sfc->base.wait_x = &yagl_onscreen_surface_wait_x;
- sfc->base.wait_gl = &yagl_onscreen_surface_wait_gl;
- sfc->base.map = &yagl_onscreen_surface_map;
- sfc->base.unmap = &yagl_onscreen_surface_unmap;
- sfc->base.set_swap_interval = &yagl_onscreen_surface_set_swap_interval;
-
- sfc->buffer = new_buffer;
-
- return sfc;
-
-fail:
- if (sfc) {
- if (sfc->tmp_pixmap) {
- if (new_buffer) {
- yagl_onscreen_display_destroy_buffer(new_buffer);
- yagl_DRI2DestroyDrawable(dpy->x_dpy, sfc->tmp_pixmap);
- }
- XFreePixmap(dpy->x_dpy, sfc->tmp_pixmap);
- }
- yagl_free(sfc);
- }
-
- return NULL;
-}
-#else
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_pixmap(struct yagl_display *dpy,
yagl_host_handle host_config,
- Pixmap x_pixmap,
+ struct yagl_native_drawable *native_pixmap,
const EGLint* attrib_list)
{
struct yagl_onscreen_display *odpy = (struct yagl_onscreen_display*)dpy;
@@ -529,12 +297,10 @@ struct yagl_onscreen_surface
sfc = yagl_malloc0(sizeof(*sfc));
- yagl_DRI2CreateDrawable(dpy->x_dpy, x_pixmap);
-
- new_buffer = yagl_onscreen_display_create_buffer(odpy,
- x_pixmap,
- DRI2BufferFrontLeft,
- 0);
+ new_buffer = yagl_onscreen_buffer_create(odpy,
+ native_pixmap,
+ yagl_native_attachment_front,
+ 0);
if (!new_buffer) {
yagl_set_error(EGL_BAD_NATIVE_PIXMAP);
@@ -557,7 +323,7 @@ struct yagl_onscreen_surface
&yagl_onscreen_surface_destroy,
host_surface,
dpy,
- x_pixmap);
+ native_pixmap);
sfc->base.invalidate = &yagl_onscreen_surface_invalidate;
sfc->base.finish = &yagl_onscreen_surface_finish;
@@ -575,14 +341,12 @@ struct yagl_onscreen_surface
fail:
if (new_buffer) {
- yagl_onscreen_display_destroy_buffer(new_buffer);
- yagl_DRI2DestroyDrawable(dpy->x_dpy, x_pixmap);
+ yagl_onscreen_buffer_destroy(new_buffer);
}
yagl_free(sfc);
return NULL;
}
-#endif
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_pbuffer(struct yagl_display *dpy,
@@ -618,22 +382,21 @@ struct yagl_onscreen_surface
}
}
- sfc->tmp_pixmap = XCreatePixmap(dpy->x_dpy,
- RootWindow(dpy->x_dpy, DefaultScreen(dpy->x_dpy)),
- width, height, 24);
+ sfc->tmp_pixmap = dpy->native_dpy->create_pixmap(dpy->native_dpy,
+ width,
+ height,
+ 24);
if (!sfc->tmp_pixmap) {
- YAGL_LOG_ERROR("XCreatePixmap(%u,%u) failed", width, height);
+ YAGL_LOG_ERROR("create_pixmap(%u,%u) failed", width, height);
yagl_set_error(EGL_BAD_ALLOC);
goto fail;
}
- yagl_DRI2CreateDrawable(dpy->x_dpy, sfc->tmp_pixmap);
-
- new_buffer = yagl_onscreen_display_create_buffer(odpy,
- sfc->tmp_pixmap,
- DRI2BufferFrontLeft,
- 0);
+ new_buffer = yagl_onscreen_buffer_create(odpy,
+ sfc->tmp_pixmap,
+ yagl_native_attachment_front,
+ 0);
if (!new_buffer) {
yagl_set_error(EGL_BAD_ALLOC);
@@ -675,10 +438,10 @@ fail:
if (sfc) {
if (sfc->tmp_pixmap) {
if (new_buffer) {
- yagl_onscreen_display_destroy_buffer(new_buffer);
- yagl_DRI2DestroyDrawable(dpy->x_dpy, sfc->tmp_pixmap);
+ yagl_onscreen_buffer_destroy(new_buffer);
}
- XFreePixmap(dpy->x_dpy, sfc->tmp_pixmap);
+ sfc->tmp_pixmap->destroy(sfc->tmp_pixmap);
+ sfc->tmp_pixmap = NULL;
}
yagl_free(sfc);
}
diff --git a/EGL/yagl_onscreen_surface.h b/EGL/yagl_onscreen_surface.h
index 7d92587..7fc7d03 100644
--- a/EGL/yagl_onscreen_surface.h
+++ b/EGL/yagl_onscreen_surface.h
@@ -4,8 +4,8 @@
#include "yagl_export.h"
#include "yagl_types.h"
#include "yagl_surface.h"
-#include "yagl_dri2.h"
-#include "yagl_onscreen_display.h"
+
+struct yagl_onscreen_buffer;
struct yagl_onscreen_surface
{
@@ -14,27 +14,20 @@ struct yagl_onscreen_surface
/*
* Backing pixmap for PBuffer surfaces. NULL otherwise.
*/
- Pixmap tmp_pixmap;
+ struct yagl_native_drawable *tmp_pixmap;
/*
- * For widow surfaces this is DRI2BufferBackLeft.
- * For pixmap surfaces this is DRI2BufferFrontLeft.
- * For pbuffer surfaces this is DRI2BufferFrontLeft of 'tmp_pixmap'.
+ * For widow surfaces this is yagl_native_attachment_back.
+ * For pixmap surfaces this is yagl_native_attachment_front.
+ * For pbuffer surfaces this is yagl_native_attachment_front of 'tmp_pixmap'.
*
* TODO: For window surfaces we also need to support
- * DRI2BufferFrontLeft.
+ * yagl_native_attachment_front.
*/
struct yagl_onscreen_buffer *buffer;
/*
- * This gets incremented in DRI2 invalidate handler, compare it to
- * 'last_timestamp' in order to find out if an invalidate event
- * had occurred.
- */
- uint32_t stamp;
-
- /*
- * Last value of 'stamp'.
+ * Last value of 'base.native_drawable->stamp'.
*/
uint32_t last_stamp;
};
@@ -42,18 +35,18 @@ struct yagl_onscreen_surface
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_window(struct yagl_display *dpy,
yagl_host_handle host_config,
- Window x_win,
- const EGLint* attrib_list);
+ struct yagl_native_drawable *native_window,
+ const EGLint *attrib_list);
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_pixmap(struct yagl_display *dpy,
yagl_host_handle host_config,
- Pixmap x_pixmap,
- const EGLint* attrib_list);
+ struct yagl_native_drawable *native_pixmap,
+ const EGLint *attrib_list);
struct yagl_onscreen_surface
*yagl_onscreen_surface_create_pbuffer(struct yagl_display *dpy,
yagl_host_handle host_config,
- const EGLint* attrib_list);
+ const EGLint *attrib_list);
#endif
diff --git a/EGL/yagl_surface.c b/EGL/yagl_surface.c
index b6b311e..bdf1f46 100644
--- a/EGL/yagl_surface.c
+++ b/EGL/yagl_surface.c
@@ -1,5 +1,6 @@
#include "yagl_surface.h"
#include "yagl_utils.h"
+#include "yagl_native_drawable.h"
#include <assert.h>
#include "EGL/eglext.h"
@@ -7,13 +8,13 @@ void yagl_surface_init_window(struct yagl_surface *sfc,
yagl_ref_destroy_func destroy_func,
yagl_host_handle handle,
struct yagl_display *dpy,
- Window x_win)
+ struct yagl_native_drawable *native_window)
{
yagl_resource_init(&sfc->res, destroy_func, handle);
sfc->dpy = dpy;
sfc->type = EGL_WINDOW_BIT;
- sfc->x_drawable.win = x_win;
+ sfc->native_drawable = native_window;
yagl_recursive_mutex_init(&sfc->mtx);
}
@@ -22,13 +23,13 @@ void yagl_surface_init_pixmap(struct yagl_surface *sfc,
yagl_ref_destroy_func destroy_func,
yagl_host_handle handle,
struct yagl_display *dpy,
- Pixmap x_pixmap)
+ struct yagl_native_drawable *native_pixmap)
{
yagl_resource_init(&sfc->res, destroy_func, handle);
sfc->dpy = dpy;
sfc->type = EGL_PIXMAP_BIT;
- sfc->x_drawable.pixmap = x_pixmap;
+ sfc->native_drawable = native_pixmap;
yagl_recursive_mutex_init(&sfc->mtx);
}
@@ -48,6 +49,10 @@ void yagl_surface_init_pbuffer(struct yagl_surface *sfc,
void yagl_surface_cleanup(struct yagl_surface *sfc)
{
+ if (sfc->native_drawable) {
+ sfc->native_drawable->destroy(sfc->native_drawable);
+ sfc->native_drawable = NULL;
+ }
yagl_resource_cleanup(&sfc->res);
pthread_mutex_destroy(&sfc->mtx);
}
@@ -58,9 +63,8 @@ EGLSurface yagl_surface_get_handle(struct yagl_surface *sfc)
case EGL_PBUFFER_BIT:
return (EGLSurface)sfc->res.handle;
case EGL_PIXMAP_BIT:
- return (EGLSurface)sfc->x_drawable.pixmap;
case EGL_WINDOW_BIT:
- return (EGLSurface)sfc->x_drawable.win;
+ return (EGLSurface)sfc->native_drawable->os_drawable;
default:
assert(0);
return NULL;
diff --git a/EGL/yagl_surface.h b/EGL/yagl_surface.h
index b966776..e634ee1 100644
--- a/EGL/yagl_surface.h
+++ b/EGL/yagl_surface.h
@@ -3,10 +3,12 @@
#include "yagl_export.h"
#include "yagl_types.h"
+#include "yagl_native_types.h"
#include "yagl_resource.h"
#include "EGL/egl.h"
struct yagl_display;
+struct yagl_native_drawable;
struct yagl_surface
{
@@ -16,11 +18,7 @@ struct yagl_surface
EGLenum type;
- union
- {
- Window win;
- Pixmap pixmap;
- } x_drawable;
+ struct yagl_native_drawable *native_drawable;
pthread_mutex_t mtx;
@@ -44,7 +42,7 @@ struct yagl_surface
int (*swap_buffers)(struct yagl_surface */*sfc*/);
- int (*copy_buffers)(struct yagl_surface */*sfc*/, Pixmap /*target*/);
+ int (*copy_buffers)(struct yagl_surface */*sfc*/, yagl_os_pixmap /*target*/);
void (*wait_x)(struct yagl_surface */*sfc*/);
@@ -57,17 +55,23 @@ struct yagl_surface
void (*set_swap_interval)(struct yagl_surface */*sfc*/, int /*interval*/);
};
+/*
+ * Takes ownership of 'native_window'.
+ */
void yagl_surface_init_window(struct yagl_surface *sfc,
yagl_ref_destroy_func destroy_func,
yagl_host_handle handle,
struct yagl_display *dpy,
- Window x_win);
+ struct yagl_native_drawable *native_window);
+/*
+ * Takes ownership of 'native_pixmap'.
+ */
void yagl_surface_init_pixmap(struct yagl_surface *sfc,
yagl_ref_destroy_func destroy_func,
yagl_host_handle handle,
struct yagl_display *dpy,
- Pixmap x_pixmap);
+ struct yagl_native_drawable *native_pixmap);
void yagl_surface_init_pbuffer(struct yagl_surface *sfc,
yagl_ref_destroy_func destroy_func,
diff --git a/GLES_common/yagl_gles_calls.c b/GLES_common/yagl_gles_calls.c
index 51a7da8..e6e1f17 100644
--- a/GLES_common/yagl_gles_calls.c
+++ b/GLES_common/yagl_gles_calls.c
@@ -1,4 +1,3 @@
-#include <X11/Xutil.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/include/yagl_marshal_egl.h b/include/yagl_marshal_egl.h
index e625f17..78ea18a 100644
--- a/include/yagl_marshal_egl.h
+++ b/include/yagl_marshal_egl.h
@@ -14,7 +14,5 @@
#define yagl_marshal_get_EGLint(buff) yagl_marshal_get_int32(buff)
#define yagl_marshal_put_EGLClientBuffer(buff, value) yagl_marshal_skip(buff)
-#define yagl_marshal_put_EGLNativePixmapType(buff, value) yagl_marshal_skip(buff)
-#define yagl_marshal_put_EGLNativeWindowType(buff, value) yagl_marshal_skip(buff)
#endif
diff --git a/include/yagl_platform.h b/include/yagl_platform.h
deleted file mode 100644
index 1c5a6b1..0000000
--- a/include/yagl_platform.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _YAGL_PLATFORM_H_
-#define _YAGL_PLATFORM_H_
-
-#if defined(__i386) || defined(_M_IX86)
-#define YAGL_LITTLE_ENDIAN
-#elif defined(__x86_64) || defined(_M_X64) || defined(_M_IA64)
-#define YAGL_LITTLE_ENDIAN
-#elif defined(__arm__)
-#define YAGL_LITTLE_ENDIAN
-#else
-#error Unknown architecture
-#endif
-
-#if defined(__x86_64) || defined(_M_X64) || defined(_M_IA64) || defined(__LP64__)
-#define YAGL_64
-#else
-#define YAGL_32
-#endif
-
-#if !defined(YAGL_64) && !defined(YAGL_32)
-#error 32 or 64 bit mode must be set
-#endif
-
-#endif
diff --git a/include/yagl_types.h b/include/yagl_types.h
index 8f0dddf..6573354 100644
--- a/include/yagl_types.h
+++ b/include/yagl_types.h
@@ -1,10 +1,29 @@
#ifndef _YAGL_TYPES_H_
#define _YAGL_TYPES_H_
-#include "yagl_platform.h"
#include <stdint.h>
#include <stddef.h>
+#if defined(__i386) || defined(_M_IX86)
+#define YAGL_LITTLE_ENDIAN
+#elif defined(__x86_64) || defined(_M_X64) || defined(_M_IA64)
+#define YAGL_LITTLE_ENDIAN
+#elif defined(__arm__)
+#define YAGL_LITTLE_ENDIAN
+#else
+#error Unknown architecture
+#endif
+
+#if defined(__x86_64) || defined(_M_X64) || defined(_M_IA64) || defined(__LP64__)
+#define YAGL_64
+#else
+#define YAGL_32
+#endif
+
+#if !defined(YAGL_64) && !defined(YAGL_32)
+#error 32 or 64 bit mode must be set
+#endif
+
typedef enum
{
yagl_render_type_offscreen = 1,
diff --git a/include/yagl_version.h b/include/yagl_version.h
index ae60f16..7c214b2 100644
--- a/include/yagl_version.h
+++ b/include/yagl_version.h
@@ -6,7 +6,7 @@
/*
* Version number.
*/
-#define YAGL_VERSION 18
+#define YAGL_VERSION 19
/*
* Device control codes magic.
diff --git a/packaging/emulator-yagl.spec b/packaging/emulator-yagl.spec
index 4c1d24b..54e79f5 100644
--- a/packaging/emulator-yagl.spec
+++ b/packaging/emulator-yagl.spec
@@ -35,6 +35,8 @@ make
%install
make install
+ln -s libGLESv2.so.2.0 %{buildroot}/usr/lib/yagl/libGLESv2.so.1.0
+ln -s libGLESv2.so.1.0 %{buildroot}/usr/lib/yagl/libGLESv2.so.1
mkdir -p %{buildroot}/usr/lib/systemd/system
cp packaging/emul-opengl-yagl.service %{buildroot}/usr/lib/systemd/system
mkdir -p %{buildroot}/etc/emulator