mirror of
https://gitlab.gnome.org/GNOME/libmks.git
synced 2024-12-21 21:25:21 +00:00
Merge branch 'bilelmoussaoui/dmabuf-texture' into 'main'
Switch to using GdkDmaBufTexture See merge request GNOME/libmks!45
This commit is contained in:
commit
90f722234b
@ -13,9 +13,9 @@ tests:
|
||||
variables:
|
||||
MESON_FLAGS: "-Db_coverage=true -Ddocs=false -Dvapi=false -Dintrospection=disabled"
|
||||
before_script:
|
||||
- sudo dnf install -y git gtk4-devel libepoxy-devel meson gcc lcov wget
|
||||
- sudo dnf install -y git gtk4-devel meson gcc gcovr lcov wget
|
||||
qemu-system-x86 qemu-ui-dbus qemu-ui-opengl
|
||||
dbus-x11 xorg-x11-server-Xvfb
|
||||
dbus-x11 xorg-x11-server-Xvfb python3-packaging
|
||||
script:
|
||||
- meson setup _build
|
||||
- meson configure ${MESON_FLAGS} _build
|
||||
@ -24,7 +24,6 @@ tests:
|
||||
- cd tests
|
||||
- BUILDDIR=_build dbus-run-session xvfb-run -ad ./functional.sh
|
||||
- cd ..
|
||||
- rm -rf _build/subprojects
|
||||
- ninja coverage-html -C _build
|
||||
artifacts:
|
||||
paths:
|
||||
@ -46,8 +45,8 @@ reference:
|
||||
variables:
|
||||
MESON_FLAGS: "--buildtype=release -Ddocs=true -Dintrospection=enabled"
|
||||
before_script:
|
||||
- sudo dnf install -y git gtk4-devel libepoxy-devel meson gcc
|
||||
gi-docgen gobject-introspection-devel vala
|
||||
- sudo dnf install -y git gtk4-devel meson gcc
|
||||
gi-docgen gobject-introspection-devel vala python3-packaging
|
||||
script:
|
||||
- mkdir -p pfx/
|
||||
- meson ${MESON_FLAGS} --prefix=${PWD}/pfx -Ddocs=true _build
|
||||
|
@ -45,7 +45,6 @@ libmks_private_sources = [
|
||||
'mks-dmabuf-paintable.c',
|
||||
'mks-display-picture.c',
|
||||
'mks-css.c',
|
||||
'mks-gl-context.c',
|
||||
'mks-inhibitor.c',
|
||||
'mks-read-only-list-model.c',
|
||||
'mks-screen-resizer.c',
|
||||
@ -120,7 +119,6 @@ libmks_private_generated_headers = [
|
||||
]
|
||||
|
||||
libmks_deps = [
|
||||
libepoxy_dep,
|
||||
libgio_dep,
|
||||
libgiounix_dep,
|
||||
libgtk_dep,
|
||||
|
@ -43,6 +43,7 @@ typedef struct
|
||||
MksScreenResizer *resizer;
|
||||
MksDisplayPicture *picture;
|
||||
MksInhibitor *inhibitor;
|
||||
GtkWidget *offload;
|
||||
GtkShortcutTrigger *ungrab_trigger;
|
||||
guint auto_resize : 1;
|
||||
} MksDisplayPrivate;
|
||||
@ -145,6 +146,7 @@ mks_display_connect (MksDisplay *self,
|
||||
mks_screen_resizer_set_screen (priv->resizer, screen);
|
||||
|
||||
mks_screen_attach (screen,
|
||||
gtk_widget_get_display (GTK_WIDGET (self)),
|
||||
NULL,
|
||||
mks_display_attach_cb,
|
||||
g_object_ref (self));
|
||||
@ -236,25 +238,12 @@ mks_display_dispose (GObject *object)
|
||||
|
||||
mks_display_disconnect (self);
|
||||
|
||||
g_clear_pointer ((GtkWidget **)&priv->picture, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->offload, gtk_widget_unparent);
|
||||
g_clear_object (&priv->resizer);
|
||||
|
||||
G_OBJECT_CLASS (mks_display_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mks_display_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
MksDisplay *self = (MksDisplay *)widget;
|
||||
MksDisplayPrivate *priv = mks_display_get_instance_private (self);
|
||||
|
||||
g_assert (MKS_IS_DISPLAY (self));
|
||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
gtk_widget_snapshot_child (widget, GTK_WIDGET (priv->picture), snapshot);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mks_display_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
@ -285,7 +274,7 @@ mks_display_measure (GtkWidget *widget,
|
||||
|
||||
g_assert (MKS_IS_DISPLAY (self));
|
||||
|
||||
gtk_widget_measure (GTK_WIDGET (priv->picture), orientation, for_size,
|
||||
gtk_widget_measure (priv->offload, orientation, for_size,
|
||||
minimum, natural, minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
@ -317,7 +306,7 @@ mks_display_size_allocate (GtkWidget *widget,
|
||||
mks_screen_attributes_free (attributes);
|
||||
}
|
||||
|
||||
gtk_widget_size_allocate (GTK_WIDGET (priv->picture),
|
||||
gtk_widget_size_allocate (priv->offload,
|
||||
&(GtkAllocation) {
|
||||
area.origin.x,
|
||||
area.origin.y,
|
||||
@ -394,7 +383,6 @@ mks_display_class_init (MksDisplayClass *klass)
|
||||
widget_class->get_request_mode = mks_display_get_request_mode;
|
||||
widget_class->measure = mks_display_measure;
|
||||
widget_class->size_allocate = mks_display_size_allocate;
|
||||
widget_class->snapshot = mks_display_snapshot;
|
||||
widget_class->grab_focus = mks_display_grab_focus;
|
||||
|
||||
properties[PROP_SCREEN] =
|
||||
@ -427,7 +415,9 @@ mks_display_init (MksDisplay *self)
|
||||
|
||||
priv->picture = g_object_new (MKS_TYPE_DISPLAY_PICTURE, NULL);
|
||||
priv->resizer = mks_screen_resizer_new ();
|
||||
gtk_widget_set_parent (GTK_WIDGET (priv->picture), GTK_WIDGET (self));
|
||||
|
||||
priv->offload = gtk_graphics_offload_new (GTK_WIDGET (priv->picture));
|
||||
gtk_widget_set_parent (priv->offload, GTK_WIDGET (self));
|
||||
|
||||
controller = gtk_event_controller_legacy_new ();
|
||||
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
|
||||
|
@ -42,7 +42,7 @@ G_DECLARE_FINAL_TYPE (MksDmabufPaintable, mks_dmabuf_paintable, MKS, DMABUF_PAIN
|
||||
|
||||
MksDmabufPaintable *mks_dmabuf_paintable_new (void);
|
||||
gboolean mks_dmabuf_paintable_import (MksDmabufPaintable *self,
|
||||
GdkGLContext *gl_context,
|
||||
GdkDisplay *display,
|
||||
MksDmabufScanoutData *data,
|
||||
cairo_region_t *region,
|
||||
GError **error);
|
||||
|
@ -25,62 +25,25 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "mks-dmabuf-paintable-private.h"
|
||||
#include "mks-gl-context-private.h"
|
||||
|
||||
/*
|
||||
* MksDmabufPaintable is a GdkPaintable that gets created the first time
|
||||
* `ScanoutDMABUF` is called.
|
||||
*
|
||||
* The scanout data is then stored until we receive a `UpdateDMABUF` call
|
||||
* so we can pass the damage region to `GdkGLTextureBuilder`.
|
||||
* so we can pass the damage region to `GdkDmabufTextureBuilder`.
|
||||
*/
|
||||
|
||||
typedef struct _MksDmabufTextureData
|
||||
{
|
||||
GdkGLContext *gl_context;
|
||||
GLuint texture_id;
|
||||
} MksDmabufTextureData;
|
||||
|
||||
struct _MksDmabufPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
GdkTexture *texture;
|
||||
GdkGLTextureBuilder *builder;
|
||||
GdkDmabufTextureBuilder *builder;
|
||||
guint width;
|
||||
guint height;
|
||||
guint dmabuf_updated : 1;
|
||||
};
|
||||
|
||||
static MksDmabufTextureData *
|
||||
mks_dmabuf_texture_data_new (GdkGLContext *gl_context,
|
||||
GLuint texture_id)
|
||||
{
|
||||
MksDmabufTextureData *texture_data;
|
||||
|
||||
g_assert (GDK_IS_GL_CONTEXT (gl_context));
|
||||
g_assert (texture_id > 0);
|
||||
|
||||
texture_data = g_new0 (MksDmabufTextureData, 1);
|
||||
texture_data->gl_context = g_object_ref (gl_context);
|
||||
texture_data->texture_id = texture_id;
|
||||
|
||||
return texture_data;
|
||||
}
|
||||
|
||||
static void
|
||||
mks_dmabuf_texture_data_free (gpointer data)
|
||||
{
|
||||
MksDmabufTextureData *texture_data = data;
|
||||
|
||||
gdk_gl_context_make_current (texture_data->gl_context);
|
||||
glDeleteTextures (1, &texture_data->texture_id);
|
||||
|
||||
texture_data->texture_id = 0;
|
||||
g_clear_object (&texture_data->gl_context);
|
||||
|
||||
g_free (texture_data);
|
||||
}
|
||||
|
||||
static int
|
||||
mks_dmabuf_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
@ -112,8 +75,7 @@ mks_dmabuf_paintable_snapshot (GdkPaintable *paintable,
|
||||
{
|
||||
MksDmabufPaintable *self = (MksDmabufPaintable *)paintable;
|
||||
g_autoptr(GdkTexture) texture = NULL;
|
||||
GdkGLContext *gl_context;
|
||||
GLuint texture_id;
|
||||
g_autoptr(GError) error = NULL;
|
||||
graphene_rect_t area;
|
||||
|
||||
g_assert (MKS_IS_DMABUF_PAINTABLE (self));
|
||||
@ -122,21 +84,22 @@ mks_dmabuf_paintable_snapshot (GdkPaintable *paintable,
|
||||
/**
|
||||
* If the widget gets resized, snapshot would be called even
|
||||
* if we didn't receive a new DMABufUpdate call.
|
||||
* So only create a new GLTexture when that happens
|
||||
* So only create a new DmabufTexture when that happens
|
||||
*/
|
||||
if (self->dmabuf_updated)
|
||||
{
|
||||
texture_id = gdk_gl_texture_builder_get_id (self->builder);
|
||||
gl_context = gdk_gl_texture_builder_get_context (self->builder);
|
||||
|
||||
|
||||
gdk_gl_texture_builder_set_update_texture (self->builder, self->texture);
|
||||
texture = gdk_gl_texture_builder_build (self->builder,
|
||||
mks_dmabuf_texture_data_free,
|
||||
mks_dmabuf_texture_data_new (gl_context,
|
||||
texture_id));
|
||||
gdk_dmabuf_texture_builder_set_update_texture (self->builder, self->texture);
|
||||
texture = gdk_dmabuf_texture_builder_build (self->builder,
|
||||
NULL, NULL, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_warning ("Failed to build texture: %s", error->message);
|
||||
return;
|
||||
}
|
||||
g_assert (texture != NULL);
|
||||
// Clear up the update region to not union it with the next UpdateDMABuf call
|
||||
gdk_gl_texture_builder_set_update_region (self->builder, NULL);
|
||||
gdk_dmabuf_texture_builder_set_update_region (self->builder, NULL);
|
||||
g_set_object (&self->texture, texture);
|
||||
self->dmabuf_updated = FALSE;
|
||||
}
|
||||
@ -183,18 +146,16 @@ mks_dmabuf_paintable_init (MksDmabufPaintable *self)
|
||||
|
||||
gboolean
|
||||
mks_dmabuf_paintable_import (MksDmabufPaintable *self,
|
||||
GdkGLContext *gl_context,
|
||||
GdkDisplay *display,
|
||||
MksDmabufScanoutData *data,
|
||||
cairo_region_t *region,
|
||||
GError **error)
|
||||
{
|
||||
cairo_region_t *accumulated_damages;
|
||||
cairo_region_t *previous_region;
|
||||
GLuint texture_id;
|
||||
guint zero = 0;
|
||||
guint plane = 0;
|
||||
|
||||
g_return_val_if_fail (MKS_IS_DMABUF_PAINTABLE (self), FALSE);
|
||||
g_return_val_if_fail (!gl_context || GDK_IS_GL_CONTEXT (gl_context), FALSE);
|
||||
|
||||
if (data->dmabuf_fd < 0)
|
||||
{
|
||||
@ -223,18 +184,6 @@ mks_dmabuf_paintable_import (MksDmabufPaintable *self,
|
||||
gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
|
||||
}
|
||||
|
||||
if (!(texture_id = mks_gl_context_import_dmabuf (gl_context,
|
||||
data->fourcc, data->width, data->height,
|
||||
1, &data->dmabuf_fd, &data->stride, &zero,
|
||||
&data->modifier)))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to import dmabuf into GL texture");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
accumulated_damages = cairo_region_create ();
|
||||
|
||||
if (region != NULL)
|
||||
@ -242,21 +191,26 @@ mks_dmabuf_paintable_import (MksDmabufPaintable *self,
|
||||
|
||||
if (self->builder != NULL)
|
||||
{
|
||||
previous_region = gdk_gl_texture_builder_get_update_region (self->builder);
|
||||
previous_region = gdk_dmabuf_texture_builder_get_update_region (self->builder);
|
||||
if (previous_region != NULL)
|
||||
cairo_region_union (accumulated_damages, previous_region);
|
||||
}
|
||||
|
||||
g_clear_object (&self->builder);
|
||||
|
||||
self->builder = gdk_gl_texture_builder_new ();
|
||||
gdk_gl_texture_builder_set_width (self->builder, self->width);
|
||||
gdk_gl_texture_builder_set_height (self->builder, self->height);
|
||||
gdk_gl_texture_builder_set_context (self->builder, gl_context);
|
||||
gdk_gl_texture_builder_set_id (self->builder, texture_id);
|
||||
self->builder = gdk_dmabuf_texture_builder_new ();
|
||||
gdk_dmabuf_texture_builder_set_modifier (self->builder, data->modifier);
|
||||
gdk_dmabuf_texture_builder_set_stride (self->builder, plane, data->stride);
|
||||
gdk_dmabuf_texture_builder_set_fourcc (self->builder, data->fourcc);
|
||||
gdk_dmabuf_texture_builder_set_width (self->builder, data->width);
|
||||
gdk_dmabuf_texture_builder_set_height (self->builder, data->height);
|
||||
gdk_dmabuf_texture_builder_set_fd (self->builder, plane, data->dmabuf_fd);
|
||||
gdk_dmabuf_texture_builder_set_offset (self->builder, plane, 0);
|
||||
gdk_dmabuf_texture_builder_set_display (self->builder, display);
|
||||
gdk_dmabuf_texture_builder_set_n_planes (self->builder, 1);
|
||||
|
||||
if (cairo_region_num_rectangles (accumulated_damages) > 0)
|
||||
gdk_gl_texture_builder_set_update_region (self->builder,
|
||||
gdk_dmabuf_texture_builder_set_update_region (self->builder,
|
||||
accumulated_damages);
|
||||
|
||||
g_clear_pointer (&accumulated_damages, cairo_region_destroy);
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* mks-gl-context-private.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GLuint mks_gl_context_import_dmabuf (GdkGLContext *context,
|
||||
guint32 format,
|
||||
guint width,
|
||||
guint height,
|
||||
guint32 n_planes,
|
||||
const int *fds,
|
||||
const guint32 *strides,
|
||||
const guint32 *offsets,
|
||||
const guint64 *modifiers);
|
||||
|
||||
G_END_DECLS
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* mks-gl-context.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
# include <gdk/wayland/gdkwayland.h>
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
# include <gdk/x11/gdkx.h>
|
||||
#endif
|
||||
|
||||
#include "mks-gl-context-private.h"
|
||||
|
||||
GLuint
|
||||
mks_gl_context_import_dmabuf (GdkGLContext *context,
|
||||
guint32 format,
|
||||
guint width,
|
||||
guint height,
|
||||
guint32 n_planes,
|
||||
const int *fds,
|
||||
const guint32 *strides,
|
||||
const guint32 *offsets,
|
||||
const guint64 *modifiers)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
EGLDisplay egl_display;
|
||||
EGLint attribs[2 * (3 + 4 * 5) + 1];
|
||||
EGLImage image;
|
||||
guint texture_id;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), 0);
|
||||
g_return_val_if_fail (0 < n_planes && n_planes <= 4, 0);
|
||||
|
||||
display = gdk_gl_context_get_display (context);
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (display))
|
||||
egl_display = gdk_wayland_display_get_egl_display (display);
|
||||
else
|
||||
#endif
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
if (GDK_IS_X11_DISPLAY (display))
|
||||
egl_display = gdk_x11_display_get_egl_display (display);
|
||||
else
|
||||
#endif
|
||||
egl_display = NULL;
|
||||
|
||||
if (egl_display == NULL)
|
||||
{
|
||||
g_warning ("Can't import dmabufs when not using EGL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
attribs[i++] = EGL_WIDTH;
|
||||
attribs[i++] = width;
|
||||
attribs[i++] = EGL_HEIGHT;
|
||||
attribs[i++] = height;
|
||||
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[i++] = format;
|
||||
|
||||
if (n_planes > 0)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||
attribs[i++] = fds[0];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||
attribs[i++] = offsets[0];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||
attribs[i++] = strides[0];
|
||||
if (modifiers)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
||||
attribs[i++] = modifiers[0] & 0xFFFFFFFF;
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
||||
attribs[i++] = modifiers[0] >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_planes > 1)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
||||
attribs[i++] = fds[1];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
||||
attribs[i++] = offsets[1];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
||||
attribs[i++] = strides[1];
|
||||
if (modifiers)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
||||
attribs[i++] = modifiers[1] & 0xFFFFFFFF;
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
||||
attribs[i++] = modifiers[1] >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
if (n_planes > 2)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
||||
attribs[i++] = fds[2];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
||||
attribs[i++] = offsets[2];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
||||
attribs[i++] = strides[2];
|
||||
if (modifiers)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
||||
attribs[i++] = modifiers[2] & 0xFFFFFFFF;
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
||||
attribs[i++] = modifiers[2] >> 32;
|
||||
}
|
||||
}
|
||||
if (n_planes > 3)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE3_FD_EXT;
|
||||
attribs[i++] = fds[3];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
|
||||
attribs[i++] = offsets[3];
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
|
||||
attribs[i++] = strides[3];
|
||||
if (modifiers)
|
||||
{
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
|
||||
attribs[i++] = modifiers[3] & 0xFFFFFFFF;
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
|
||||
attribs[i++] = modifiers[3] >> 32;
|
||||
}
|
||||
}
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
image = eglCreateImageKHR (egl_display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT,
|
||||
(EGLClientBuffer)NULL,
|
||||
attribs);
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
g_warning ("Failed to create EGL image: %d\n", eglGetError ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, image);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
eglDestroyImageKHR (egl_display, image);
|
||||
|
||||
return texture_id;
|
||||
}
|
@ -29,7 +29,8 @@ G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE (MksPaintable, mks_paintable, MKS, PAINTABLE, GObject)
|
||||
|
||||
GdkPaintable *_mks_paintable_new (GCancellable *cancellable,
|
||||
GdkPaintable *_mks_paintable_new (GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
int *peer_fd,
|
||||
GError **error);
|
||||
GdkCursor *_mks_paintable_get_cursor (MksPaintable *self);
|
||||
|
@ -39,9 +39,9 @@
|
||||
struct _MksPaintable
|
||||
{
|
||||
GObject parent_instance;
|
||||
GdkGLContext *gl_context;
|
||||
MksQemuListener *listener;
|
||||
GDBusConnection *connection;
|
||||
GdkDisplay *display;
|
||||
GdkPaintable *child;
|
||||
GdkCursor *cursor;
|
||||
MksDmabufScanoutData *scanout_data;
|
||||
@ -155,23 +155,6 @@ paintable_iface_init (GdkPaintableInterface *iface)
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (MksPaintable, mks_paintable, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, paintable_iface_init))
|
||||
|
||||
static GdkGLContext *
|
||||
mks_paintable_get_gl_context (MksPaintable *self,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (MKS_IS_PAINTABLE (self));
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
{
|
||||
GdkDisplay *display = gdk_display_get_default ();
|
||||
|
||||
if (!(self->gl_context = gdk_display_create_gl_context (display, error)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return self->gl_context;
|
||||
}
|
||||
|
||||
static void
|
||||
mks_paintable_dispose (GObject *object)
|
||||
{
|
||||
@ -180,8 +163,8 @@ mks_paintable_dispose (GObject *object)
|
||||
g_clear_object (&self->connection);
|
||||
g_clear_object (&self->listener);
|
||||
g_clear_object (&self->child);
|
||||
g_clear_object (&self->gl_context);
|
||||
g_clear_object (&self->cursor);
|
||||
g_clear_object (&self->display);
|
||||
|
||||
G_OBJECT_CLASS (mks_paintable_parent_class)->dispose (object);
|
||||
}
|
||||
@ -396,7 +379,6 @@ mks_paintable_listener_update_dmabuf (MksPaintable *self,
|
||||
{
|
||||
cairo_region_t *region = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GdkGLContext *gl_context;
|
||||
|
||||
g_assert (MKS_IS_PAINTABLE (self));
|
||||
g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation));
|
||||
@ -409,9 +391,8 @@ mks_paintable_listener_update_dmabuf (MksPaintable *self,
|
||||
y = self->scanout_data->height - y - height;
|
||||
|
||||
region = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { x, y, width, height });
|
||||
if (!(gl_context = mks_paintable_get_gl_context (self, &error)) ||
|
||||
!mks_dmabuf_paintable_import (MKS_DMABUF_PAINTABLE (self->child),
|
||||
gl_context,
|
||||
if (!mks_dmabuf_paintable_import (MKS_DMABUF_PAINTABLE (self->child),
|
||||
self->display,
|
||||
self->scanout_data,
|
||||
region,
|
||||
&error))
|
||||
@ -705,7 +686,8 @@ mks_paintable_connection_cb (GObject *object,
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
_mks_paintable_new (GCancellable *cancellable,
|
||||
_mks_paintable_new (GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
int *peer_fd,
|
||||
GError **error)
|
||||
{
|
||||
@ -721,7 +703,7 @@ _mks_paintable_new (GCancellable *cancellable,
|
||||
*peer_fd = -1;
|
||||
|
||||
self = g_object_new (MKS_TYPE_PAINTABLE, NULL);
|
||||
|
||||
self->display = g_object_ref (display);
|
||||
/* Create a socketpair() to use for D-Bus P2P protocol. We will be receiving
|
||||
* DMA-BUF FDs over this.
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <glib/gstdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "mks-device-private.h"
|
||||
#include "mks-enums.h"
|
||||
@ -637,6 +638,7 @@ mks_screen_attach_cb (GObject *object,
|
||||
*/
|
||||
void
|
||||
mks_screen_attach (MksScreen *self,
|
||||
GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
@ -654,7 +656,7 @@ mks_screen_attach (MksScreen *self,
|
||||
g_task_set_source_tag (task, mks_screen_attach);
|
||||
|
||||
if (!check_console (self, &error) ||
|
||||
!(paintable = _mks_paintable_new (cancellable, &fd, &error)))
|
||||
!(paintable = _mks_paintable_new (display, cancellable, &fd, &error)))
|
||||
goto failure;
|
||||
|
||||
g_task_set_task_data (task, g_steal_pointer (&paintable), g_object_unref);
|
||||
@ -714,6 +716,7 @@ mks_screen_attach_finish (MksScreen *self,
|
||||
*/
|
||||
GdkPaintable *
|
||||
mks_screen_attach_sync (MksScreen *self,
|
||||
GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
@ -725,7 +728,7 @@ mks_screen_attach_sync (MksScreen *self,
|
||||
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
|
||||
if (!check_console (self, error) ||
|
||||
!(paintable = _mks_paintable_new (cancellable, &fd, error)))
|
||||
!(paintable = _mks_paintable_new (display, cancellable, &fd, error)))
|
||||
return NULL;
|
||||
|
||||
unix_fd_list = g_unix_fd_list_new_from_array (&fd, 1), fd = -1;
|
||||
|
@ -91,6 +91,7 @@ gboolean mks_screen_configure_sync (MksScreen *self,
|
||||
GError **error);
|
||||
MKS_AVAILABLE_IN_ALL
|
||||
void mks_screen_attach (MksScreen *self,
|
||||
GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
@ -100,6 +101,7 @@ GdkPaintable *mks_screen_attach_finish (MksScreen *self,
|
||||
GError **error);
|
||||
MKS_AVAILABLE_IN_ALL
|
||||
GdkPaintable *mks_screen_attach_sync (MksScreen *self,
|
||||
GdkDisplay *display,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
@ -23,7 +23,7 @@ add_project_arguments(['-I' + meson.project_build_root()], language: 'c')
|
||||
|
||||
# Check dependencies
|
||||
glib_req_version = '2.75.0'
|
||||
gtk_req_version = '4.11'
|
||||
gtk_req_version = '4.13'
|
||||
|
||||
glib_req = '>= @0@'.format(glib_req_version)
|
||||
gtk_req = '>= @0@'.format(gtk_req_version)
|
||||
@ -40,7 +40,6 @@ if gtk_minor % 2 == 1
|
||||
gtk_minor = gtk_minor + 1
|
||||
endif
|
||||
|
||||
libepoxy_dep = dependency('epoxy')
|
||||
libgio_dep = dependency('gio-2.0', version: glib_req)
|
||||
libgiounix_dep = dependency('gio-unix-2.0', version: glib_req)
|
||||
libgtk_dep = dependency('gtk4', version: gtk_req, fallback: ['gtk'])
|
||||
|
Loading…
Reference in New Issue
Block a user