Commit 7eae4985 authored by Alexander Larsson's avatar Alexander Larsson Committed by Matthias Clasen

wayland: Add OpenGL support

This uses EGL to implement GdkGLContext for wayland.
parent 6717242d
......@@ -427,7 +427,7 @@ fi
PKG_PROG_PKG_CONFIG
WAYLAND_DEPENDENCIES="wayland-client >= wayland_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version"
WAYLAND_DEPENDENCIES="wayland-client >= wayland_required_version xkbcommon >= 0.2.0 wayland-cursor >= wayland_required_version wayland-egl >= wayland_required_version"
if test "$enable_wayland_backend" = "maybe" ; then
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
PKG_CHECK_EXISTS($WAYLAND_DEPENDENCIES, [have_wayland_deps=yes], [have_wayland_deps=no])
......
......@@ -39,7 +39,9 @@ libgdk_wayland_la_SOURCES = \
gdkdisplay-wayland.h \
gdkdnd-wayland.c \
gdkeventsource.c \
gdkkeys-wayland.c \
gdkkeys-wayland.c \
gdkglcontext-wayland.c \
gdkglcontext-wayland.h \
gdkscreen-wayland.c \
gdkselection-wayland.c \
gdkwindow-wayland.c \
......@@ -54,6 +56,7 @@ libgdkinclude_HEADERS = \
libgdkwaylandinclude_HEADERS = \
gdkwaylanddevice.h \
gdkwaylanddisplay.h \
gdkwaylandglcontext.h \
gdkwaylandselection.h \
gdkwaylandwindow.h
......
......@@ -34,6 +34,7 @@
#include "gdkdevicemanager.h"
#include "gdkkeysprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkglcontext-wayland.h"
/**
* SECTION:wayland_interaction
......@@ -540,6 +541,9 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass * class)
display_class->convert_selection = _gdk_wayland_display_convert_selection;
display_class->text_property_to_utf8_list = _gdk_wayland_display_text_property_to_utf8_list;
display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target;
display_class->destroy_gl_context = gdk_wayland_display_destroy_gl_context;
display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
}
static void
......
......@@ -26,6 +26,7 @@
#include <stdint.h>
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <wayland-egl.h>
#include <gdk/wayland/gtk-shell-client-protocol.h>
#include <gdk/wayland/xdg-shell-client-protocol.h>
......@@ -37,6 +38,8 @@
#include "gdkdisplayprivate.h"
#include <epoxy/egl.h>
G_BEGIN_DECLS
typedef struct _GdkWaylandSelection GdkWaylandSelection;
......@@ -76,6 +79,16 @@ struct _GdkWaylandDisplay
struct xkb_context *xkb_context;
GdkWaylandSelection *selection;
/* egl info */
EGLDisplay egl_display;
int egl_major_version;
int egl_minor_version;
guint have_egl : 1;
guint have_egl_khr_create_context : 1;
guint have_egl_buffer_age : 1;
guint have_egl_swap_buffers_with_damage : 1;
};
struct _GdkWaylandDisplayClass
......
This diff is collapsed.
/* GDK - The GIMP Drawing Kit
*
* gdkglcontext-wayland.h: Private Wayland specific OpenGL wrappers
*
* Copyright © 2014 Emmanuele Bassi
* Copyright © 2014 Red Hat, Int
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_WAYLAND_GL_CONTEXT__
#define __GDK_WAYLAND_GL_CONTEXT__
#include "gdkglcontextprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkvisual.h"
#include "gdkwindow.h"
#include "gdkinternals.h"
#include "gdkmain.h"
#include <epoxy/egl.h>
G_BEGIN_DECLS
struct _GdkWaylandGLContext
{
GdkGLContext parent_instance;
EGLContext egl_context;
EGLConfig egl_config;
};
struct _GdkWaylandGLContextClass
{
GdkGLContextClass parent_class;
};
gboolean gdk_wayland_display_init_gl (GdkDisplay *display);
GdkGLContext * gdk_wayland_window_create_gl_context (GdkWindow *window,
GdkGLProfile profile,
GdkGLContext *share,
GError **error);
void gdk_wayland_window_invalidate_for_new_frame (GdkWindow *window,
cairo_region_t *update_area);
void gdk_wayland_display_destroy_gl_context (GdkDisplay *display,
GdkGLContext *context);
gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
GdkGLContext *context);
G_END_DECLS
#endif /* __GDK_WAYLAND_GL_CONTEXT__ */
......@@ -237,5 +237,7 @@ struct wl_data_source * gdk_wayland_selection_get_data_source (GdkWindow *owner,
GdkAtom selection);
void gdk_wayland_selection_unset_data_source (GdkAtom selection);
EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
EGLConfig config);
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
......@@ -33,6 +33,7 @@
#include <gdk/wayland/gdkwaylanddisplay.h>
#include <gdk/wayland/gdkwaylandselection.h>
#include <gdk/wayland/gdkwaylandwindow.h>
#include <gdk/wayland/gdkwaylandglcontext.h>
#undef __GDKWAYLAND_H_INSIDE__
......
/* GDK - The GIMP Drawing Kit
*
* gdkglcontext-wayland.c: Wayland specific OpenGL wrappers
*
* Copyright © 2014 Emmanuele Bassi
* Copyright © 2014 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_WAYLAND_GL_CONTEXT_H__
#define __GDK_WAYLAND_GL_CONTEXT_H__
#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GDK_COMPILATION)
#error "Only <gdk/gdkwayland.h> can be included directly."
#endif
#include <gdk/gdk.h>
G_BEGIN_DECLS
#define GDK_WAYLAND_TYPE_GL_CONTEXT (gdk_wayland_gl_context_get_type ())
#define GDK_WAYLAND_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_WAYLAND_TYPE_GL_CONTEXT, GdkWaylandGLContext))
#define GDK_WAYLAND_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_WAYLAND_TYPE_GL_CONTEXT))
typedef struct _GdkWaylandGLContext GdkWaylandGLContext;
typedef struct _GdkWaylandGLContextClass GdkWaylandGLContextClass;
GDK_AVAILABLE_IN_3_14
GType gdk_wayland_gl_context_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GDK_WAYLAND_GL_CONTEXT_H__ */
......@@ -26,6 +26,7 @@
#include "gdkwindow.h"
#include "gdkwindowimpl.h"
#include "gdkdisplay-wayland.h"
#include "gdkglcontext-wayland.h"
#include "gdkframeclockprivate.h"
#include "gdkprivate-wayland.h"
#include "gdkinternals.h"
......@@ -97,6 +98,9 @@ struct _GdkWindowImplWayland
struct wl_subsurface *subsurface;
struct wl_egl_window *egl_window;
EGLSurface egl_surface;
unsigned int mapped : 1;
unsigned int use_custom_surface : 1;
unsigned int pending_commit : 1;
......@@ -170,6 +174,9 @@ gdk_wayland_window_update_size (GdkWindow *window,
window->width = width;
window->height = height;
if (impl->egl_window)
wl_egl_window_resize (impl->egl_window, width, height, 0, 0);
area.x = 0;
area.y = 0;
area.width = window->width;
......@@ -582,15 +589,18 @@ gdk_window_impl_wayland_end_paint (GdkWindow *window)
cairo_rectangle_int_t rect;
int i, n;
gdk_wayland_window_attach_image (window);
n = cairo_region_num_rectangles (window->current_paint.region);
for (i = 0; i < n; i++)
if (!window->current_paint.use_gl)
{
cairo_region_get_rectangle (window->current_paint.region, i, &rect);
wl_surface_damage (impl->surface,
rect.x, rect.y, rect.width, rect.height);
impl->pending_commit = TRUE;
gdk_wayland_window_attach_image (window);
n = cairo_region_num_rectangles (window->current_paint.region);
for (i = 0; i < n; i++)
{
cairo_region_get_rectangle (window->current_paint.region, i, &rect);
wl_surface_damage (impl->surface,
rect.x, rect.y, rect.width, rect.height);
impl->pending_commit = TRUE;
}
}
}
......@@ -1156,10 +1166,23 @@ gdk_wayland_window_show (GdkWindow *window,
static void
gdk_wayland_window_hide_surface (GdkWindow *window)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (impl->surface)
{
if (impl->egl_surface)
{
eglDestroySurface(display_wayland->egl_display, impl->egl_surface);
impl->egl_surface = NULL;
}
if (impl->egl_window)
{
wl_egl_window_destroy (impl->egl_window);
impl->egl_window = NULL;
}
if (impl->xdg_surface)
{
xdg_surface_destroy (impl->xdg_surface);
......@@ -2128,6 +2151,8 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
impl_class->set_opaque_region = gdk_wayland_window_set_opaque_region;
impl_class->set_shadow_width = gdk_wayland_window_set_shadow_width;
impl_class->show_window_menu = gdk_wayland_window_show_window_menu;
impl_class->create_gl_context = gdk_wayland_window_create_gl_context;
impl_class->invalidate_for_new_frame = gdk_wayland_window_invalidate_for_new_frame;
}
void
......@@ -2169,6 +2194,50 @@ gdk_wayland_window_get_wl_surface (GdkWindow *window)
return impl->surface;
}
static struct wl_egl_window *
gdk_wayland_window_get_wl_egl_window (GdkWindow *window)
{
GdkWindowImplWayland *impl;
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (impl->egl_window == NULL)
{
impl->egl_window =
wl_egl_window_create(impl->surface,
impl->wrapper->width,
impl->wrapper->height);
}
return impl->egl_window;
}
EGLSurface
gdk_wayland_window_get_egl_surface (GdkWindow *window,
EGLConfig config)
{
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
GdkWindowImplWayland *impl;
struct wl_egl_window *egl_window;
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
if (impl->egl_surface == NULL)
{
egl_window = gdk_wayland_window_get_wl_egl_window (window);
impl->egl_surface =
eglCreateWindowSurface (display_wayland->egl_display,
config, egl_window, NULL);
}
return impl->egl_surface;
}
/**
* gdk_wayland_window_set_use_custom_surface:
* @window: (type GdkWaylandWindow): a #GdkWindow
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment