Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b6f479375e |
@@ -1,67 +1,6 @@
|
||||
Overview of Changes in 4.13.3, 15-11-2023
|
||||
Overview of Changes in 4.13.2, xx-xx-xxxx
|
||||
=========================================
|
||||
|
||||
* GtkGraphicsOffload: A new widget to support passthrough
|
||||
of dmabuf textures with subsurfaces on Wayland
|
||||
|
||||
* GtkListView:
|
||||
- reduce tree indentation
|
||||
|
||||
* GtkInspector:
|
||||
- Show more GL information
|
||||
- Add a subsurface overlay
|
||||
- Improve the fps overlay
|
||||
|
||||
* GDK
|
||||
- Allow implicit modifiers for dmabufs
|
||||
- Support more dmabuf formats: NV16, NV61, NV24, NV42
|
||||
and 3-plane YUV formats
|
||||
|
||||
* GSK
|
||||
- Fix padding of icons in the GL atlas
|
||||
- Fix handling of texture-scale nodes in cairo
|
||||
- Treat texture-scale nodes more faithfully in GL
|
||||
|
||||
* Accessibility:
|
||||
- Tweak the accessible name computation for corner cases
|
||||
|
||||
* The GTK/GDK/GSK_DEBUG environment variables now
|
||||
work in productions as well as in debug builds
|
||||
|
||||
* Translation updates
|
||||
Catalan
|
||||
French
|
||||
Russian
|
||||
|
||||
|
||||
Overview of Changes in 4.13.2, 22-10-2023
|
||||
=========================================
|
||||
|
||||
* GtkPrintdialog:
|
||||
- New async-style api to replace GtkPrintOperation
|
||||
|
||||
* GtkEmojiChooser:
|
||||
- Add more languages: Bengali, Hindi, Japanese, Finnish,
|
||||
Thai and Norwegian bokmål
|
||||
|
||||
* Accessibility:
|
||||
- Fix some utf8 handling issues
|
||||
|
||||
* GDK:
|
||||
- Add support for dmabuf textures, with GdkDmabufTextureBuilder
|
||||
- Add a few more supported memory formats for textures
|
||||
|
||||
* GSK:
|
||||
- Add a fast-path for masking color
|
||||
- Add support for importing dmabuf textures
|
||||
- Handle GLES better by using some extensions
|
||||
|
||||
* Translation updates:
|
||||
Catalan
|
||||
Russian
|
||||
Turkish
|
||||
|
||||
|
||||
Overview of Changes in 4.13.1, 28-09-2023
|
||||
=========================================
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef _MSC_VER
|
||||
#pragma error "This header is for Microsoft VC or clang-cl only."
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* Make MSVC more pedantic, this is a recommended pragma list
|
||||
* from _Win32_Programming_ by Rector and Newcomer.
|
||||
*/
|
||||
#ifndef __clang__
|
||||
#pragma warning(error:4002) /* too many actual parameters for macro */
|
||||
#pragma warning(error:4003) /* not enough actual parameters for macro */
|
||||
#pragma warning(1:4010) /* single-line comment contains line-continuation character */
|
||||
#pragma warning(error:4013) /* 'function' undefined; assuming extern returning int */
|
||||
#pragma warning(1:4016) /* no function return type; using int as default */
|
||||
#pragma warning(error:4020) /* too many actual parameters */
|
||||
#pragma warning(error:4021) /* too few actual parameters */
|
||||
#pragma warning(error:4027) /* function declared without formal parameter list */
|
||||
#pragma warning(error:4029) /* declared formal parameter list different from definition */
|
||||
#pragma warning(error:4033) /* 'function' must return a value */
|
||||
#pragma warning(error:4035) /* 'function' : no return value */
|
||||
#pragma warning(error:4045) /* array bounds overflow */
|
||||
#pragma warning(error:4047) /* different levels of indirection */
|
||||
#pragma warning(error:4049) /* terminating line number emission */
|
||||
#pragma warning(error:4053) /* An expression of type void was used as an operand */
|
||||
#pragma warning(error:4071) /* no function prototype given */
|
||||
#pragma warning(disable:4101) /* unreferenced local variable */
|
||||
#pragma warning(error:4150)
|
||||
|
||||
/* G_NORETURN */
|
||||
#pragma warning(error:4646) /* function declared with __declspec(noreturn) has non-void return type */
|
||||
#pragma warning(error:4715) /* 'function': not all control paths return a value */
|
||||
#pragma warning(error:4098) /* 'void' function returning a value */
|
||||
|
||||
#pragma warning(disable:4244) /* No possible loss of data warnings */
|
||||
#pragma warning(disable:4305) /* No truncation from int to char warnings */
|
||||
|
||||
#pragma warning(error:4819) /* The file contains a character that cannot be represented in the current code page */
|
||||
#endif /* __clang__ */
|
||||
|
||||
/* work around Microsoft's premature attempt to deprecate the C-Library */
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_NONSTDC_NO_WARNINGS
|
||||
@@ -75,9 +75,7 @@ query_tooltip (GtkWidget *widget,
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
|
||||
|
||||
precision = 1;
|
||||
s = NULL;
|
||||
do {
|
||||
g_free (s);
|
||||
s = g_strdup_printf ("%.*f", precision, self->scale);
|
||||
l = strlen (s) - 1;
|
||||
while (s[l] == '0')
|
||||
|
||||
@@ -139,7 +139,6 @@ do_video_player (GtkWidget *do_widget)
|
||||
|
||||
video = gtk_video_new ();
|
||||
gtk_video_set_autoplay (GTK_VIDEO (video), TRUE);
|
||||
gtk_video_set_graphics_offload (GTK_VIDEO (video), GTK_GRAPHICS_OFFLOAD_ENABLED);
|
||||
gtk_window_set_child (GTK_WINDOW (window), video);
|
||||
|
||||
title = gtk_header_bar_new ();
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 533 B |
Binary file not shown.
|
After Width: | Height: | Size: 127 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M3.384 3h3.231c.213 0 .385.224.385.502v2.996C7 6.776 6.828 7 6.615 7h-3.23C3.17 7 3 6.776 3 6.498V3.502C3 3.224 3.17 3 3.384 3zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 7 9 6.776 9 6.498V3.502C9 3.224 9.17 3 9.384 3zm-6 6h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C3.17 13 3 12.776 3 12.498V9.502C3 9.224 3.17 9 3.384 9zm6 0h3.231c.213 0 .385.224.385.502v2.996c0 .278-.172.502-.385.502h-3.23C9.17 13 9 12.776 9 12.498V9.502C9 9.224 9.17 9 9.384 9z" style="marker:none" overflow="visible" color="#000" fill="#474747"/></svg>
|
||||
|
After Width: | Height: | Size: 654 B |
@@ -25,12 +25,14 @@
|
||||
<file>icons/16x16/actions/format-justify-fill-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-left-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/format-justify-right-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/insert-image.png</file>
|
||||
<file>icons/16x16/actions/insert-link-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/send-to-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/star-new-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-continuous-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-dual-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-grid-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-paged-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/zoom-in-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/zoom-in.png</file>
|
||||
@@ -86,6 +88,7 @@
|
||||
<file>icons/scalable/actions/view-dual-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-paged-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-fullscreen-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/view-grid-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-in-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-original-symbolic.svg</file>
|
||||
<file>icons/scalable/actions/zoom-out-symbolic.svg</file>
|
||||
|
||||
@@ -41,7 +41,7 @@ activate (GtkApplication* app,
|
||||
window = gtk_application_window_new (app);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Window");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -183,7 +183,7 @@ activate (GtkApplication *app,
|
||||
|
||||
gtk_box_append (GTK_BOX (box), button);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -331,7 +331,8 @@ activate (GtkApplication *app,
|
||||
*/
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 2, 1);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_widget_show (window);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
@@ -553,7 +554,7 @@ activate (GtkApplication *app,
|
||||
|
||||
g_signal_connect (press, "pressed", G_CALLBACK (pressed), drawing_area);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -630,7 +631,7 @@ activate (GtkApplication *app,
|
||||
button = gtk_builder_get_object (builder, "quit");
|
||||
g_signal_connect_swapped (button, "clicked", G_CALLBACK (quit_cb), window);
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (window), TRUE);
|
||||
gtk_widget_show (GTK_WIDGET (window));
|
||||
|
||||
/* We do not need the builder any more */
|
||||
g_object_unref (builder);
|
||||
|
||||
@@ -35,11 +35,6 @@ Showing
|
||||
|
||||
The ``show`` command displays the rendernode.
|
||||
|
||||
``--undecorated``
|
||||
|
||||
Removes window decorations. This is meant for rendering of exactly the rendernode
|
||||
without any titlebar.
|
||||
|
||||
Rendering
|
||||
^^^^^^^^^
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ main (int argc, char **argv)
|
||||
// ...
|
||||
|
||||
// Show the application window
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
gtk_widget_show (window);
|
||||
|
||||
// Enter the main event loop, and wait for user interaction
|
||||
while (!done)
|
||||
|
||||
@@ -206,9 +206,6 @@ are only available when GTK has been configured with `-Ddebug=true`.
|
||||
`dmabuf`
|
||||
: Information about dmabuf handling (Linux-only)
|
||||
|
||||
`offload`
|
||||
: Information about subsurfaces and graphics offload (Wayland-only)
|
||||
|
||||
A number of options affect behavior instead of logging:
|
||||
|
||||
`nograbs`
|
||||
@@ -309,9 +306,6 @@ A number of options affect behavior instead of logging:
|
||||
`sync`
|
||||
: Sync after each frame
|
||||
|
||||
`offload-disable`
|
||||
: Disable graphics offload to subsurfaces
|
||||
|
||||
`vulkan-staging-image`
|
||||
: Use a staging image for Vulkan texture upload
|
||||
|
||||
|
||||
@@ -209,11 +209,13 @@ _gdk_broadway_roundtrip_notify (GdkSurface *surface,
|
||||
timings->complete = TRUE;
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,12 +369,14 @@ portal_file_serializer (GdkContentSerializer *serializer)
|
||||
GDK_DEBUG (DND, "file transfer portal: Adding %s", g_file_peek_path (file));
|
||||
g_ptr_array_add (files, g_file_get_path (file));
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
else if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *uri = g_file_get_uri (file);
|
||||
gdk_debug_message ("file transfer portal: %s has no path, dropping\n", uri);
|
||||
g_free (uri);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_ptr_array_add (files, NULL);
|
||||
}
|
||||
@@ -424,12 +426,14 @@ portal_finish (GObject *object,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
{
|
||||
char *s = g_strjoinv (", ", files);
|
||||
gdk_debug_message ("file transfer portal: Receiving files: %s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
value = gdk_content_deserializer_get_value (deserializer);
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_FILE))
|
||||
|
||||
@@ -118,25 +118,24 @@ static const GdkDebugKey gdk_debug_keys[] = {
|
||||
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
|
||||
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
|
||||
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
|
||||
{ "offload", GDK_DEBUG_OFFLOAD, "Information about subsurfaces and graphics offload" },
|
||||
|
||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)" },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals" },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals" },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
|
||||
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)" },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL" },
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context" },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API" },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows" },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11" },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows" },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support" },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer" },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings" },
|
||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible" },
|
||||
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)" },
|
||||
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support" },
|
||||
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)", TRUE },
|
||||
{ "portals", GDK_DEBUG_PORTALS, "Force use of portals", TRUE },
|
||||
{ "no-portals", GDK_DEBUG_NO_PORTALS, "Disable use of portals", TRUE },
|
||||
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support", TRUE },
|
||||
{ "gl-fractional", GDK_DEBUG_GL_FRACTIONAL, "Enable fractional scaling for OpenGL (experimental)", TRUE },
|
||||
{ "gl-debug", GDK_DEBUG_GL_DEBUG, "Insert debugging information in OpenGL", TRUE },
|
||||
{ "gl-legacy", GDK_DEBUG_GL_LEGACY, "Use a legacy OpenGL context", TRUE },
|
||||
{ "gl-gles", GDK_DEBUG_GL_GLES, "Only allow OpenGL GLES API", TRUE },
|
||||
{ "gl-egl", GDK_DEBUG_GL_EGL, "Use EGL on X11 or Windows", TRUE },
|
||||
{ "gl-glx", GDK_DEBUG_GL_GLX, "Use GLX on X11", TRUE },
|
||||
{ "gl-wgl", GDK_DEBUG_GL_WGL, "Use WGL on Windows", TRUE },
|
||||
{ "vulkan-disable", GDK_DEBUG_VULKAN_DISABLE, "Disable Vulkan support", TRUE },
|
||||
{ "vulkan-validate", GDK_DEBUG_VULKAN_VALIDATE, "Load the Vulkan validation layer", TRUE },
|
||||
{ "default-settings",GDK_DEBUG_DEFAULT_SETTINGS, "Force default values for xsettings", TRUE },
|
||||
{ "high-depth", GDK_DEBUG_HIGH_DEPTH, "Use high bit depth rendering if possible", TRUE },
|
||||
{ "no-vsync", GDK_DEBUG_NO_VSYNC, "Repaint instantly (uses 100% CPU with animations)", TRUE },
|
||||
{ "dmabuf-disable", GDK_DEBUG_DMABUF_DISABLE, "Disable dmabuf support", TRUE },
|
||||
};
|
||||
|
||||
|
||||
@@ -197,6 +196,13 @@ gdk_parse_debug_var (const char *variable,
|
||||
const char *q;
|
||||
gboolean invert;
|
||||
gboolean help;
|
||||
gboolean debug_enabled;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
debug_enabled = TRUE;
|
||||
#else
|
||||
debug_enabled = FALSE;
|
||||
#endif
|
||||
|
||||
string = g_getenv (variable);
|
||||
if (string == NULL)
|
||||
@@ -228,6 +234,12 @@ gdk_parse_debug_var (const char *variable,
|
||||
if (strlen (keys[i].key) == q - p &&
|
||||
g_ascii_strncasecmp (keys[i].key, p, q - p) == 0)
|
||||
{
|
||||
if (!debug_enabled && !keys[i].always_enabled)
|
||||
{
|
||||
fprintf (stderr, "\"%s\" is only available when building GTK with G_ENABLE_DEBUG. See %s=help\n",
|
||||
val, variable);
|
||||
break;
|
||||
}
|
||||
result |= keys[i].value;
|
||||
break;
|
||||
}
|
||||
@@ -251,7 +263,8 @@ gdk_parse_debug_var (const char *variable,
|
||||
|
||||
fprintf (stderr, "Supported %s values:\n", variable);
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
||||
if (debug_enabled || keys[i].always_enabled)
|
||||
fprintf (stderr, " %s%*s%s\n", keys[i].key, (int)(max_width - strlen (keys[i].key)), " ", keys[i].help);
|
||||
}
|
||||
fprintf (stderr, " %s%*s%s\n", "all", max_width - 3, " ", "Enable all values. Other given values are subtracted");
|
||||
fprintf (stderr, " %s%*s%s\n", "help", max_width - 4, " ", "Print this help");
|
||||
@@ -264,7 +277,8 @@ gdk_parse_debug_var (const char *variable,
|
||||
|
||||
for (i = 0; i < nkeys; i++)
|
||||
{
|
||||
all_flags |= keys[i].value;
|
||||
if (debug_enabled || keys[i].always_enabled)
|
||||
all_flags |= keys[i].value;
|
||||
}
|
||||
|
||||
result = all_flags & (~result);
|
||||
|
||||
+29
-33
@@ -37,26 +37,25 @@ typedef enum {
|
||||
GDK_DEBUG_SELECTION = 1 << 9,
|
||||
GDK_DEBUG_CLIPBOARD = 1 << 10,
|
||||
GDK_DEBUG_DMABUF = 1 << 11,
|
||||
GDK_DEBUG_OFFLOAD = 1 << 12,
|
||||
|
||||
/* flags below are influencing behavior */
|
||||
GDK_DEBUG_NOGRABS = 1 << 13,
|
||||
GDK_DEBUG_PORTALS = 1 << 14,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 15,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 16,
|
||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 17,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 18,
|
||||
GDK_DEBUG_GL_GLES = 1 << 19,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 20,
|
||||
GDK_DEBUG_GL_EGL = 1 << 21,
|
||||
GDK_DEBUG_GL_GLX = 1 << 22,
|
||||
GDK_DEBUG_GL_WGL = 1 << 23,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 24,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 25,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 26,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 27,
|
||||
GDK_DEBUG_NO_VSYNC = 1 << 28,
|
||||
GDK_DEBUG_DMABUF_DISABLE = 1 << 29,
|
||||
GDK_DEBUG_NOGRABS = 1 << 12,
|
||||
GDK_DEBUG_PORTALS = 1 << 13,
|
||||
GDK_DEBUG_NO_PORTALS = 1 << 14,
|
||||
GDK_DEBUG_GL_DISABLE = 1 << 15,
|
||||
GDK_DEBUG_GL_FRACTIONAL = 1 << 16,
|
||||
GDK_DEBUG_GL_LEGACY = 1 << 17,
|
||||
GDK_DEBUG_GL_GLES = 1 << 18,
|
||||
GDK_DEBUG_GL_DEBUG = 1 << 19,
|
||||
GDK_DEBUG_GL_EGL = 1 << 20,
|
||||
GDK_DEBUG_GL_GLX = 1 << 21,
|
||||
GDK_DEBUG_GL_WGL = 1 << 22,
|
||||
GDK_DEBUG_VULKAN_DISABLE = 1 << 23,
|
||||
GDK_DEBUG_VULKAN_VALIDATE = 1 << 24,
|
||||
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 25,
|
||||
GDK_DEBUG_HIGH_DEPTH = 1 << 26,
|
||||
GDK_DEBUG_NO_VSYNC = 1 << 27,
|
||||
GDK_DEBUG_DMABUF_DISABLE = 1 << 28,
|
||||
} GdkDebugFlags;
|
||||
|
||||
extern guint _gdk_debug_flags;
|
||||
@@ -65,24 +64,13 @@ GdkDebugFlags gdk_display_get_debug_flags (GdkDisplay *display);
|
||||
void gdk_display_set_debug_flags (GdkDisplay *display,
|
||||
GdkDebugFlags flags);
|
||||
|
||||
static inline void
|
||||
gdk_debug_message (const char *format, ...) G_GNUC_PRINTF(1, 2);
|
||||
static inline void
|
||||
gdk_debug_message (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char *s;
|
||||
|
||||
va_start (args, format);
|
||||
s = g_strdup_vprintf (format, args);
|
||||
va_end (args);
|
||||
#ifdef GLIB_USING_SYSTEM_PRINTF
|
||||
fprintf (stderr, "%s\n", s);
|
||||
#define gdk_debug_message(format, ...) fprintf (stderr, format "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
g_fprintf (stderr, "%s\n", s);
|
||||
#define gdk_debug_message(format, ...) g_fprintf (stderr, format "\n", ##__VA_ARGS__)
|
||||
#endif
|
||||
g_free (s);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
#define GDK_DISPLAY_DEBUG_CHECK(display,type) \
|
||||
G_UNLIKELY (gdk_display_get_debug_flags (display) & GDK_DEBUG_##type)
|
||||
@@ -93,6 +81,13 @@ gdk_debug_message (const char *format, ...)
|
||||
gdk_debug_message (__VA_ARGS__); \
|
||||
} G_STMT_END
|
||||
|
||||
#else /* !G_ENABLE_DEBUG */
|
||||
|
||||
#define GDK_DISPLAY_DEBUG_CHECK(display,type) 0
|
||||
#define GDK_DISPLAY_DEBUG(display,type,...)
|
||||
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#define GDK_DEBUG_CHECK(type) GDK_DISPLAY_DEBUG_CHECK (NULL,type)
|
||||
#define GDK_DEBUG(type,...) GDK_DISPLAY_DEBUG (NULL,type,__VA_ARGS__)
|
||||
|
||||
@@ -101,6 +96,7 @@ typedef struct
|
||||
const char *key;
|
||||
guint value;
|
||||
const char *help;
|
||||
gboolean always_enabled;
|
||||
} GdkDebugKey;
|
||||
|
||||
guint gdk_parse_debug_var (const char *variable,
|
||||
|
||||
+9
-31
@@ -391,10 +391,6 @@ gdk_display_dispose (GObject *object)
|
||||
|
||||
g_queue_clear (&display->queued_events);
|
||||
|
||||
g_clear_object (&display->egl_gsk_renderer);
|
||||
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
|
||||
|
||||
g_clear_object (&priv->gl_context);
|
||||
#ifdef HAVE_EGL
|
||||
g_clear_pointer (&priv->egl_display, eglTerminate);
|
||||
@@ -1428,6 +1424,7 @@ gdk_display_get_gl_context (GdkDisplay *self)
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static int
|
||||
strvcmp (gconstpointer p1,
|
||||
gconstpointer p2)
|
||||
@@ -1484,6 +1481,7 @@ describe_egl_config (EGLDisplay egl_display,
|
||||
|
||||
return g_strdup_printf ("R%dG%dB%dA%d%s", red, green, blue, alpha, type == EGL_COLOR_COMPONENT_TYPE_FIXED_EXT ? "" : " float");
|
||||
}
|
||||
#endif
|
||||
|
||||
gpointer
|
||||
gdk_display_get_egl_config (GdkDisplay *self)
|
||||
@@ -1772,10 +1770,6 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
|
||||
self->have_egl_pixel_format_float =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
|
||||
self->have_egl_dma_buf_import =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
|
||||
self->have_egl_dma_buf_export =
|
||||
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
|
||||
|
||||
if (self->have_egl_no_config_context)
|
||||
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
|
||||
@@ -1784,6 +1778,7 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
if (priv->egl_config_high_depth == NULL)
|
||||
priv->egl_config_high_depth = priv->egl_config;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (self, OPENGL))
|
||||
{
|
||||
char *ext = describe_extensions (priv->egl_display);
|
||||
@@ -1807,6 +1802,7 @@ gdk_display_init_egl (GdkDisplay *self,
|
||||
g_free (std_cfg);
|
||||
g_free (ext);
|
||||
}
|
||||
#endif
|
||||
|
||||
gdk_profiler_end_mark (start_time, "init EGL", NULL);
|
||||
|
||||
@@ -1843,7 +1839,7 @@ gdk_display_get_egl_display (GdkDisplay *self)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
static void
|
||||
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
|
||||
const GdkDmabufDownloader *downloader,
|
||||
@@ -1851,8 +1847,7 @@ gdk_display_add_dmabuf_downloader (GdkDisplay *display,
|
||||
{
|
||||
gsize i;
|
||||
|
||||
if (!downloader->add_formats (downloader, display, builder))
|
||||
return;
|
||||
downloader->add_formats (downloader, display, builder);
|
||||
|
||||
/* dmabuf_downloaders is NULL-terminated */
|
||||
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
|
||||
@@ -1879,31 +1874,19 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
||||
if (self->dmabuf_formats != NULL)
|
||||
return;
|
||||
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Beginning initialization of dmabuf support");
|
||||
|
||||
builder = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
if (!GDK_DISPLAY_DEBUG_CHECK (self, DMABUF_DISABLE))
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
|
||||
{
|
||||
gdk_display_prepare_gl (self, NULL);
|
||||
|
||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (gdk_display_prepare_gl (self, NULL))
|
||||
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
|
||||
|
||||
GDK_DISPLAY_DEBUG (self, DMABUF,
|
||||
"Initialized support for %zu dmabuf formats",
|
||||
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_display_get_dmabuf_formats:
|
||||
@@ -1914,11 +1897,6 @@ gdk_display_init_dmabuf (GdkDisplay *self)
|
||||
* GTK may use OpenGL or Vulkan to support some formats.
|
||||
* Calling this function will then initialize them if they aren't yet.
|
||||
*
|
||||
* The formats returned by this function can be used for negotiating
|
||||
* buffer formats with producers such as v4l, pipewire or GStreamer.
|
||||
*
|
||||
* To learn more about dma-bufs, see [class@Gdk.DmabufTextureBuilder].
|
||||
*
|
||||
* Returns: (transfer none): a `GdkDmabufFormats` object
|
||||
*
|
||||
* Since: 4.14
|
||||
|
||||
@@ -114,16 +114,9 @@ struct _GdkDisplay
|
||||
guint have_egl_buffer_age : 1;
|
||||
guint have_egl_no_config_context : 1;
|
||||
guint have_egl_pixel_format_float : 1;
|
||||
guint have_egl_dma_buf_import : 1;
|
||||
guint have_egl_dma_buf_export : 1;
|
||||
|
||||
GdkDmabufFormats *dmabuf_formats;
|
||||
const GdkDmabufDownloader *dmabuf_downloaders[4];
|
||||
|
||||
/* Cached data the EGL dmabuf downloader */
|
||||
gpointer egl_gsk_renderer;
|
||||
GdkDmabufFormats *egl_dmabuf_formats;
|
||||
GdkDmabufFormats *egl_external_formats;
|
||||
};
|
||||
|
||||
struct _GdkDisplayClass
|
||||
|
||||
+127
-281
@@ -24,11 +24,11 @@
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
|
||||
@@ -133,31 +133,15 @@ download_nv12 (guchar *dst_data,
|
||||
{
|
||||
const guchar *y_data, *uv_data;
|
||||
gsize x, y, y_stride, uv_stride;
|
||||
gsize U, V, X_SUB, Y_SUB;
|
||||
gsize U, V;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
if (dmabuf->fourcc == DRM_FORMAT_NV21)
|
||||
{
|
||||
case DRM_FORMAT_NV12:
|
||||
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_NV21:
|
||||
U = 1; V = 0; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_NV16:
|
||||
U = 0; V = 1; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_NV61:
|
||||
U = 1; V = 0; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_NV24:
|
||||
U = 0; V = 1; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_NV42:
|
||||
U = 1; V = 0; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
U = 1; V = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
U = 0; V = 1;
|
||||
}
|
||||
|
||||
y_stride = dmabuf->planes[0].stride;
|
||||
@@ -165,108 +149,35 @@ download_nv12 (guchar *dst_data,
|
||||
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
|
||||
uv_stride = dmabuf->planes[1].stride;
|
||||
uv_data = src_data[1] + dmabuf->planes[1].offset;
|
||||
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * uv_stride);
|
||||
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + 1) / 2 * uv_stride);
|
||||
|
||||
for (y = 0; y < height; y += Y_SUB)
|
||||
for (y = 0; y < height; y += 2)
|
||||
{
|
||||
for (x = 0; x < width; x += X_SUB)
|
||||
guchar *dst2_data = dst_data + dst_stride;
|
||||
const guchar *y2_data = y_data + y_stride;
|
||||
|
||||
for (x = 0; x < width; x += 2)
|
||||
{
|
||||
int r, g, b;
|
||||
gsize xs, ys;
|
||||
|
||||
get_uv_values (&itu601_wide, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b);
|
||||
get_uv_values (&itu601_wide, uv_data[x + U], uv_data[x + V], &r, &g, &b);
|
||||
|
||||
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
|
||||
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
|
||||
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
|
||||
set_rgb_values (&dst_data[3 * x], y_data[x], r, g, b);
|
||||
if (x + 1 < width)
|
||||
set_rgb_values (&dst_data[3 * (x + 1)], y_data[x], r, g, b);
|
||||
if (y + 1 < height)
|
||||
{
|
||||
set_rgb_values (&dst2_data[3 * x], y2_data[x], r, g, b);
|
||||
if (x + 1 < width)
|
||||
set_rgb_values (&dst2_data[3 * (x + 1)], y2_data[x], r, g, b);
|
||||
}
|
||||
}
|
||||
dst_data += Y_SUB * dst_stride;
|
||||
y_data += Y_SUB * y_stride;
|
||||
dst_data += 2 * dst_stride;
|
||||
y_data += 2 * y_stride;
|
||||
uv_data += uv_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
download_yuv_3 (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
GdkMemoryFormat dst_format,
|
||||
gsize width,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
{
|
||||
const guchar *y_data, *u_data, *v_data;
|
||||
gsize x, y, y_stride, u_stride, v_stride;
|
||||
gsize U, V, X_SUB, Y_SUB;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
{
|
||||
case DRM_FORMAT_YUV410:
|
||||
U = 1; V = 2; X_SUB = 4; Y_SUB = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YVU410:
|
||||
U = 2; V = 1; X_SUB = 4; Y_SUB = 4;
|
||||
break;
|
||||
case DRM_FORMAT_YUV411:
|
||||
U = 1; V = 2; X_SUB = 4; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU411:
|
||||
U = 2; V = 1; X_SUB = 4; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YUV420:
|
||||
U = 1; V = 2; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YVU420:
|
||||
U = 2; V = 1; X_SUB = 2; Y_SUB = 2;
|
||||
break;
|
||||
case DRM_FORMAT_YUV422:
|
||||
U = 1; V = 2; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU422:
|
||||
U = 2; V = 1; X_SUB = 2; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YUV444:
|
||||
U = 1; V = 2; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
case DRM_FORMAT_YVU444:
|
||||
U = 2; V = 1; X_SUB = 1; Y_SUB = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
y_stride = dmabuf->planes[0].stride;
|
||||
y_data = src_data[0] + dmabuf->planes[0].offset;
|
||||
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
|
||||
u_stride = dmabuf->planes[U].stride;
|
||||
u_data = src_data[U] + dmabuf->planes[U].offset;
|
||||
g_return_if_fail (sizes[U] >= dmabuf->planes[U].offset + (height + Y_SUB - 1) / Y_SUB * u_stride);
|
||||
v_stride = dmabuf->planes[V].stride;
|
||||
v_data = src_data[V] + dmabuf->planes[V].offset;
|
||||
g_return_if_fail (sizes[V] >= dmabuf->planes[V].offset + (height + Y_SUB - 1) / Y_SUB * v_stride);
|
||||
|
||||
for (y = 0; y < height; y += Y_SUB)
|
||||
{
|
||||
for (x = 0; x < width; x += X_SUB)
|
||||
{
|
||||
int r, g, b;
|
||||
gsize xs, ys;
|
||||
|
||||
get_uv_values (&itu601_wide, u_data[x / X_SUB], v_data[x / X_SUB], &r, &g, &b);
|
||||
|
||||
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
|
||||
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
|
||||
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
|
||||
}
|
||||
dst_data += Y_SUB * dst_stride;
|
||||
y_data += Y_SUB * y_stride;
|
||||
u_data += u_stride;
|
||||
v_data += v_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
download_yuyv (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
@@ -335,24 +246,10 @@ static const GdkDrmFormatInfo supported_formats[] = {
|
||||
/* YUV formats */
|
||||
{ DRM_FORMAT_NV12, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_NV21, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_NV16, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_NV61, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_NV24, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_NV42, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
|
||||
{ DRM_FORMAT_YUYV, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_YVYU, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_VYUY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_UYVY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
|
||||
{ DRM_FORMAT_YUV410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YUV444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
{ DRM_FORMAT_YVU444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
|
||||
};
|
||||
|
||||
static const GdkDrmFormatInfo *
|
||||
@@ -367,25 +264,7 @@ get_drm_format_info (guint32 fourcc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkMemoryFormat
|
||||
gdk_dmabuf_get_memory_format (GdkDisplay *display,
|
||||
guint32 fourcc,
|
||||
gboolean premultiplied)
|
||||
{
|
||||
const GdkDrmFormatInfo *info = get_drm_format_info (fourcc);
|
||||
|
||||
if (info)
|
||||
return premultiplied ? info->premultiplied_memory_format
|
||||
: info->unpremultiplied_memory_format;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Falling back to generic ARGB for dmabuf format %.4s", (char *)&fourcc);
|
||||
|
||||
return premultiplied ? GDK_MEMORY_A8R8G8B8_PREMULTIPLIED
|
||||
: GDK_MEMORY_A8R8G8B8;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder)
|
||||
@@ -394,17 +273,10 @@ gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
downloader->name,
|
||||
(char *) &supported_formats[i].fourcc, (guint64) DRM_FORMAT_MOD_LINEAR);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (builder,
|
||||
supported_formats[i].fourcc,
|
||||
DRM_FORMAT_MOD_LINEAR);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -416,6 +288,7 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
GError **error)
|
||||
{
|
||||
const GdkDrmFormatInfo *info;
|
||||
char buf[36];
|
||||
|
||||
info = get_drm_format_info (dmabuf->fourcc);
|
||||
|
||||
@@ -423,8 +296,8 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
{
|
||||
g_set_error (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
"Unsupported dmabuf format %.4s",
|
||||
(char *) &dmabuf->fourcc);
|
||||
"Unsupported dmabuf format %s",
|
||||
gdk_dmabuf_fourcc_print (buf, sizeof (buf), dmabuf->fourcc));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -432,8 +305,8 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
{
|
||||
g_set_error (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
"Unsupported dmabuf modifier %#lx (only linear buffers are supported)",
|
||||
dmabuf->modifier);
|
||||
"Unsupported dmabuf modifier %s (only linear buffers are supported)",
|
||||
gdk_dmabuf_modifier_print (buf, sizeof (buf), dmabuf->modifier));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -444,10 +317,9 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
|
||||
GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
gdk_dmabuf_direct_downloader_do_download (GdkTexture *texture,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
const GdkDrmFormatInfo *info;
|
||||
const GdkDmabuf *dmabuf;
|
||||
@@ -455,13 +327,14 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES];
|
||||
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
|
||||
gsize i, j;
|
||||
gchar buf[64];
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
info = get_drm_format_info (dmabuf->fourcc);
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (texture)), DMABUF,
|
||||
"Using %s for downloading a dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier);
|
||||
GDK_DEBUG (DMABUF,
|
||||
"Using mmap() and memcpy() for downloading a dmabuf (format %s)",
|
||||
gdk_dmabuf_format_print (buf, sizeof (buf), dmabuf->fourcc, dmabuf->modifier));
|
||||
|
||||
for (i = 0; i < dmabuf->n_planes; i++)
|
||||
{
|
||||
@@ -483,8 +356,6 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
|
||||
g_warning ("Failed to seek dmabuf: %s", g_strerror (errno));
|
||||
goto out;
|
||||
}
|
||||
/* be a good citizen and seek back to the start, as the dos recommend */
|
||||
lseek (dmabuf->planes[i].fd, 0, SEEK_SET);
|
||||
|
||||
if (ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
|
||||
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
|
||||
@@ -530,7 +401,7 @@ gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader,
|
||||
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
|
||||
|
||||
if (format == src_format)
|
||||
gdk_dmabuf_direct_downloader_do_download (downloader, texture, data, stride);
|
||||
gdk_dmabuf_direct_downloader_do_download (texture, data, stride);
|
||||
else
|
||||
{
|
||||
unsigned int width, height;
|
||||
@@ -543,7 +414,7 @@ gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader,
|
||||
src_stride = width * gdk_memory_format_bytes_per_pixel (src_format);
|
||||
src_data = g_new (guchar, src_stride * height);
|
||||
|
||||
gdk_dmabuf_direct_downloader_do_download (downloader, texture, src_data, src_stride);
|
||||
gdk_dmabuf_direct_downloader_do_download (texture, src_data, src_stride);
|
||||
|
||||
gdk_memory_convert (data, stride, format,
|
||||
src_data, src_stride, src_format,
|
||||
@@ -576,13 +447,15 @@ gdk_dmabuf_get_direct_downloader (void)
|
||||
* controlled by the callers.
|
||||
*
|
||||
* Things we do here:
|
||||
*
|
||||
*
|
||||
* 1. Disallow any dmabuf format that we do not know.
|
||||
*
|
||||
* 2. Ignore non-linear modifiers.
|
||||
* 1. Treat the INVALID modifier the same as LINEAR.
|
||||
*
|
||||
* 3. Try and fix various inconsistencies between V4L and Mesa
|
||||
* for linear modifiers, like the e.g. single-plane NV12.
|
||||
* 2. Ignore all other modifiers.
|
||||
*
|
||||
* 3. Try and fix various inconsistencies between V4L and Mesa,
|
||||
* like NV12.
|
||||
*
|
||||
* *** WARNING ***
|
||||
*
|
||||
@@ -624,15 +497,12 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
|
||||
*dest = *src;
|
||||
|
||||
if (src->modifier)
|
||||
if (src->modifier && src->modifier != DRM_FORMAT_MOD_INVALID)
|
||||
return TRUE;
|
||||
|
||||
switch (dest->fourcc)
|
||||
{
|
||||
case DRM_FORMAT_NV12:
|
||||
case DRM_FORMAT_NV21:
|
||||
case DRM_FORMAT_NV16:
|
||||
case DRM_FORMAT_NV61:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 2;
|
||||
@@ -642,87 +512,6 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_NV24:
|
||||
case DRM_FORMAT_NV42:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 2;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = dest->planes[0].stride * 2;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV410:
|
||||
case DRM_FORMAT_YVU410:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 3) / 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV411:
|
||||
case DRM_FORMAT_YVU411:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV420:
|
||||
case DRM_FORMAT_YVU420:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 1) / 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV422:
|
||||
case DRM_FORMAT_YVU422:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
case DRM_FORMAT_YUV444:
|
||||
case DRM_FORMAT_YVU444:
|
||||
if (dest->n_planes == 1)
|
||||
{
|
||||
dest->n_planes = 3;
|
||||
dest->planes[1].fd = dest->planes[0].fd;
|
||||
dest->planes[1].stride = dest->planes[0].stride;
|
||||
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
|
||||
dest->planes[2].fd = dest->planes[1].fd;
|
||||
dest->planes[2].stride = dest->planes[1].stride;
|
||||
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -730,27 +519,84 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_dmabuf_is_disjoint:
|
||||
* @dmabuf: a sanitized GdkDmabuf
|
||||
*
|
||||
* A dmabuf is considered disjoint if it uses more than
|
||||
* 1 file descriptor.
|
||||
*
|
||||
* Returns: %TRUE if the dmabuf is disjoint
|
||||
**/
|
||||
gboolean
|
||||
gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
|
||||
const char *
|
||||
gdk_dmabuf_fourcc_print (char *buf,
|
||||
gsize size,
|
||||
guint32 fourcc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < dmabuf->n_planes; i++)
|
||||
{
|
||||
if (dmabuf->planes[0].fd != dmabuf->planes[i].fd)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
snprintf (buf, size, "%.4s", (char *)&fourcc);
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DMABUF */
|
||||
static const char *
|
||||
get_modifier_name (char *buf,
|
||||
gsize size,
|
||||
guint64 modifier)
|
||||
{
|
||||
static struct {
|
||||
guchar id;
|
||||
const char *name;
|
||||
} vendors[] = {
|
||||
{ DRM_FORMAT_MOD_VENDOR_NONE, "NONE" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_INTEL, "Intel" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_AMD, "AMD" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_NVIDIA, "NVidia" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_SAMSUNG, "Samsung" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_QCOM, "Qualcomm" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_VIVANTE, "Vivante" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_BROADCOM, "Broadcom" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_ARM, "Arm" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_ALLWINNER, "Allwinner" },
|
||||
{ DRM_FORMAT_MOD_VENDOR_AMLOGIC, "Amlogic" },
|
||||
};
|
||||
|
||||
if (modifier == DRM_FORMAT_MOD_INVALID)
|
||||
return "INVALID";
|
||||
else if (modifier == DRM_FORMAT_MOD_LINEAR)
|
||||
return "LINEAR";
|
||||
|
||||
for (int i = 0; i < G_N_ELEMENTS (vendors); i++)
|
||||
{
|
||||
if (vendors[i].id == fourcc_mod_get_vendor (modifier))
|
||||
{
|
||||
snprintf (buf, size, "%s,%" G_GINT64_MODIFIER "u", vendors[i].name, modifier & 0x00ffffffffffffffUL);
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf (buf, size, "%#" G_GINT64_MODIFIER "x", modifier);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
gdk_dmabuf_modifier_print (char *buf,
|
||||
gsize size,
|
||||
guint64 modifier)
|
||||
{
|
||||
char buf2[64];
|
||||
|
||||
snprintf (buf, size, "%s", get_modifier_name (buf2, sizeof (buf2), modifier));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
gdk_dmabuf_format_print (char *buf,
|
||||
gsize size,
|
||||
guint32 fourcc,
|
||||
guint64 modifier)
|
||||
{
|
||||
gsize len;
|
||||
char buf2[64];
|
||||
|
||||
gdk_dmabuf_fourcc_print (buf, size, fourcc);
|
||||
len = strlen (buf);
|
||||
|
||||
snprintf (buf + len, size - len, ":%s", get_modifier_name (buf2, sizeof (buf2), modifier));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LINUX_DMA_BUF_H */
|
||||
|
||||
@@ -1,342 +0,0 @@
|
||||
/* gdkdmabufegl.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* 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 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 Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
#include "gdkdmabufformatsbuilderprivate.h"
|
||||
#include "gdkdebugprivate.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdktexturedownloader.h"
|
||||
|
||||
#include <graphene.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
/* A dmabuf downloader implementation that downloads buffers via
|
||||
* gsk_renderer_render_texture + GL texture download.
|
||||
*/
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_collect_formats (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *formats,
|
||||
GdkDmabufFormatsBuilder *external)
|
||||
{
|
||||
GdkGLContext *context = gdk_display_get_gl_context (display);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
int num_fourccs;
|
||||
int *fourccs;
|
||||
guint64 *modifiers;
|
||||
unsigned int *external_only;
|
||||
int n_mods;
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY ||
|
||||
!display->have_egl_dma_buf_import)
|
||||
return FALSE;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
eglQueryDmaBufFormatsEXT (egl_display, 0, NULL, &num_fourccs);
|
||||
fourccs = g_new (int, num_fourccs);
|
||||
eglQueryDmaBufFormatsEXT (egl_display, num_fourccs, fourccs, &num_fourccs);
|
||||
|
||||
n_mods = 80;
|
||||
modifiers = g_new (guint64, n_mods);
|
||||
external_only = g_new (unsigned int, n_mods);
|
||||
|
||||
for (int i = 0; i < num_fourccs; i++)
|
||||
{
|
||||
int num_modifiers;
|
||||
gboolean all_external;
|
||||
|
||||
eglQueryDmaBufModifiersEXT (egl_display,
|
||||
fourccs[i],
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&num_modifiers);
|
||||
|
||||
if (num_modifiers > n_mods)
|
||||
{
|
||||
n_mods = num_modifiers;
|
||||
modifiers = g_renew (guint64, modifiers, n_mods);
|
||||
external_only = g_renew (unsigned int, external_only, n_mods);
|
||||
}
|
||||
|
||||
eglQueryDmaBufModifiersEXT (egl_display,
|
||||
fourccs[i],
|
||||
num_modifiers,
|
||||
modifiers,
|
||||
external_only,
|
||||
&num_modifiers);
|
||||
|
||||
all_external = TRUE;
|
||||
|
||||
for (int j = 0; j < num_modifiers; j++)
|
||||
{
|
||||
/* All linear formats we support are already added my the mmap downloader.
|
||||
* We don't add external formats, unless we can use them (via GLES)
|
||||
*/
|
||||
if (modifiers[j] != DRM_FORMAT_MOD_LINEAR &&
|
||||
(!external_only[j] || gdk_gl_context_get_use_es (context)))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"%s%s dmabuf format %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
external_only[j] ? "external " : "",
|
||||
downloader->name,
|
||||
(char *) &fourccs[i],
|
||||
modifiers[j]);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], modifiers[j]);
|
||||
}
|
||||
if (external_only[j])
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
|
||||
else
|
||||
all_external = FALSE;
|
||||
}
|
||||
|
||||
/* Accept implicit modifiers as long as we accept the format at all.
|
||||
* This is a bit of a crapshot, but unfortunately needed for a bunch
|
||||
* of drivers.
|
||||
*
|
||||
* As an extra wrinkle, treat the implicit modifier as 'external only'
|
||||
* if all formats with the same fourcc are 'external only'.
|
||||
*/
|
||||
if (!all_external || gdk_gl_context_get_use_es (context))
|
||||
gdk_dmabuf_formats_builder_add_format (formats, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
if (all_external)
|
||||
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], DRM_FORMAT_MOD_INVALID);
|
||||
}
|
||||
|
||||
g_free (modifiers);
|
||||
g_free (external_only);
|
||||
g_free (fourccs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_add_formats (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder)
|
||||
{
|
||||
GdkDmabufFormatsBuilder *formats;
|
||||
GdkDmabufFormatsBuilder *external;
|
||||
gboolean retval = FALSE;
|
||||
|
||||
g_assert (display->egl_dmabuf_formats == NULL);
|
||||
g_assert (display->egl_external_formats == NULL);
|
||||
|
||||
formats = gdk_dmabuf_formats_builder_new ();
|
||||
external = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
retval = gdk_dmabuf_egl_downloader_collect_formats (downloader, display, formats, external);
|
||||
|
||||
display->egl_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (formats);
|
||||
display->egl_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
|
||||
|
||||
gdk_dmabuf_formats_builder_add_formats (builder, display->egl_dmabuf_formats);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_supports (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean premultiplied,
|
||||
GdkMemoryFormat *out_format,
|
||||
GError **error)
|
||||
{
|
||||
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
*out_format = gdk_dmabuf_get_memory_format (display, dmabuf->fourcc, premultiplied);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_set_error (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
|
||||
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Hack. We don't include gsk/gsk.h here to avoid a build order problem
|
||||
* with the generated header gskenumtypes.h, so we need to hack around
|
||||
* a bit to access the gsk api we need.
|
||||
*/
|
||||
|
||||
typedef gpointer GskRenderer;
|
||||
|
||||
extern GskRenderer * gsk_gl_renderer_new (void);
|
||||
extern gboolean gsk_renderer_realize (GskRenderer *renderer,
|
||||
GdkSurface *surface,
|
||||
GError **error);
|
||||
extern GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture);
|
||||
|
||||
typedef void (* InvokeFunc) (gpointer data);
|
||||
|
||||
typedef struct _InvokeData
|
||||
{
|
||||
volatile int spinlock;
|
||||
InvokeFunc func;
|
||||
gpointer data;
|
||||
} InvokeData;
|
||||
|
||||
static gboolean
|
||||
gdk_dmabuf_egl_downloader_invoke_callback (gpointer data)
|
||||
{
|
||||
InvokeData *invoke = data;
|
||||
GdkGLContext *previous;
|
||||
|
||||
previous = gdk_gl_context_get_current ();
|
||||
|
||||
invoke->func (invoke->data);
|
||||
|
||||
if (previous)
|
||||
gdk_gl_context_make_current (previous);
|
||||
else
|
||||
gdk_gl_context_clear_current ();
|
||||
|
||||
g_atomic_int_set (&invoke->spinlock, 1);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Run func in the main thread, taking care not to disturb
|
||||
* the current GL context of the caller.
|
||||
*/
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_run (InvokeFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
InvokeData invoke = { 0, func, data };
|
||||
|
||||
g_main_context_invoke (NULL, gdk_dmabuf_egl_downloader_invoke_callback, &invoke);
|
||||
|
||||
while (g_atomic_int_get (&invoke.spinlock) == 0) ;
|
||||
}
|
||||
|
||||
typedef struct _Download Download;
|
||||
|
||||
struct _Download
|
||||
{
|
||||
GdkDmabufTexture *texture;
|
||||
GdkMemoryFormat format;
|
||||
guchar *data;
|
||||
gsize stride;
|
||||
};
|
||||
|
||||
static GskRenderer *
|
||||
get_gsk_renderer (GdkDisplay *display)
|
||||
{
|
||||
if (!display->egl_gsk_renderer)
|
||||
{
|
||||
GskRenderer *renderer;
|
||||
GError *error = NULL;
|
||||
|
||||
renderer = gsk_gl_renderer_new ();
|
||||
|
||||
if (!gsk_renderer_realize (renderer, NULL, &error))
|
||||
{
|
||||
g_warning ("Failed to realize GL renderer: %s", error->message);
|
||||
g_error_free (error);
|
||||
g_object_unref (renderer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display->egl_gsk_renderer = renderer;
|
||||
}
|
||||
|
||||
return display->egl_gsk_renderer;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_do_download (gpointer data)
|
||||
{
|
||||
Download *download = data;
|
||||
GdkDisplay *display;
|
||||
GskRenderer *renderer;
|
||||
GdkTexture *native;
|
||||
GdkTextureDownloader *downloader;
|
||||
|
||||
display = gdk_dmabuf_texture_get_display (download->texture);
|
||||
|
||||
renderer = get_gsk_renderer (display);
|
||||
|
||||
native = gsk_renderer_convert_texture (renderer, GDK_TEXTURE (download->texture));
|
||||
|
||||
downloader = gdk_texture_downloader_new (native);
|
||||
gdk_texture_downloader_set_format (downloader, download->format);
|
||||
gdk_texture_downloader_download_into (downloader, download->data, download->stride);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
|
||||
g_object_unref (native);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_dmabuf_egl_downloader_download (const GdkDmabufDownloader *downloader,
|
||||
GdkTexture *texture,
|
||||
GdkMemoryFormat format,
|
||||
guchar *data,
|
||||
gsize stride)
|
||||
{
|
||||
Download download;
|
||||
const GdkDmabuf *dmabuf;
|
||||
|
||||
download.texture = GDK_DMABUF_TEXTURE (texture);
|
||||
download.format = format;
|
||||
download.data = data;
|
||||
download.stride = stride;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
|
||||
GDK_DISPLAY_DEBUG (gdk_dmabuf_texture_get_display (download.texture), DMABUF,
|
||||
"Using %s for downloading a dmabuf (format %.4s:%#" G_GINT64_MODIFIER "x)",
|
||||
downloader->name, (char *)&dmabuf->fourcc, dmabuf->modifier);
|
||||
|
||||
|
||||
gdk_dmabuf_egl_downloader_run (gdk_dmabuf_egl_downloader_do_download, &download);
|
||||
}
|
||||
|
||||
const GdkDmabufDownloader *
|
||||
gdk_dmabuf_get_egl_downloader (void)
|
||||
{
|
||||
static const GdkDmabufDownloader downloader = {
|
||||
"egl",
|
||||
gdk_dmabuf_egl_downloader_add_formats,
|
||||
gdk_dmabuf_egl_downloader_supports,
|
||||
gdk_dmabuf_egl_downloader_download,
|
||||
};
|
||||
|
||||
return &downloader;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DMABUF && HAVE_EGL */
|
||||
@@ -37,10 +37,6 @@
|
||||
* The list of supported formats is sorted by preference,
|
||||
* with the best formats coming first.
|
||||
*
|
||||
* The list may contains (format, modfier) pairs where the modifier
|
||||
* is `DMA_FORMAT_MOD_INVALID`, indicating that **_implicit modifiers_**
|
||||
* may be used with this format.
|
||||
*
|
||||
* See [class@Gdk.DmabufTextureBuilder] for more information
|
||||
* about DMA buffers.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
|
||||
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
|
||||
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
|
||||
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
|
||||
|
||||
+16
-11
@@ -22,9 +22,10 @@ struct _GdkDmabuf
|
||||
struct _GdkDmabufDownloader
|
||||
{
|
||||
const char *name;
|
||||
gboolean (* add_formats) (const GdkDmabufDownloader *downloader,
|
||||
void (* add_formats) (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
GdkDmabufFormatsBuilder *builder);
|
||||
|
||||
gboolean (* supports) (const GdkDmabufDownloader *downloader,
|
||||
GdkDisplay *display,
|
||||
const GdkDmabuf *dmabuf,
|
||||
@@ -38,21 +39,25 @@ struct _GdkDmabufDownloader
|
||||
gsize stride);
|
||||
};
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
const GdkDmabufDownloader *
|
||||
gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
|
||||
|
||||
const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
|
||||
const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (void) G_GNUC_CONST;
|
||||
|
||||
gboolean gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
gboolean gdk_dmabuf_sanitize (GdkDmabuf *dest,
|
||||
gsize width,
|
||||
gsize height,
|
||||
const GdkDmabuf *src,
|
||||
GError **error);
|
||||
|
||||
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
|
||||
|
||||
GdkMemoryFormat gdk_dmabuf_get_memory_format (GdkDisplay *display,
|
||||
guint32 fourcc,
|
||||
gboolean premultiplied);
|
||||
const char * gdk_dmabuf_fourcc_print (char *str,
|
||||
gsize size,
|
||||
guint32 fourcc);
|
||||
const char * gdk_dmabuf_modifier_print (char *str,
|
||||
gsize size,
|
||||
guint64 modifier);
|
||||
const char * gdk_dmabuf_format_print (char *str,
|
||||
gsize size,
|
||||
guint32 fourcc,
|
||||
guint64 modifier);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
#include <gdk/gdkgltexturebuilder.h>
|
||||
#include <gdk/gdktexturedownloader.h>
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
@@ -129,7 +129,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
#ifdef HAVE_DMABUF
|
||||
#ifdef HAVE_LINUX_DMA_BUF_H
|
||||
GdkDmabufTexture *self;
|
||||
GdkTexture *update_texture;
|
||||
GdkDisplay *display;
|
||||
@@ -172,8 +172,8 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u, downloader %s",
|
||||
GDK_DEBUG (DMABUF,
|
||||
"Dmabuf texture, format %.4s:%#lx, %s%u planes, memory format %u, downloader %s",
|
||||
(char *) &dmabuf.fourcc, dmabuf.modifier,
|
||||
gdk_dmabuf_texture_builder_get_premultiplied (builder) ? " premultiplied, " : "",
|
||||
dmabuf.n_planes,
|
||||
@@ -210,7 +210,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
|
||||
return GDK_TEXTURE (self);
|
||||
|
||||
#else /* !HAVE_DMABUF */
|
||||
#else /* !HAVE_LINUX_DMA_BUF_H */
|
||||
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
|
||||
"dmabuf support disabled at compile-time.");
|
||||
return NULL;
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
|
||||
struct _GdkDmabufTextureBuilder
|
||||
@@ -83,36 +80,24 @@ struct _GdkDmabufTextureBuilderClass
|
||||
* descriptor per plane.
|
||||
*
|
||||
* The format of the data (for graphics data, essentially its colorspace) is described
|
||||
* by a 32-bit integer. These format identifiers are defined in the header file `drm_fourcc.h`
|
||||
* by a 32-bit integer. These format identifiers are defined in the header file
|
||||
* [drm/drm_fourcc.h](https://github.com/torvalds/linux/blob/master/include/uapi/drm/drm_fourcc.h)
|
||||
* and commonly referred to as **_fourcc_** values, since they are identified by 4 ASCII
|
||||
* characters. Additionally, each DMA buffer has a **_modifier_**, which is a 64-bit integer
|
||||
* that describes driver-specific details of the memory layout, such as tiling or compression.
|
||||
*
|
||||
* For historical reasons, some producers of dma-bufs don't provide an explicit modifier, but
|
||||
* instead return `DMA_FORMAT_MOD_INVALID` to indicate that their modifier is **_implicit_**.
|
||||
* GTK tries to accomodate this situation by accepting `DMA_FORMAT_MOD_INVALID` as modifier.
|
||||
*
|
||||
* The operation of `GdkDmabufTextureBuilder` is quite simple: Create a texture builder,
|
||||
* set all the necessary properties, and then call [method@Gdk.DmabufTextureBuilder.build]
|
||||
* to create the new texture.
|
||||
*
|
||||
* The required properties for a dma-buf texture are
|
||||
*
|
||||
* * The width and height in pixels
|
||||
*
|
||||
* * The `fourcc` code and `modifier` which identify the format and memory layout of the dma-buf
|
||||
*
|
||||
* * The file descriptor, offset and stride for each of the planes
|
||||
* - The width and height in pixels
|
||||
* - The `fourcc` code and `modifier` which identify the format and memory layout of the dma-buf
|
||||
* - The file descriptor, offset and stride for each of the planes
|
||||
*
|
||||
* `GdkDmabufTextureBuilder` can be used for quick one-shot construction of
|
||||
* textures as well as kept around and reused to construct multiple textures.
|
||||
*
|
||||
* For further information, see
|
||||
*
|
||||
* * The Linux kernel [documentation](https://docs.kernel.org/driver-api/dma-buf.html)
|
||||
*
|
||||
* * The header file [drm_fourcc.h](https://gitlab.freedesktop.org/mesa/drm/-/blob/main/include/drm/drm_fourcc.h)
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
|
||||
@@ -261,7 +246,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
gobject_class->set_property = gdk_dmabuf_texture_builder_set_property;
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:display: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_display org.gtk.Property.set=gdk_dmabuf_texture_builder_set_display)
|
||||
* GdkDmabufTextureBuilder:display: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_display org.gdk.Property.set=gdk_dmabuf_texture_builder_set_display)
|
||||
*
|
||||
* The display that this texture will be used on.
|
||||
*
|
||||
@@ -273,7 +258,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:width: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_width org.gtk.Property.set=gdk_dmabuf_texture_builder_set_width)
|
||||
* GdkDmabufTextureBuilder:width: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_width org.gdk.Property.set=gdk_dmabuf_texture_builder_set_width)
|
||||
*
|
||||
* The width of the texture.
|
||||
*
|
||||
@@ -285,7 +270,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:height: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_height org.gtk.Property.set=gdk_dmabuf_texture_builder_set_height)
|
||||
* GdkDmabufTextureBuilder:height: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_height org.gdk.Property.set=gdk_dmabuf_texture_builder_set_height)
|
||||
*
|
||||
* The height of the texture.
|
||||
*
|
||||
@@ -297,7 +282,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:fourcc: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_fourcc org.gtk.Property.set=gdk_dmabuf_texture_builder_set_fourcc)
|
||||
* GdkDmabufTextureBuilder:fourcc: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_fourcc org.gdk.Property.set=gdk_dmabuf_texture_builder_set_fourcc)
|
||||
*
|
||||
* The format of the texture, as a fourcc value.
|
||||
*
|
||||
@@ -335,7 +320,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:n-planes: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_n_planes org.gtk.Property.set=gdk_dmabuf_texture_builder_set_n_planes)
|
||||
* GdkDmabufTextureBuilder:n-planes: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_n_planes org.gdk.Property.set=gdk_dmabuf_texture_builder_set_n_planes)
|
||||
*
|
||||
* The number of planes of the texture.
|
||||
*
|
||||
@@ -350,7 +335,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_update_region org.gtk.Property.set=gdk_dmabuf_texture_builder_set_update_region)
|
||||
* GdkDmabufTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_update_region org.gdk.Property.set=gdk_dmabuf_texture_builder_set_update_region)
|
||||
*
|
||||
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
|
||||
*
|
||||
@@ -362,9 +347,9 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:update-texture: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_update_texture org.gtk.Property.set=gdk_dmabuf_texture_builder_set_update_texture)
|
||||
* GdkDmabufTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_dmabuf_texture_builder_get_update_texture org.gdk.Property.set=gdk_dmabuf_texture_builder_set_update_texture)
|
||||
*
|
||||
* The texture [property@Gdk.DmabufTextureBuilder:update-region] is an update for.
|
||||
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
@@ -446,7 +431,7 @@ gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_width: (attributes org.gtk.Method.get_property=width)
|
||||
* gdk_dmabuf_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the width previously set via gdk_dmabuf_texture_builder_set_width() or
|
||||
@@ -465,7 +450,7 @@ gdk_dmabuf_texture_builder_get_width (GdkDmabufTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_width: (attributes org.gtk.Method.set_property=width)
|
||||
* gdk_dmabuf_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @width: The texture's width or 0 to unset
|
||||
*
|
||||
@@ -490,7 +475,7 @@ gdk_dmabuf_texture_builder_set_width (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_height: (attributes org.gtk.Method.get_property=height)
|
||||
* gdk_dmabuf_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the height previously set via gdk_dmabuf_texture_builder_set_height() or
|
||||
@@ -509,7 +494,7 @@ gdk_dmabuf_texture_builder_get_height (GdkDmabufTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_height: (attributes org.gtk.Method.set_property=height)
|
||||
* gdk_dmabuf_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @height: the texture's height or 0 to unset
|
||||
*
|
||||
@@ -534,7 +519,7 @@ gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_fourcc: (attributes org.gtk.Method.get_property=fourcc)
|
||||
* gdk_dmabuf_texture_builder_get_fourcc: (attributes org.gdk.Method.get_property=fourcc)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the format previously set via gdk_dmabuf_texture_builder_set_fourcc()
|
||||
@@ -555,7 +540,7 @@ gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_fourcc: (attributes org.gtk.Method.set_property=fourcc)
|
||||
* gdk_dmabuf_texture_builder_set_fourcc: (attributes org.gdk.Method.set_property=fourcc)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @fourcc: the texture's format or 0 to unset
|
||||
*
|
||||
@@ -623,7 +608,7 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_n_planes: (attributes org.gtk.Method.get_property=n-planes)
|
||||
* gdk_dmabuf_texture_builder_get_n_planes: (attributes org.gdk.Method.get_property=n-planes)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the number of planes.
|
||||
@@ -685,7 +670,7 @@ gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_n_planes: (attributes org.gtk.Method.set_property=n-planes)
|
||||
* gdk_dmabuf_texture_builder_set_n_planes: (attributes org.gdk.Method.set_property=n-planes)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @n_planes: the number of planes
|
||||
*
|
||||
@@ -846,7 +831,7 @@ gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
|
||||
* gdk_dmabuf_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the texture previously set via gdk_dmabuf_texture_builder_set_update_texture() or
|
||||
@@ -865,7 +850,7 @@ gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_update_texture: (attributes org.gtk.Method.set_property=update-texture)
|
||||
* gdk_dmabuf_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @texture: (nullable): the texture to update
|
||||
*
|
||||
@@ -888,7 +873,7 @@ gdk_dmabuf_texture_builder_set_update_texture (GdkDmabufTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_update_region: (attributes org.gtk.Method.get_property=update-region)
|
||||
* gdk_dmabuf_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets the region previously set via gdk_dmabuf_texture_builder_set_update_region() or
|
||||
@@ -907,7 +892,7 @@ gdk_dmabuf_texture_builder_get_update_region (GdkDmabufTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_update_region: (attributes org.gtk.Method.set_property=update-region)
|
||||
* gdk_dmabuf_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @region: (nullable): the region to update
|
||||
*
|
||||
@@ -991,10 +976,9 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
|
||||
for (i = 0; i < self->dmabuf.n_planes; i++)
|
||||
g_return_val_if_fail (self->dmabuf.planes[i].fd != -1, NULL);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (self->display, DMABUF_DISABLE))
|
||||
if (GDK_DEBUG_CHECK (DMABUF_DISABLE))
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
|
||||
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
|
||||
"dmabuf support disabled via GDK_DEBUG environment variable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -68,12 +68,6 @@ gdk_draw_context_default_surface_resized (GdkDrawContext *context)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_context_default_empty_frame (GdkDrawContext *context)
|
||||
{
|
||||
g_warning ("FIXME: Implement");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_draw_context_dispose (GObject *gobject)
|
||||
{
|
||||
@@ -167,7 +161,6 @@ gdk_draw_context_class_init (GdkDrawContextClass *klass)
|
||||
gobject_class->dispose = gdk_draw_context_dispose;
|
||||
|
||||
klass->surface_resized = gdk_draw_context_default_surface_resized;
|
||||
klass->empty_frame = gdk_draw_context_default_empty_frame;
|
||||
|
||||
/**
|
||||
* GdkDrawContext:display: (attributes org.gtk.Property.get=gdk_draw_context_get_display)
|
||||
@@ -477,17 +470,3 @@ gdk_draw_context_get_frame_region (GdkDrawContext *context)
|
||||
|
||||
return priv->frame_region;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_draw_context_empty_frame (GdkDrawContext *context)
|
||||
{
|
||||
GdkDrawContextPrivate *priv = gdk_draw_context_get_instance_private (context);
|
||||
|
||||
g_return_if_fail (GDK_IS_DRAW_CONTEXT (context));
|
||||
g_return_if_fail (priv->surface != NULL);
|
||||
|
||||
if (GDK_SURFACE_DESTROYED (priv->surface))
|
||||
return;
|
||||
|
||||
GDK_DRAW_CONTEXT_GET_CLASS (context)->empty_frame (context);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ void gdk_draw_context_begin_frame (GdkDrawContext
|
||||
const cairo_region_t *region);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gdk_draw_context_end_frame (GdkDrawContext *context);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gdk_draw_context_is_in_frame (GdkDrawContext *context);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
|
||||
@@ -46,7 +46,6 @@ struct _GdkDrawContextClass
|
||||
cairo_region_t *update_area);
|
||||
void (* end_frame) (GdkDrawContext *context,
|
||||
cairo_region_t *painted);
|
||||
void (* empty_frame) (GdkDrawContext *context);
|
||||
void (* surface_resized) (GdkDrawContext *context);
|
||||
};
|
||||
|
||||
@@ -55,9 +54,5 @@ void gdk_draw_context_surface_resized (GdkDrawContext
|
||||
void gdk_draw_context_begin_frame_full (GdkDrawContext *context,
|
||||
GdkMemoryDepth depth,
|
||||
const cairo_region_t *region);
|
||||
|
||||
void gdk_draw_context_empty_frame (GdkDrawContext *context);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -402,6 +402,7 @@ gdk_event_alloc (GdkEventType event_type,
|
||||
|
||||
GdkEvent *event = (GdkEvent *) g_type_create_instance (gdk_event_types[event_type]);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (EVENTS))
|
||||
{
|
||||
char *str = g_enum_to_string (GDK_TYPE_EVENT_TYPE, event_type);
|
||||
@@ -409,6 +410,7 @@ gdk_event_alloc (GdkEventType event_type,
|
||||
g_type_name (gdk_event_types[event_type]), str);
|
||||
g_free (str);
|
||||
}
|
||||
#endif
|
||||
|
||||
event->event_type = event_type;
|
||||
event->surface = surface != NULL ? g_object_ref (surface) : NULL;
|
||||
|
||||
@@ -531,6 +531,8 @@ gdk_frame_clock_get_current_timings (GdkFrameClock *frame_clock)
|
||||
return gdk_frame_clock_get_timings (frame_clock, priv->frame_counter);
|
||||
}
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
void
|
||||
_gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
GdkFrameTimings *timings)
|
||||
@@ -577,6 +579,7 @@ _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
|
||||
g_message ("%s", str->str);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
#define DEFAULT_REFRESH_INTERVAL 16667 /* 16.7ms (1/60th second) */
|
||||
#define MAX_HISTORY_AGE 150000 /* 150ms */
|
||||
|
||||
@@ -585,12 +585,14 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
|
||||
{
|
||||
int iter;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_LAYOUT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT))
|
||||
timings->layout_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
|
||||
/* We loop in the layout phase, because we don't want to progress
|
||||
@@ -614,12 +616,14 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
case GDK_FRAME_CLOCK_PHASE_PAINT:
|
||||
if (!gdk_frame_clock_idle_is_frozen (clock_idle))
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (priv->phase != GDK_FRAME_CLOCK_PHASE_PAINT &&
|
||||
(priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT))
|
||||
timings->paint_start_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
|
||||
if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT)
|
||||
@@ -639,11 +643,13 @@ gdk_frame_clock_paint_idle (void *data)
|
||||
*/
|
||||
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
|
||||
}
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DEBUG_CHECK (FRAMES))
|
||||
{
|
||||
if (timings)
|
||||
timings->frame_end_time = g_get_monotonic_time ();
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS:
|
||||
|
||||
@@ -95,9 +95,11 @@ struct _GdkFrameTimings
|
||||
gint64 refresh_interval;
|
||||
gint64 predicted_presentation_time;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gint64 layout_start_time;
|
||||
gint64 paint_start_time;
|
||||
gint64 frame_end_time;
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
guint complete : 1;
|
||||
guint slept_before : 1;
|
||||
|
||||
+2
-284
@@ -83,7 +83,6 @@
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
#include "gdkglversionprivate.h"
|
||||
#include "gdkdmabufformatsprivate.h"
|
||||
|
||||
#include "gdkprivate.h"
|
||||
|
||||
@@ -96,10 +95,6 @@
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <drm_fourcc.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
|
||||
@@ -1563,6 +1558,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
epoxy_has_gl_extension ("GL_ARB_sync") ||
|
||||
epoxy_has_gl_extension ("GL_APPLE_sync");
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
int max_texture_size;
|
||||
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
@@ -1587,6 +1583,7 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
priv->has_sync ? "yes" : "no",
|
||||
priv->has_bgra ? "yes" : "no");
|
||||
}
|
||||
#endif
|
||||
|
||||
priv->extensions_checked = TRUE;
|
||||
}
|
||||
@@ -1980,282 +1977,3 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
|
||||
|
||||
g_assert (the_gl_backend_type == backend_type);
|
||||
}
|
||||
|
||||
static guint
|
||||
gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int target)
|
||||
{
|
||||
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLint attribs[64];
|
||||
int i;
|
||||
EGLImage image;
|
||||
guint texture_id;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), 0);
|
||||
g_return_val_if_fail (width > 0, 0);
|
||||
g_return_val_if_fail (height > 0, 0);
|
||||
g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0);
|
||||
g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0);
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import dmabufs into GL, missing EGL or EGL_EXT_image_dma_buf_import_modifiers");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
|
||||
|
||||
i = 0;
|
||||
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[i++] = EGL_TRUE;
|
||||
attribs[i++] = EGL_WIDTH;
|
||||
attribs[i++] = width;
|
||||
attribs[i++] = EGL_HEIGHT;
|
||||
attribs[i++] = height;
|
||||
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[i++] = dmabuf->fourcc;
|
||||
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[i++] = EGL_ITU_REC601_EXT;
|
||||
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[i++] = EGL_YUV_FULL_RANGE_EXT;
|
||||
|
||||
#define ADD_PLANE(plane) \
|
||||
{ \
|
||||
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \
|
||||
{ \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \
|
||||
attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \
|
||||
attribs[i++] = dmabuf->modifier >> 32; \
|
||||
} \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].fd; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].stride; \
|
||||
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \
|
||||
attribs[i++] = dmabuf->planes[plane].offset; \
|
||||
}
|
||||
|
||||
ADD_PLANE (0);
|
||||
|
||||
if (dmabuf->n_planes > 1) ADD_PLANE (1);
|
||||
if (dmabuf->n_planes > 2) ADD_PLANE (2);
|
||||
if (dmabuf->n_planes > 3) ADD_PLANE (3);
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
image = eglCreateImageKHR (egl_display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT,
|
||||
(EGLClientBuffer)NULL,
|
||||
attribs);
|
||||
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating EGLImage for dmabuf failed: %#x",
|
||||
eglGetError ());
|
||||
return 0;
|
||||
}
|
||||
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (target, texture_id);
|
||||
glEGLImageTargetTexture2DOES (target, image);
|
||||
glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
eglDestroyImageKHR (egl_display, image);
|
||||
|
||||
return texture_id;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
guint
|
||||
gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean *external)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
guint texture_id;
|
||||
|
||||
gdk_display_init_dmabuf (display);
|
||||
|
||||
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
|
||||
{
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_2D);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_2D texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = FALSE;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
if (!gdk_gl_context_get_use_es (self))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import external_only %.4s:%#" G_GINT64_MODIFIER "x outside of GLES",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
GL_TEXTURE_EXTERNAL_OES);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Import of external_only %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf failed",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Imported %dx%d %.4s:%#" G_GINT64_MODIFIER "x dmabuf as GL_TEXTURE_EXTERNAL_OES texture",
|
||||
width, height,
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier);
|
||||
*external = TRUE;
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_gl_context_export_dmabuf (GdkGLContext *self,
|
||||
unsigned int texture_id,
|
||||
GdkDmabuf *dmabuf)
|
||||
{
|
||||
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLContext egl_context = priv->egl_context;
|
||||
EGLint attribs[10];
|
||||
EGLImage image;
|
||||
gboolean result = FALSE;
|
||||
int i;
|
||||
int fourcc;
|
||||
int n_planes;
|
||||
guint64 modifier;
|
||||
int fds[GDK_DMABUF_MAX_PLANES];
|
||||
int strides[GDK_DMABUF_MAX_PLANES];
|
||||
int offsets[GDK_DMABUF_MAX_PLANES];
|
||||
|
||||
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
|
||||
g_return_val_if_fail (texture_id > 0, FALSE);
|
||||
g_return_val_if_fail (dmabuf != NULL, FALSE);
|
||||
|
||||
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_export)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't export dmabufs from GL, missing EGL or EGL_EXT_image_dma_buf_export");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF, "Exporting GL texture to dmabuf");
|
||||
|
||||
i = 0;
|
||||
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
|
||||
attribs[i++] = EGL_TRUE;
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
image = eglCreateImageKHR (egl_display,
|
||||
egl_context,
|
||||
EGL_GL_TEXTURE_2D_KHR,
|
||||
(EGLClientBuffer)GUINT_TO_POINTER (texture_id),
|
||||
attribs);
|
||||
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Creating EGLImage for dmabuf failed: %#x", eglGetError ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!eglExportDMABUFImageQueryMESA (egl_display,
|
||||
image,
|
||||
&fourcc,
|
||||
&n_planes,
|
||||
&modifier))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"eglExportDMABUFImageQueryMESA failed: %#x", eglGetError ());
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (n_planes < 1 || n_planes > GDK_DMABUF_MAX_PLANES)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"dmabufs with %d planes are not supported", n_planes);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!eglExportDMABUFImageMESA (egl_display,
|
||||
image,
|
||||
fds,
|
||||
strides,
|
||||
offsets))
|
||||
{
|
||||
g_warning ("eglExportDMABUFImage failed: %#x", eglGetError ());
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_planes; i++)
|
||||
{
|
||||
if (fds[i] == -1)
|
||||
{
|
||||
g_warning ("dmabuf plane %d has no file descriptor", i);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dmabuf->fourcc = (guint32)fourcc;
|
||||
dmabuf->modifier = modifier;
|
||||
dmabuf->n_planes = n_planes;
|
||||
|
||||
for (i = 0; i < n_planes; i++)
|
||||
{
|
||||
dmabuf->planes[i].fd = fds[i];
|
||||
dmabuf->planes[i].stride = (int) strides[i];
|
||||
dmabuf->planes[i].offset = (int) offsets[i];
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Exported GL texture to dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %d)",
|
||||
(char *)&fourcc, modifier, n_planes);
|
||||
|
||||
result = TRUE;
|
||||
|
||||
out:
|
||||
eglDestroyImageKHR (egl_display, image);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "gdkglcontext.h"
|
||||
#include "gdkdrawcontextprivate.h"
|
||||
#include "gdkglversionprivate.h"
|
||||
#include "gdkdmabufprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -164,14 +163,5 @@ gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext
|
||||
|
||||
double gdk_gl_context_get_scale (GdkGLContext *self);
|
||||
|
||||
guint gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
gboolean *external);
|
||||
|
||||
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
|
||||
unsigned int texture_id,
|
||||
GdkDmabuf *dmabuf);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+27
-27
@@ -213,7 +213,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
gobject_class->set_property = gdk_gl_texture_builder_set_property;
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:context: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_context org.gtk.Property.set=gdk_gl_texture_builder_set_context)
|
||||
* GdkGLTextureBuilder:context: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_context org.gdk.Property.set=gdk_gl_texture_builder_set_context)
|
||||
*
|
||||
* The context owning the texture.
|
||||
*
|
||||
@@ -225,7 +225,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:format: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_format org.gtk.Property.set=gdk_gl_texture_builder_set_format)
|
||||
* GdkGLTextureBuilder:format: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_format org.gdk.Property.set=gdk_gl_texture_builder_set_format)
|
||||
*
|
||||
* The format when downloading the texture.
|
||||
*
|
||||
@@ -238,7 +238,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:has-mipmap: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gtk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
|
||||
* GdkGLTextureBuilder:has-mipmap: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_has_mipmap org.gdk.Property.set=gdk_gl_texture_builder_set_has_mipmap)
|
||||
*
|
||||
* If the texture has a mipmap.
|
||||
*
|
||||
@@ -250,7 +250,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:height: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_height org.gtk.Property.set=gdk_gl_texture_builder_set_height)
|
||||
* GdkGLTextureBuilder:height: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_height org.gdk.Property.set=gdk_gl_texture_builder_set_height)
|
||||
*
|
||||
* The height of the texture.
|
||||
*
|
||||
@@ -262,7 +262,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:id: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_id org.gtk.Property.set=gdk_gl_texture_builder_set_id)
|
||||
* GdkGLTextureBuilder:id: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_id org.gdk.Property.set=gdk_gl_texture_builder_set_id)
|
||||
*
|
||||
* The texture ID to use.
|
||||
*
|
||||
@@ -274,7 +274,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:sync: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_sync org.gtk.Property.set=gdk_gl_texture_builder_set_sync)
|
||||
* GdkGLTextureBuilder:sync: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_sync org.gdk.Property.set=gdk_gl_texture_builder_set_sync)
|
||||
*
|
||||
* An optional `GLSync` object.
|
||||
*
|
||||
@@ -287,7 +287,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_region org.gtk.Property.set=gdk_gl_texture_builder_set_update_region)
|
||||
* GdkGLTextureBuilder:update-region: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_region org.gdk.Property.set=gdk_gl_texture_builder_set_update_region)
|
||||
*
|
||||
* The update region for [property@Gdk.GLTextureBuilder:update-texture].
|
||||
*
|
||||
@@ -299,7 +299,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:update-texture: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_update_texture org.gtk.Property.set=gdk_gl_texture_builder_set_update_texture)
|
||||
* GdkGLTextureBuilder:update-texture: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_update_texture org.gdk.Property.set=gdk_gl_texture_builder_set_update_texture)
|
||||
*
|
||||
* The texture [property@Gdk.GLTextureBuilder:update-region] is an update for.
|
||||
*
|
||||
@@ -311,7 +311,7 @@ gdk_gl_texture_builder_class_init (GdkGLTextureBuilderClass *klass)
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkGLTextureBuilder:width: (attributes org.gtk.Property.get=gdk_gl_texture_builder_get_width org.gtk.Property.set=gdk_gl_texture_builder_set_width)
|
||||
* GdkGLTextureBuilder:width: (attributes org.gdk.Property.get=gdk_gl_texture_builder_get_width org.gdk.Property.set=gdk_gl_texture_builder_set_width)
|
||||
*
|
||||
* The width of the texture.
|
||||
*
|
||||
@@ -347,7 +347,7 @@ gdk_gl_texture_builder_new (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_context: (attributes org.gtk.Method.get_property=context)
|
||||
* gdk_gl_texture_builder_get_context: (attributes org.gdk.Method.get_property=context)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the context previously set via gdk_gl_texture_builder_set_context() or
|
||||
@@ -366,7 +366,7 @@ gdk_gl_texture_builder_get_context (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_context: (attributes org.gtk.Method.set_property=context)
|
||||
* gdk_gl_texture_builder_set_context: (attributes org.gdk.Method.set_property=context)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @context: (nullable): The context the texture beongs to or %NULL to unset
|
||||
*
|
||||
@@ -391,7 +391,7 @@ gdk_gl_texture_builder_set_context (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_height: (attributes org.gtk.Method.get_property=height)
|
||||
* gdk_gl_texture_builder_get_height: (attributes org.gdk.Method.get_property=height)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the height previously set via gdk_gl_texture_builder_set_height() or
|
||||
@@ -410,7 +410,7 @@ gdk_gl_texture_builder_get_height (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_height: (attributes org.gtk.Method.set_property=height)
|
||||
* gdk_gl_texture_builder_set_height: (attributes org.gdk.Method.set_property=height)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @height: The texture's height or 0 to unset
|
||||
*
|
||||
@@ -435,7 +435,7 @@ gdk_gl_texture_builder_set_height (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_id: (attributes org.gtk.Method.get_property=id)
|
||||
* gdk_gl_texture_builder_get_id: (attributes org.gdk.Method.get_property=id)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the texture id previously set via gdk_gl_texture_builder_set_id() or
|
||||
@@ -454,7 +454,7 @@ gdk_gl_texture_builder_get_id (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_id: (attributes org.gtk.Method.set_property=id)
|
||||
* gdk_gl_texture_builder_set_id: (attributes org.gdk.Method.set_property=id)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @id: The texture id to be used for creating the texture
|
||||
*
|
||||
@@ -481,7 +481,7 @@ gdk_gl_texture_builder_set_id (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_width: (attributes org.gtk.Method.get_property=width)
|
||||
* gdk_gl_texture_builder_get_width: (attributes org.gdk.Method.get_property=width)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the width previously set via gdk_gl_texture_builder_set_width() or
|
||||
@@ -500,7 +500,7 @@ gdk_gl_texture_builder_get_width (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_width: (attributes org.gtk.Method.set_property=width)
|
||||
* gdk_gl_texture_builder_set_width: (attributes org.gdk.Method.set_property=width)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @width: The texture's width or 0 to unset
|
||||
*
|
||||
@@ -525,7 +525,7 @@ gdk_gl_texture_builder_set_width (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gtk.Method.get_property=has-mipmap)
|
||||
* gdk_gl_texture_builder_get_has_mipmap: (attributes org.gdk.Method.get_property=has-mipmap)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets whether the texture has a mipmap.
|
||||
@@ -543,7 +543,7 @@ gdk_gl_texture_builder_get_has_mipmap (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gtk.Method.set_property=has-mipmap)
|
||||
* gdk_gl_texture_builder_set_has_mipmap: (attributes org.gdk.Method.set_property=has-mipmap)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @has_mipmap: Whether the texture has a mipmap
|
||||
*
|
||||
@@ -569,7 +569,7 @@ gdk_gl_texture_builder_set_has_mipmap (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_sync: (attributes org.gtk.Method.get_property=sync)
|
||||
* gdk_gl_texture_builder_get_sync: (attributes org.gdk.Method.get_property=sync)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the `GLsync` previously set via gdk_gl_texture_builder_set_sync().
|
||||
@@ -587,7 +587,7 @@ gdk_gl_texture_builder_get_sync (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_sync: (attributes org.gtk.Method.set_property=sync)
|
||||
* gdk_gl_texture_builder_set_sync: (attributes org.gdk.Method.set_property=sync)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @sync: (nullable): the GLSync object
|
||||
*
|
||||
@@ -617,7 +617,7 @@ gdk_gl_texture_builder_set_sync (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_format: (attributes org.gtk.Method.get_property=format)
|
||||
* gdk_gl_texture_builder_get_format: (attributes org.gdk.Method.get_property=format)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the format previously set via gdk_gl_texture_builder_set_format().
|
||||
@@ -635,7 +635,7 @@ gdk_gl_texture_builder_get_format (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_format: (attributes org.gtk.Method.set_property=format)
|
||||
* gdk_gl_texture_builder_set_format: (attributes org.gdk.Method.set_property=format)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @format: The texture's format
|
||||
*
|
||||
@@ -673,7 +673,7 @@ gdk_gl_texture_builder_set_format (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
|
||||
* gdk_gl_texture_builder_get_update_texture: (attributes org.gdk.Method.get_property=update_texture)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the texture previously set via gdk_gl_texture_builder_set_update_texture() or
|
||||
@@ -692,7 +692,7 @@ gdk_gl_texture_builder_get_update_texture (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_update_texture: (attributes org.gtk.Method.set_property=update-texture)
|
||||
* gdk_gl_texture_builder_set_update_texture: (attributes org.gdk.Method.set_property=update_texture)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @texture: (nullable): the texture to update
|
||||
*
|
||||
@@ -715,7 +715,7 @@ gdk_gl_texture_builder_set_update_texture (GdkGLTextureBuilder *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_get_update_region: (attributes org.gtk.Method.get_property=update-region)
|
||||
* gdk_gl_texture_builder_get_update_region: (attributes org.gdk.Method.get_property=update_region)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
*
|
||||
* Gets the region previously set via gdk_gl_texture_builder_set_update_region() or
|
||||
@@ -734,7 +734,7 @@ gdk_gl_texture_builder_get_update_region (GdkGLTextureBuilder *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_gl_texture_builder_set_update_region: (attributes org.gtk.Method.set_property=update-region)
|
||||
* gdk_gl_texture_builder_set_update_region: (attributes org.gdk.Method.set_property=update_region)
|
||||
* @self: a `GdkGLTextureBuilder`
|
||||
* @region: (nullable): the region to update
|
||||
*
|
||||
|
||||
@@ -481,7 +481,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
G_ALIGNOF (guchar),
|
||||
GDK_MEMORY_U8,
|
||||
{ 0, 0, 0, 0 },
|
||||
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
{ GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
|
||||
r8g8b8_to_float,
|
||||
r8g8b8_from_float,
|
||||
},
|
||||
@@ -491,7 +491,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
G_ALIGNOF (guchar),
|
||||
GDK_MEMORY_U8,
|
||||
{ 0, 0, G_MAXUINT, G_MAXUINT },
|
||||
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
{ GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
|
||||
b8g8r8_to_float,
|
||||
b8g8r8_from_float,
|
||||
},
|
||||
@@ -501,7 +501,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
G_ALIGNOF (guint16),
|
||||
GDK_MEMORY_U16,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
{ GL_RGB16, GL_RGB, GL_UNSIGNED_SHORT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
|
||||
r16g16b16_to_float,
|
||||
r16g16b16_from_float,
|
||||
},
|
||||
@@ -531,7 +531,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
G_ALIGNOF (guint16),
|
||||
GDK_MEMORY_FLOAT16,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
{ GL_RGB16F, GL_RGB, GL_HALF_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
|
||||
r16g16b16_float_to_float,
|
||||
r16g16b16_float_from_float,
|
||||
},
|
||||
@@ -561,7 +561,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
G_ALIGNOF (float),
|
||||
GDK_MEMORY_FLOAT32,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGB32F, GL_RGB, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
{ GL_RGB32F, GL_RGB, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
|
||||
r32g32b32_float_to_float,
|
||||
r32g32b32_float_from_float,
|
||||
},
|
||||
@@ -569,7 +569,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
|
||||
GDK_MEMORY_ALPHA_PREMULTIPLIED,
|
||||
16,
|
||||
G_ALIGNOF (float),
|
||||
GDK_MEMORY_FLOAT32,
|
||||
TRUE,
|
||||
{ 0, 0, 3, 0 },
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
|
||||
r32g32b32a32_float_to_float,
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat, Inc.
|
||||
*
|
||||
* 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 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 Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktexture.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkSubsurface, gdk_subsurface, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gdk_subsurface_init (GdkSubsurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_subsurface_finalize (GObject *object)
|
||||
{
|
||||
GdkSubsurface *subsurface = GDK_SUBSURFACE (object);
|
||||
|
||||
g_ptr_array_remove (subsurface->parent->subsurfaces, subsurface);
|
||||
g_clear_object (&subsurface->parent);
|
||||
|
||||
G_OBJECT_CLASS (gdk_subsurface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_subsurface_class_init (GdkSubsurfaceClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_subsurface_finalize;
|
||||
}
|
||||
|
||||
GdkSurface *
|
||||
gdk_subsurface_get_parent (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
|
||||
|
||||
return subsurface->parent;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), FALSE);
|
||||
g_return_val_if_fail (GDK_IS_TEXTURE (texture), FALSE);
|
||||
g_return_val_if_fail (rect != NULL, FALSE);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->attach (subsurface, texture, rect);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_subsurface_detach (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->detach (subsurface);
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_subsurface_get_texture (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), NULL);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->get_texture (subsurface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_subsurface_get_rect (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
g_return_if_fail (rect != NULL);
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->get_rect (subsurface, rect);
|
||||
}
|
||||
|
||||
/* If sibling is NULL, place the subsurface above its parent */
|
||||
void
|
||||
gdk_subsurface_place_above (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
g_return_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling));
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->place_above (subsurface, sibling);
|
||||
}
|
||||
|
||||
/* If sibling is NULL, place the subsurface below its parent */
|
||||
void
|
||||
gdk_subsurface_place_below (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_SUBSURFACE (subsurface));
|
||||
g_return_if_fail (sibling == NULL || GDK_IS_SUBSURFACE (sibling));
|
||||
|
||||
GDK_SUBSURFACE_GET_CLASS (subsurface)->place_below (subsurface, sibling);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_subsurface_is_above_parent (GdkSubsurface *subsurface)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_SUBSURFACE (subsurface), TRUE);
|
||||
|
||||
return GDK_SUBSURFACE_GET_CLASS (subsurface)->is_above_parent (subsurface);
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat, Inc.
|
||||
*
|
||||
* 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 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 Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Uninstalled header defining types and functions internal to GDK */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdksurface.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkSubsurface GdkSubsurface;
|
||||
typedef struct _GdkSubsurfaceClass GdkSubsurfaceClass;
|
||||
|
||||
#define GDK_TYPE_SUBSURFACE (gdk_subsurface_get_type ())
|
||||
#define GDK_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_SUBSURFACE, GdkSubsurface))
|
||||
#define GDK_SUBSURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
|
||||
#define GDK_IS_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_SUBSURFACE))
|
||||
#define GDK_SUBSURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SUBSURFACE, GdkSubsurfaceClass))
|
||||
|
||||
struct _GdkSubsurface
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkSurface *parent;
|
||||
|
||||
int ref_count;
|
||||
};
|
||||
|
||||
|
||||
struct _GdkSubsurfaceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* attach) (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect);
|
||||
void (* detach) (GdkSubsurface *subsurface);
|
||||
GdkTexture * (* get_texture) (GdkSubsurface *subsurface);
|
||||
void (* get_rect) (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect);
|
||||
void (* place_above) (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling);
|
||||
void (* place_below) (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling);
|
||||
gboolean (* is_above_parent) (GdkSubsurface *subsurface);
|
||||
};
|
||||
|
||||
GType gdk_subsurface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkSurface * gdk_subsurface_get_parent (GdkSubsurface *subsurface);
|
||||
gboolean gdk_subsurface_attach (GdkSubsurface *subsurface,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect);
|
||||
void gdk_subsurface_detach (GdkSubsurface *subsurface);
|
||||
GdkTexture * gdk_subsurface_get_texture (GdkSubsurface *subsurface);
|
||||
void gdk_subsurface_get_rect (GdkSubsurface *subsurface,
|
||||
graphene_rect_t *rect);
|
||||
void gdk_subsurface_place_above (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling);
|
||||
void gdk_subsurface_place_below (GdkSubsurface *subsurface,
|
||||
GdkSubsurface *sibling);
|
||||
gboolean gdk_subsurface_is_above_parent (GdkSubsurface *subsurface);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "gdkrectangle.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkvulkancontext.h"
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -486,8 +485,6 @@ gdk_surface_init (GdkSurface *surface)
|
||||
|
||||
surface->device_cursor = g_hash_table_new_full (NULL, NULL,
|
||||
NULL, g_object_unref);
|
||||
|
||||
surface->subsurfaces = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static double
|
||||
@@ -496,14 +493,6 @@ gdk_surface_real_get_scale (GdkSurface *surface)
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
static GdkSubsurface *
|
||||
gdk_surface_real_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (surface), OFFLOAD,
|
||||
"Subsurfaces not supported for %s", G_OBJECT_TYPE_NAME (surface));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_surface_constructed (GObject *object)
|
||||
{
|
||||
@@ -526,7 +515,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
|
||||
|
||||
klass->beep = gdk_surface_real_beep;
|
||||
klass->get_scale = gdk_surface_real_get_scale;
|
||||
klass->create_subsurface = gdk_surface_real_create_subsurface;
|
||||
|
||||
/**
|
||||
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
|
||||
@@ -769,10 +757,6 @@ gdk_surface_finalize (GObject *object)
|
||||
if (surface->parent)
|
||||
surface->parent->children = g_list_remove (surface->parent->children, surface);
|
||||
|
||||
g_assert (surface->subsurfaces->len == 0);
|
||||
|
||||
g_ptr_array_unref (surface->subsurfaces);
|
||||
|
||||
G_OBJECT_CLASS (gdk_surface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -3070,32 +3054,3 @@ gdk_surface_leave_monitor (GdkSurface *surface,
|
||||
{
|
||||
g_signal_emit (surface, signals[LEAVE_MONITOR], 0, monitor);
|
||||
}
|
||||
|
||||
GdkSubsurface *
|
||||
gdk_surface_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
GdkSubsurface *subsurface;
|
||||
|
||||
subsurface = GDK_SURFACE_GET_CLASS (surface)->create_subsurface (surface);
|
||||
|
||||
if (subsurface)
|
||||
{
|
||||
subsurface->parent = g_object_ref (surface);
|
||||
g_ptr_array_add (surface->subsurfaces, subsurface);
|
||||
}
|
||||
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
gsize
|
||||
gdk_surface_get_n_subsurfaces (GdkSurface *surface)
|
||||
{
|
||||
return surface->subsurfaces->len;
|
||||
}
|
||||
|
||||
GdkSubsurface *
|
||||
gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
gsize idx)
|
||||
{
|
||||
return g_ptr_array_index (surface->subsurfaces, idx);
|
||||
}
|
||||
|
||||
+2
-16
@@ -23,14 +23,9 @@
|
||||
#include "gdkenumtypes.h"
|
||||
#include "gdksurface.h"
|
||||
#include "gdktoplevel.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkSubsurface GdkSubsurface;
|
||||
|
||||
typedef struct _GskRenderNode GskRenderNode;
|
||||
|
||||
struct _GdkSurface
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -97,8 +92,6 @@ struct _GdkSurface
|
||||
cairo_region_t *opaque_region;
|
||||
|
||||
GdkSeat *current_shortcuts_inhibited_seat;
|
||||
|
||||
GPtrArray *subsurfaces;
|
||||
};
|
||||
|
||||
struct _GdkSurfaceClass
|
||||
@@ -153,9 +146,6 @@ struct _GdkSurfaceClass
|
||||
cairo_region_t *region);
|
||||
void (* request_layout) (GdkSurface *surface);
|
||||
gboolean (* compute_size) (GdkSurface *surface);
|
||||
|
||||
GdkSubsurface *
|
||||
(* create_subsurface) (GdkSurface *surface);
|
||||
};
|
||||
|
||||
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
|
||||
@@ -344,11 +334,7 @@ void gdk_surface_request_motion (GdkSurface *surface);
|
||||
|
||||
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
|
||||
|
||||
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
|
||||
void gdk_surface_destroy_subsurface (GdkSurface *surface,
|
||||
GdkSubsurface *subsurface);
|
||||
gsize gdk_surface_get_n_subsurfaces (GdkSurface *surface);
|
||||
GdkSubsurface * gdk_surface_get_subsurface (GdkSurface *surface,
|
||||
gsize idx);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -252,6 +252,7 @@ gdk_vulkan_strerror (VkResult result)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *
|
||||
surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
{
|
||||
@@ -274,6 +275,7 @@ surface_present_mode_to_string (VkPresentModeKHR present_mode)
|
||||
|
||||
return "(unknown)";
|
||||
}
|
||||
#endif
|
||||
|
||||
static const VkPresentModeKHR preferred_present_modes[] = {
|
||||
VK_PRESENT_MODE_MAILBOX_KHR,
|
||||
|
||||
@@ -180,6 +180,7 @@ typedef enum {
|
||||
POLLING_DESCRIPTORS,
|
||||
} SelectThreadState;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *const state_names[] = {
|
||||
"BEFORE_START",
|
||||
"WAITING",
|
||||
@@ -187,6 +188,7 @@ static const char *const state_names[] = {
|
||||
"POLLING_RESTART",
|
||||
"POLLING_DESCRIPTORS"
|
||||
};
|
||||
#endif
|
||||
|
||||
static SelectThreadState select_thread_state = BEFORE_START;
|
||||
|
||||
@@ -372,6 +374,7 @@ select_thread_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
dump_poll_result (GPollFD *ufds,
|
||||
guint nfds)
|
||||
@@ -397,6 +400,7 @@ dump_poll_result (GPollFD *ufds,
|
||||
gdk_debug_message ("%s", s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
pollfds_equal (GPollFD *old_pollfds,
|
||||
@@ -464,11 +468,13 @@ select_thread_start_poll (GPollFD *ufds,
|
||||
n_ready = old_poll_func (ufds, nfds, 0);
|
||||
if (n_ready > 0 || timeout == 0)
|
||||
{
|
||||
if (GDK_DEBUG_CHECK (EVENTLOOP) && n_ready > 0)
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0)
|
||||
{
|
||||
gdk_debug_message ("EventLoop: Found ready file descriptors before waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
|
||||
return n_ready;
|
||||
}
|
||||
@@ -606,11 +612,13 @@ select_thread_collect_poll (GPollFD *ufds, guint nfds)
|
||||
}
|
||||
}
|
||||
|
||||
if (GDK_DEBUG_CHECK (EVENTLOOP))
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP)
|
||||
{
|
||||
gdk_debug_message ("EventLoop: Found ready file descriptors after waiting");
|
||||
dump_poll_result (ufds, nfds);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SELECT_THREAD_UNLOCK ();
|
||||
|
||||
@@ -18,7 +18,6 @@ gdk_public_sources = files([
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdmabuf.c',
|
||||
'gdkdmabufegl.c',
|
||||
'gdkdmabufformats.c',
|
||||
'gdkdmabufformatsbuilder.c',
|
||||
'gdkdmabuftexture.c',
|
||||
@@ -55,7 +54,6 @@ gdk_public_sources = files([
|
||||
'gdktexture.c',
|
||||
'gdktexturedownloader.c',
|
||||
'gdkvulkancontext.c',
|
||||
'gdksubsurface.c',
|
||||
'gdksurface.c',
|
||||
'gdkpopuplayout.c',
|
||||
'gdkprofiler.c',
|
||||
@@ -218,7 +216,6 @@ gdk_deps = [
|
||||
platform_gio_dep,
|
||||
pangocairo_dep,
|
||||
vulkan_dep,
|
||||
dmabuf_dep,
|
||||
png_dep,
|
||||
tiff_dep,
|
||||
jpeg_dep,
|
||||
|
||||
@@ -194,23 +194,6 @@ gdk_wayland_cairo_context_end_frame (GdkDrawContext *draw_context,
|
||||
self->paint_surface = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_cairo_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->has_pending_subsurface_commits)
|
||||
return;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "surface commit");
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_cairo_context_clear_all_cairo_surfaces (GdkWaylandCairoContext *self)
|
||||
{
|
||||
@@ -258,7 +241,6 @@ gdk_wayland_cairo_context_class_init (GdkWaylandCairoContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_cairo_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_cairo_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_wayland_cairo_context_empty_frame;
|
||||
draw_context_class->surface_resized = gdk_wayland_cairo_context_surface_resized;
|
||||
|
||||
cairo_context_class->cairo_create = gdk_wayland_cairo_context_cairo_create;
|
||||
|
||||
@@ -225,12 +225,14 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_clipboard_read_async);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: read for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, cb->offer_formats);
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
@@ -320,12 +322,14 @@ gdk_wayland_clipboard_claim_remote (GdkWaylandClipboard *cb,
|
||||
|
||||
gdk_wayland_clipboard_discard_offer (cb);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: remote clipboard claim for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
cb->offer_formats = formats;
|
||||
cb->offer = offer;
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#ifdef HAVE_LINUX_MEMFD_H
|
||||
#include <linux/memfd.h>
|
||||
@@ -57,7 +56,6 @@
|
||||
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
#include <wayland/server-decoration-client-protocol.h>
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
#include "wm-button-layout-translation.h"
|
||||
|
||||
@@ -269,119 +267,58 @@ postpone_on_globals_closure (GdkWaylandDisplay *display_wayland,
|
||||
g_list_append (display_wayland->on_has_globals_closures, closure);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
get_format_name (uint32_t format,
|
||||
char name[10])
|
||||
{
|
||||
if (format == 0)
|
||||
g_strlcpy (name, "ARGB8888", 10);
|
||||
else if (format == 1)
|
||||
g_strlcpy (name, "XRGB8888", 10);
|
||||
else
|
||||
g_snprintf (name, 10, "4cc %c%c%c%c",
|
||||
(char) (format & 0xff),
|
||||
(char) ((format >> 8) & 0xff),
|
||||
(char) ((format >> 16) & 0xff),
|
||||
(char) ((format >> 24) & 0xff));
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
wl_shm_format (void *data,
|
||||
struct wl_shm *wl_shm,
|
||||
uint32_t format)
|
||||
{
|
||||
GDK_DEBUG (MISC, "supported shm pixel format %.4s (0x%X)",
|
||||
format == 0 ? "ARGB8888"
|
||||
: (format == 1 ? "XRGB8888"
|
||||
: (char *) &format), format);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
char buf[10];
|
||||
#endif
|
||||
|
||||
GDK_DEBUG (MISC, "supported pixel format %s (0x%X)",
|
||||
get_format_name (format, buf), (guint) format);
|
||||
}
|
||||
|
||||
static const struct wl_shm_listener wl_shm_listener = {
|
||||
wl_shm_format
|
||||
};
|
||||
|
||||
static void
|
||||
linux_dmabuf_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
|
||||
{
|
||||
GDK_DEBUG (MISC, "dmabuf feedback done");
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_format_table (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
int32_t fd,
|
||||
uint32_t size)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
|
||||
display_wayland->linux_dmabuf_n_formats = size / 16;
|
||||
display_wayland->linux_dmabuf_formats = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf format table (%lu entries)", display_wayland->linux_dmabuf_n_formats);
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_main_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *device)
|
||||
{
|
||||
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf main device: %u %u", major (dev), minor (dev));
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_done (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
|
||||
{
|
||||
GDK_DEBUG (MISC, "dmabuf feedback tranche done");
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_target_device (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *device)
|
||||
{
|
||||
dev_t dev G_GNUC_UNUSED = *(dev_t *)device->data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf tranche target device: %u %u", major (dev), minor (dev));
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_formats (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
struct wl_array *indices)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
|
||||
GDK_DEBUG (MISC, "got dmabuf tranche formats (%lu entries):", indices->size / sizeof (guint16));
|
||||
guint16 *pos;
|
||||
|
||||
wl_array_for_each (pos, indices)
|
||||
{
|
||||
LinuxDmabufFormat *fmt G_GNUC_UNUSED = &display_wayland->linux_dmabuf_formats[*pos];
|
||||
uint32_t f G_GNUC_UNUSED = fmt->fourcc;
|
||||
uint64_t m G_GNUC_UNUSED = fmt->modifier;
|
||||
GDK_DEBUG (MISC, " %.4s:%#" G_GINT64_MODIFIER "x", (char *) &f, m);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
linux_dmabuf_tranche_flags (void *data,
|
||||
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
|
||||
uint32_t flags)
|
||||
{
|
||||
GDK_DEBUG (MISC,
|
||||
"got dmabuf tranche flags: %s",
|
||||
flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ? "scanout" : "");
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_feedback_v1_listener linux_dmabuf_feedback_listener = {
|
||||
linux_dmabuf_done,
|
||||
linux_dmabuf_format_table,
|
||||
linux_dmabuf_main_device,
|
||||
linux_dmabuf_tranche_done,
|
||||
linux_dmabuf_tranche_target_device,
|
||||
linux_dmabuf_tranche_formats,
|
||||
linux_dmabuf_tranche_flags,
|
||||
};
|
||||
|
||||
static void
|
||||
server_decoration_manager_default_mode (void *data,
|
||||
struct org_kde_kwin_server_decoration_manager *manager,
|
||||
uint32_t mode)
|
||||
{
|
||||
g_assert (mode <= ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *modes[] = {
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_NONE] = "none",
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT] = "client",
|
||||
[ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_SERVER] = "server",
|
||||
};
|
||||
#endif
|
||||
GdkWaylandDisplay *display_wayland = data;
|
||||
GDK_DISPLAY_DEBUG (GDK_DISPLAY (data), MISC, "Compositor prefers decoration mode '%s'", modes[mode]);
|
||||
display_wayland->server_decoration_mode = mode;
|
||||
@@ -445,16 +382,6 @@ gdk_registry_handle_global (void *data,
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1);
|
||||
wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland);
|
||||
}
|
||||
else if (strcmp (interface, "zwp_linux_dmabuf_v1") == 0 && version >= 4)
|
||||
{
|
||||
display_wayland->linux_dmabuf =
|
||||
wl_registry_bind (display_wayland->wl_registry, id, &zwp_linux_dmabuf_v1_interface, version);
|
||||
display_wayland->linux_dmabuf_feedback =
|
||||
zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
|
||||
zwp_linux_dmabuf_feedback_v1_add_listener (display_wayland->linux_dmabuf_feedback,
|
||||
&linux_dmabuf_feedback_listener, display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
else if (strcmp (interface, "xdg_wm_base") == 0)
|
||||
{
|
||||
display_wayland->xdg_wm_base_id = id;
|
||||
@@ -799,10 +726,6 @@ gdk_wayland_display_dispose (GObject *object)
|
||||
g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy);
|
||||
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
|
||||
g_clear_pointer (&display_wayland->linux_dmabuf_feedback, zwp_linux_dmabuf_feedback_v1_destroy);
|
||||
if (display_wayland->linux_dmabuf_formats)
|
||||
munmap (display_wayland->linux_dmabuf_formats, display_wayland->linux_dmabuf_n_formats * 16);
|
||||
|
||||
g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
|
||||
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);
|
||||
@@ -2320,6 +2243,8 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
subpixel_to_string (int layout)
|
||||
{
|
||||
@@ -2366,6 +2291,8 @@ transform_to_string (int transform)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
update_scale (GdkDisplay *display)
|
||||
{
|
||||
|
||||
@@ -71,13 +71,6 @@ typedef enum _GdkWaylandShellVariant
|
||||
GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6
|
||||
} GdkWaylandShellVariant;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t fourcc;
|
||||
uint32_t padding;
|
||||
uint64_t modifier;
|
||||
} LinuxDmabufFormat;
|
||||
|
||||
struct _GdkWaylandDisplay
|
||||
{
|
||||
GdkDisplay parent_instance;
|
||||
@@ -102,10 +95,6 @@ struct _GdkWaylandDisplay
|
||||
struct wl_registry *wl_registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
|
||||
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback;
|
||||
gsize linux_dmabuf_n_formats;
|
||||
LinuxDmabufFormat *linux_dmabuf_formats;
|
||||
struct xdg_wm_base *xdg_wm_base;
|
||||
struct zxdg_shell_v6 *zxdg_shell_v6;
|
||||
struct gtk_shell1 *gtk_shell;
|
||||
|
||||
@@ -340,12 +340,14 @@ gdk_wayland_drag_create_data_source (GdkDrag *drag)
|
||||
|
||||
mimetypes = gdk_content_formats_get_mime_types (formats, &n_mimetypes);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drag_get_display (drag), EVENTS))
|
||||
{
|
||||
char *s = g_strjoinv (" ", (char **)mimetypes);
|
||||
gdk_debug_message ("create data source, mime types=%s", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
wl_data_source_offer (drag_wayland->data_source, GDK_WAYLAND_LOCAL_DND_MIME_TYPE);
|
||||
for (i = 0; i < n_mimetypes; i++)
|
||||
|
||||
@@ -191,12 +191,14 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_drop_read_async);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_drop_get_display (drop), DND))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: read for %s", drop, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
mime_type = gdk_content_formats_match_mime_type (formats,
|
||||
gdk_drop_get_formats (drop));
|
||||
if (mime_type == NULL)
|
||||
|
||||
@@ -75,7 +75,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
WL_SURFACE_OFFSET_SINCE_VERSION)
|
||||
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
|
||||
|
||||
/* We should do this when setting up the EGLSurface, but we don't make_current then */
|
||||
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
|
||||
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
@@ -83,22 +83,6 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_empty_frame (GdkDrawContext *draw_context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (impl->has_pending_subsurface_commits)
|
||||
{
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
{
|
||||
@@ -107,7 +91,6 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
|
||||
draw_context_class->empty_frame = gdk_wayland_gl_context_empty_frame;
|
||||
|
||||
context_class->backend_type = GDK_GL_EGL;
|
||||
}
|
||||
|
||||
@@ -495,6 +495,7 @@ static void
|
||||
print_modifiers (GdkDisplay *display,
|
||||
struct xkb_keymap *keymap)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
int i, j;
|
||||
uint32_t real;
|
||||
struct xkb_state *state;
|
||||
@@ -537,6 +538,7 @@ print_modifiers (GdkDisplay *display,
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
xkb_state_unref (state);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -107,12 +107,14 @@ gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
|
||||
|
||||
gdk_wayland_primary_discard_offer (cb);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (GDK_CLIPBOARD (cb)), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: remote primary claim for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
cb->offer_formats = formats;
|
||||
cb->offer = offer;
|
||||
@@ -268,12 +270,14 @@ gdk_wayland_primary_claim (GdkClipboard *clipboard,
|
||||
{
|
||||
GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (clipboard), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: claim primary (%s) for %s", cb, local ? "local" : "remote", s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
if (local)
|
||||
{
|
||||
GdkWaylandDisplay *wdisplay = GDK_WAYLAND_DISPLAY (gdk_clipboard_get_display (clipboard));
|
||||
@@ -324,12 +328,14 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
|
||||
g_task_set_priority (task, io_priority);
|
||||
g_task_set_source_tag (task, gdk_wayland_primary_read_async);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (gdk_clipboard_get_display (clipboard), CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%p: read for %s", cb, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
mime_type = gdk_content_formats_match_mime_type (formats, cb->offer_formats);
|
||||
if (mime_type == NULL)
|
||||
{
|
||||
|
||||
@@ -222,3 +222,4 @@ void gdk_wayland_surface_update_scale (GdkSurface *surface);
|
||||
|
||||
GdkModifierType gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap,
|
||||
guint32 mods);
|
||||
|
||||
|
||||
@@ -877,6 +877,8 @@ pointer_handle_button (void *data,
|
||||
gdk_wayland_seat_flush_frame_event (seat);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
get_axis_name (uint32_t axis)
|
||||
{
|
||||
@@ -891,6 +893,8 @@ get_axis_name (uint32_t axis)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
pointer_handle_axis (void *data,
|
||||
struct wl_pointer *pointer,
|
||||
@@ -939,6 +943,8 @@ pointer_handle_frame (void *data,
|
||||
gdk_wayland_seat_flush_frame_event (seat);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static const char *
|
||||
get_axis_source_name (enum wl_pointer_axis_source source)
|
||||
{
|
||||
@@ -957,6 +963,8 @@ get_axis_source_name (enum wl_pointer_axis_source source)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
pointer_handle_axis_source (void *data,
|
||||
struct wl_pointer *pointer,
|
||||
@@ -1082,6 +1090,7 @@ get_active_layout (GdkKeymap *keymap)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *
|
||||
get_active_layout_name (GdkKeymap *keymap)
|
||||
{
|
||||
@@ -1091,6 +1100,7 @@ get_active_layout_name (GdkKeymap *keymap)
|
||||
|
||||
return xkb_keymap_layout_get_name (xkb_keymap, get_active_layout (keymap));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
keyboard_handle_keymap (void *data,
|
||||
@@ -1116,6 +1126,7 @@ keyboard_handle_keymap (void *data,
|
||||
|
||||
_gdk_wayland_keymap_update_from_fd (seat->keymap, format, fd, size);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (seat->keymap->display, INPUT))
|
||||
{
|
||||
GString *s = g_string_new ("");
|
||||
@@ -1132,6 +1143,7 @@ keyboard_handle_keymap (void *data,
|
||||
gdk_debug_message ("layouts: %s", s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_signal_emit_by_name (seat->keymap, "keys-changed");
|
||||
g_signal_emit_by_name (seat->keymap, "state-changed");
|
||||
@@ -3423,7 +3435,9 @@ static void
|
||||
tablet_pad_group_handle_done (void *data,
|
||||
struct zwp_tablet_pad_group_v2 *wp_tablet_pad_group)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkWaylandTabletPadGroupData *group = data;
|
||||
#endif
|
||||
|
||||
GDK_SEAT_DEBUG (group->pad->seat, EVENTS,
|
||||
"tablet pad group handle done, pad group = %p",
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
|
||||
|
||||
typedef struct _GdkWaylandSubsurface GdkWaylandSubsurface;
|
||||
typedef struct _GdkWaylandSubsurfaceClass GdkWaylandSubsurfaceClass;
|
||||
|
||||
#define GDK_TYPE_WAYLAND_SUBSURFACE (gdk_wayland_subsurface_get_type ())
|
||||
#define GDK_WAYLAND_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_SUBSURFACE, GdkWaylandSubsurface))
|
||||
#define GDK_WAYLAND_SUBSURFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_SUBSURFACE, GdkWaylandSubsurfaceClass))
|
||||
#define GDK_IS_WAYLAND_SUBSURFACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_SUBSURFACE))
|
||||
#define GDK_WAYLAND_SUBSURFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_WAYLAND_SUBSURFACE, GdkWaylandSubsurfaceClass))
|
||||
|
||||
struct _GdkWaylandSubsurface
|
||||
{
|
||||
GdkSubsurface parent_instance;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct wl_subsurface *subsurface;
|
||||
struct wp_viewport *viewport;
|
||||
|
||||
GdkTexture *texture;
|
||||
cairo_rectangle_int_t dest;
|
||||
|
||||
struct wl_region *opaque_region;
|
||||
|
||||
struct wl_callback *frame_callback;
|
||||
|
||||
gboolean above_parent;
|
||||
};
|
||||
|
||||
struct _GdkWaylandSubsurfaceClass
|
||||
{
|
||||
GdkSubsurfaceClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_wayland_subsurface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gdk_wayland_subsurface_request_frame (GdkSubsurface *subsurface);
|
||||
void gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *subsurface);
|
||||
@@ -1,407 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2023 Red Hat, Inc
|
||||
*
|
||||
* 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 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 Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdksubsurface-wayland-private.h"
|
||||
|
||||
#include "gdkmemoryformatprivate.h"
|
||||
#include "gdkdisplay-wayland.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdksurface-wayland-private.h"
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandSubsurface, gdk_wayland_subsurface, GDK_TYPE_SUBSURFACE)
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_init (GdkWaylandSubsurface *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (object);
|
||||
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
||||
g_clear_pointer (&self->opaque_region, wl_region_destroy);
|
||||
g_clear_pointer (&self->viewport, wp_viewport_destroy);
|
||||
g_clear_pointer (&self->subsurface, wl_subsurface_destroy);
|
||||
g_clear_pointer (&self->surface, wl_surface_destroy);
|
||||
g_clear_pointer (&self->subsurface, wl_subsurface_destroy);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_subsurface_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
dmabuf_buffer_release (void *data,
|
||||
struct wl_buffer *buffer)
|
||||
{
|
||||
GdkTexture *texture = data;
|
||||
|
||||
g_object_unref (texture);
|
||||
wl_buffer_destroy (buffer);
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener dmabuf_buffer_listener = {
|
||||
dmabuf_buffer_release,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct wl_buffer *buffer;
|
||||
gboolean done;
|
||||
} CreateBufferData;
|
||||
|
||||
static void
|
||||
params_buffer_created (void *data,
|
||||
struct zwp_linux_buffer_params_v1 *params,
|
||||
struct wl_buffer *buffer)
|
||||
{
|
||||
CreateBufferData *cd = data;
|
||||
|
||||
cd->buffer = buffer;
|
||||
cd->done = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
params_buffer_failed (void *data,
|
||||
struct zwp_linux_buffer_params_v1 *params)
|
||||
{
|
||||
CreateBufferData *cd = data;
|
||||
|
||||
cd->buffer = NULL;
|
||||
cd->done = TRUE;
|
||||
}
|
||||
|
||||
static const struct zwp_linux_buffer_params_v1_listener params_listener = {
|
||||
params_buffer_created,
|
||||
params_buffer_failed,
|
||||
};
|
||||
|
||||
static struct wl_buffer *
|
||||
get_wl_buffer (GdkWaylandSubsurface *self,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SUBSURFACE (self)->parent));
|
||||
const GdkDmabuf *dmabuf;
|
||||
struct zwp_linux_buffer_params_v1 *params;
|
||||
struct wl_buffer *buffer;
|
||||
CreateBufferData cd = { NULL, FALSE };
|
||||
struct wl_event_queue *event_queue;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
|
||||
params = zwp_linux_dmabuf_v1_create_params (display->linux_dmabuf);
|
||||
|
||||
for (gsize i = 0; i < dmabuf->n_planes; i++)
|
||||
zwp_linux_buffer_params_v1_add (params,
|
||||
dmabuf->planes[i].fd,
|
||||
i,
|
||||
dmabuf->planes[i].offset,
|
||||
dmabuf->planes[i].stride,
|
||||
dmabuf->modifier >> 32,
|
||||
dmabuf->modifier & 0xffffffff);
|
||||
|
||||
event_queue = wl_display_create_queue (display->wl_display);
|
||||
|
||||
wl_proxy_set_queue ((struct wl_proxy *) params, event_queue);
|
||||
|
||||
zwp_linux_buffer_params_v1_add_listener (params, ¶ms_listener, &cd);
|
||||
|
||||
zwp_linux_buffer_params_v1_create (params,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
dmabuf->fourcc,
|
||||
0);
|
||||
|
||||
while (!cd.done)
|
||||
gdk_wayland_display_dispatch_queue (GDK_DISPLAY (display), event_queue);
|
||||
|
||||
wl_event_queue_destroy (event_queue);
|
||||
zwp_linux_buffer_params_v1_destroy (params);
|
||||
|
||||
buffer = cd.buffer;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
wl_proxy_set_queue ((struct wl_proxy *) buffer, NULL);
|
||||
wl_buffer_add_listener (buffer, &dmabuf_buffer_listener, g_object_ref (texture));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_subsurface_attach (GdkSubsurface *sub,
|
||||
GdkTexture *texture,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
gboolean result;
|
||||
struct wl_buffer *buffer = NULL;
|
||||
|
||||
if (sub->parent == NULL)
|
||||
{
|
||||
g_warning ("Can't draw to destroyed subsurface %p", self);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->dest.x = rect->origin.x;
|
||||
self->dest.y = rect->origin.y;
|
||||
self->dest.width = rect->size.width;
|
||||
self->dest.height = rect->size.height;
|
||||
|
||||
if (self->dest.x != rect->origin.x ||
|
||||
self->dest.y != rect->origin.y ||
|
||||
self->dest.width != rect->size.width ||
|
||||
self->dest.height != rect->size.height)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
|
||||
"Non-integer coordinates %g %g %g %g for %dx%d texture, hiding subsurface %p",
|
||||
rect->origin.x, rect->origin.y,
|
||||
rect->size.width, rect->size.height,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
self);
|
||||
}
|
||||
else if (!GDK_IS_DMABUF_TEXTURE (texture))
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
|
||||
"%dx%d %s is not a GdkDmabufTexture, hiding subsurface %p",
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
G_OBJECT_TYPE_NAME (texture),
|
||||
self);
|
||||
}
|
||||
else if (gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_OPAQUE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
|
||||
"Cannot offload non-opaque %dx%d texture, hiding subsurface %p",
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
self);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = get_wl_buffer (self, texture);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
|
||||
"Compositor failed to create wl_buffer for %dx%d texture, hiding subsurface %p",
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
g_set_object (&self->texture, texture);
|
||||
|
||||
wl_subsurface_set_position (self->subsurface, self->dest.x, self->dest.y);
|
||||
wp_viewport_set_destination (self->viewport, self->dest.width, self->dest.height);
|
||||
|
||||
wl_surface_attach (self->surface, buffer, 0, 0);
|
||||
wl_surface_damage_buffer (self->surface,
|
||||
0, 0,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture));
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (sub->parent), OFFLOAD,
|
||||
"Attached %dx%d texture to subsurface %p at %d %d %d %d",
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
self,
|
||||
self->dest.x, self->dest.y,
|
||||
self->dest.width, self->dest.height);
|
||||
|
||||
result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_set_object (&self->texture, NULL);
|
||||
|
||||
wl_surface_attach (self->surface, NULL, 0, 0);
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
wl_surface_commit (self->surface);
|
||||
|
||||
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
|
||||
GDK_WAYLAND_SURFACE (sub->parent)->opaque_region_dirty = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_detach (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
|
||||
if (sub->parent == NULL)
|
||||
{
|
||||
g_warning ("Can't draw to destroyed subsurface %p", self);
|
||||
return;
|
||||
}
|
||||
|
||||
g_set_object (&self->texture, NULL);
|
||||
wl_surface_attach (self->surface, NULL, 0, 0);
|
||||
wl_surface_commit (self->surface);
|
||||
|
||||
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
|
||||
GDK_WAYLAND_SURFACE (sub->parent)->opaque_region_dirty = TRUE;
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
gdk_wayland_subsurface_get_texture (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
|
||||
return self->texture;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_get_rect (GdkSubsurface *sub,
|
||||
graphene_rect_t *rect)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
|
||||
rect->origin.x = self->dest.x;
|
||||
rect->origin.y = self->dest.y;
|
||||
rect->size.width = self->dest.width;
|
||||
rect->size.height = self->dest.height;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_place_above (GdkSubsurface *sub,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
GdkWaylandSubsurface *sib = sibling ? GDK_WAYLAND_SUBSURFACE (sibling) : NULL;
|
||||
gboolean above_parent;
|
||||
|
||||
g_return_if_fail (sibling == NULL || sub->parent == sibling->parent);
|
||||
|
||||
if (sib)
|
||||
{
|
||||
wl_subsurface_place_above (self->subsurface, sib->surface);
|
||||
above_parent = sib->above_parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_subsurface_place_above (self->subsurface,
|
||||
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
|
||||
above_parent = TRUE;
|
||||
}
|
||||
|
||||
if (self->above_parent != above_parent)
|
||||
self->above_parent = above_parent;
|
||||
|
||||
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_place_below (GdkSubsurface *sub,
|
||||
GdkSubsurface *sibling)
|
||||
{
|
||||
GdkWaylandSubsurface *self = GDK_WAYLAND_SUBSURFACE (sub);
|
||||
GdkWaylandSubsurface *sib = sibling ? GDK_WAYLAND_SUBSURFACE (sibling) : NULL;
|
||||
gboolean above_parent;
|
||||
|
||||
g_return_if_fail (sibling == NULL || sub->parent == sibling->parent);
|
||||
|
||||
if (sib)
|
||||
{
|
||||
wl_subsurface_place_below (self->subsurface, sib->surface);
|
||||
above_parent = sib->above_parent;
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_subsurface_place_below (self->subsurface,
|
||||
GDK_WAYLAND_SURFACE (sub->parent)->display_server.wl_surface);
|
||||
above_parent = FALSE;
|
||||
}
|
||||
|
||||
if (self->above_parent != above_parent)
|
||||
self->above_parent = above_parent;
|
||||
|
||||
((GdkWaylandSurface *)sub->parent)->has_pending_subsurface_commits = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_subsurface_is_above_parent (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
return self->above_parent;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_subsurface_class_init (GdkWaylandSubsurfaceClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GdkSubsurfaceClass *subsurface_class = GDK_SUBSURFACE_CLASS (class);
|
||||
|
||||
object_class->finalize = gdk_wayland_subsurface_finalize;
|
||||
|
||||
subsurface_class->attach = gdk_wayland_subsurface_attach;
|
||||
subsurface_class->detach = gdk_wayland_subsurface_detach;
|
||||
subsurface_class->get_texture = gdk_wayland_subsurface_get_texture;
|
||||
subsurface_class->get_rect = gdk_wayland_subsurface_get_rect;
|
||||
subsurface_class->place_above = gdk_wayland_subsurface_place_above;
|
||||
subsurface_class->place_below = gdk_wayland_subsurface_place_below;
|
||||
subsurface_class->is_above_parent = gdk_wayland_subsurface_is_above_parent;
|
||||
};
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSubsurface *sub = data;
|
||||
|
||||
g_assert (((GdkWaylandSubsurface *)sub)->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (sub->parent));
|
||||
|
||||
gdk_wayland_surface_frame_callback (sub->parent, time);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback
|
||||
};
|
||||
|
||||
void
|
||||
gdk_wayland_subsurface_request_frame (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
self->frame_callback = wl_surface_frame (self->surface);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
|
||||
wl_callback_add_listener (self->frame_callback, &frame_listener, self);
|
||||
wl_surface_commit (self->surface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_subsurface_clear_frame_callback (GdkSubsurface *sub)
|
||||
{
|
||||
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
|
||||
|
||||
g_clear_pointer (&self->frame_callback, wl_callback_destroy);
|
||||
}
|
||||
@@ -46,7 +46,6 @@ struct _GdkWaylandSurface
|
||||
|
||||
unsigned int initial_configure_received : 1;
|
||||
unsigned int has_uncommitted_ack_configure : 1;
|
||||
unsigned int has_pending_subsurface_commits : 1;
|
||||
unsigned int mapped : 1;
|
||||
unsigned int awaiting_frame_frozen : 1;
|
||||
|
||||
@@ -123,9 +122,6 @@ void gdk_wayland_surface_get_window_geometry (GdkSurface *surface,
|
||||
void gdk_wayland_surface_freeze_state (GdkSurface *surface);
|
||||
void gdk_wayland_surface_thaw_state (GdkSurface *surface);
|
||||
|
||||
void gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
uint32_t time);
|
||||
|
||||
|
||||
#define GDK_TYPE_WAYLAND_DRAG_SURFACE (gdk_wayland_drag_surface_get_type ())
|
||||
GType gdk_wayland_drag_surface_get_type (void) G_GNUC_CONST;
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdksubsurfaceprivate.h"
|
||||
#include "gdksubsurface-wayland-private.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
@@ -51,9 +48,6 @@
|
||||
#include "gdksurface-wayland-private.h"
|
||||
#include "gdktoplevel-wayland-private.h"
|
||||
|
||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||
|
||||
|
||||
/**
|
||||
* GdkWaylandSurface:
|
||||
*
|
||||
@@ -158,7 +152,7 @@ wl_region_from_cairo_region (GdkWaylandDisplay *display,
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Surface implementation */
|
||||
/* {{{ Surface implementation */
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_init (GdkWaylandSurface *impl)
|
||||
@@ -199,7 +193,7 @@ get_egl_window_size (GdkSurface *surface,
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, GL_FRACTIONAL))
|
||||
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_GL_FRACTIONAL)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OPENGL, "Using fractional scale %g for EGL window", gdk_fractional_scale_to_double (&impl->scale));
|
||||
|
||||
@@ -264,10 +258,12 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
|
||||
_gdk_surface_update_size (surface);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
uint32_t time)
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSurface *surface = data;
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkWaylandDisplay *display_wayland =
|
||||
GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
|
||||
@@ -277,13 +273,10 @@ gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "frame event");
|
||||
GDK_DISPLAY_DEBUG (GDK_DISPLAY (display_wayland), EVENTS, "frame %p", surface);
|
||||
|
||||
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
|
||||
g_assert (impl->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (surface));
|
||||
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
|
||||
gdk_wayland_subsurface_clear_frame_callback (subsurface);
|
||||
}
|
||||
g_clear_pointer (&impl->frame_callback, wl_callback_destroy);
|
||||
|
||||
GDK_WAYLAND_SURFACE_GET_CLASS (impl)->handle_frame (impl);
|
||||
|
||||
@@ -315,26 +308,15 @@ gdk_wayland_surface_frame_callback (GdkSurface *surface,
|
||||
|
||||
timings->complete = TRUE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
#endif
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (void *data,
|
||||
struct wl_callback *callback,
|
||||
uint32_t time)
|
||||
{
|
||||
GdkSurface *surface = data;
|
||||
|
||||
g_assert (GDK_WAYLAND_SURFACE (surface)->frame_callback == callback);
|
||||
g_assert (!GDK_SURFACE_DESTROYED (surface));
|
||||
|
||||
gdk_wayland_surface_frame_callback (surface, time);
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
frame_callback
|
||||
};
|
||||
@@ -396,13 +378,6 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
|
||||
self->frame_callback = wl_surface_frame (self->display_server.wl_surface);
|
||||
wl_proxy_set_queue ((struct wl_proxy *) self->frame_callback, NULL);
|
||||
wl_callback_add_listener (self->frame_callback, &frame_listener, surface);
|
||||
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkSubsurface *subsurface = gdk_surface_get_subsurface (surface, i);
|
||||
gdk_wayland_subsurface_request_frame (subsurface);
|
||||
}
|
||||
|
||||
self->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
|
||||
}
|
||||
|
||||
@@ -428,7 +403,6 @@ gdk_wayland_surface_notify_committed (GdkSurface *surface)
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
impl->has_uncommitted_ack_configure = FALSE;
|
||||
impl->has_pending_subsurface_commits = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -437,9 +411,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (surface->update_freeze_count == 0 &&
|
||||
(impl->has_uncommitted_ack_configure ||
|
||||
impl->has_pending_subsurface_commits))
|
||||
if (surface->update_freeze_count == 0 && impl->has_uncommitted_ack_configure)
|
||||
{
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
@@ -640,25 +612,8 @@ gdk_wayland_surface_sync_opaque_region (GdkSurface *surface)
|
||||
return;
|
||||
|
||||
if (impl->opaque_region != NULL)
|
||||
{
|
||||
if (gdk_surface_get_n_subsurfaces (surface) > 0)
|
||||
{
|
||||
cairo_region_t *region = cairo_region_copy (impl->opaque_region);
|
||||
for (gsize i = 0; i < gdk_surface_get_n_subsurfaces (surface); i++)
|
||||
{
|
||||
GdkWaylandSubsurface *sub = (GdkWaylandSubsurface *)gdk_surface_get_subsurface (surface, i);
|
||||
if (sub->texture != NULL)
|
||||
cairo_region_subtract_rectangle (region, &sub->dest);
|
||||
}
|
||||
|
||||
wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)),
|
||||
region);
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
else
|
||||
wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)),
|
||||
impl->opaque_region);
|
||||
}
|
||||
wl_region = wl_region_from_cairo_region (GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)),
|
||||
impl->opaque_region);
|
||||
|
||||
wl_surface_set_opaque_region (impl->display_server.wl_surface, wl_region);
|
||||
|
||||
@@ -1056,7 +1011,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface)
|
||||
wl_surface_commit (impl->display_server.wl_surface);
|
||||
|
||||
impl->has_uncommitted_ack_configure = FALSE;
|
||||
impl->has_pending_subsurface_commits = FALSE;
|
||||
|
||||
impl->last_sent_window_geometry = (GdkRectangle) { 0 };
|
||||
impl->mapped = FALSE;
|
||||
@@ -1253,8 +1207,6 @@ gdk_wayland_surface_default_hide_surface (GdkWaylandSurface *surface)
|
||||
{
|
||||
}
|
||||
|
||||
static GdkSubsurface *gdk_wayland_surface_create_subsurface (GdkSurface *surface);
|
||||
|
||||
static void
|
||||
gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
|
||||
{
|
||||
@@ -1278,7 +1230,6 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
|
||||
surface_class->get_scale = gdk_wayland_surface_get_scale;
|
||||
surface_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
|
||||
surface_class->request_layout = gdk_wayland_surface_request_layout;
|
||||
surface_class->create_subsurface = gdk_wayland_surface_create_subsurface;
|
||||
|
||||
klass->handle_configure = gdk_wayland_surface_default_handle_configure;
|
||||
klass->handle_frame = gdk_wayland_surface_default_handle_frame;
|
||||
@@ -1354,49 +1305,4 @@ gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
|
||||
}
|
||||
|
||||
/* }}}} */
|
||||
/* {{{ Subsurface */
|
||||
|
||||
static GdkSubsurface *
|
||||
gdk_wayland_surface_create_subsurface (GdkSurface *surface)
|
||||
{
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GdkWaylandDisplay *disp = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandSubsurface *sub;
|
||||
struct wl_region *region;
|
||||
|
||||
if (disp->viewporter == NULL)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Can't use subsurfaces without viewporter");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sub = g_object_new (GDK_TYPE_WAYLAND_SUBSURFACE, NULL);
|
||||
|
||||
sub->surface = wl_compositor_create_surface (disp->compositor);
|
||||
sub->subsurface = wl_subcompositor_get_subsurface (disp->subcompositor,
|
||||
sub->surface,
|
||||
impl->display_server.wl_surface);
|
||||
sub->viewport = wp_viewporter_get_viewport (disp->viewporter, sub->surface);
|
||||
|
||||
/* No input, please */
|
||||
region = wl_compositor_create_region (disp->compositor);
|
||||
wl_surface_set_input_region (sub->surface, region);
|
||||
wl_region_destroy (region);
|
||||
|
||||
/* Keep a max-sized opaque region so we don't have to update it
|
||||
* when the size of the texture changes.
|
||||
*/
|
||||
sub->opaque_region = wl_compositor_create_region (disp->compositor);
|
||||
wl_region_add (sub->opaque_region, 0, 0, G_MAXINT, G_MAXINT);
|
||||
wl_surface_set_opaque_region (sub->surface, sub->opaque_region);
|
||||
|
||||
sub->above_parent = TRUE;
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
|
||||
|
||||
return GDK_SUBSURFACE (sub);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#include "gdkwaylanddisplay.h"
|
||||
#include "gdkwaylandsurface.h"
|
||||
#include "gdksurface-wayland-private.h"
|
||||
#include "gdkprivate-wayland.h"
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandVulkanContext, gdk_wayland_vulkan_context, GDK_TYPE_VULKAN_CONTEXT)
|
||||
@@ -73,22 +72,6 @@ gdk_vulkan_context_wayland_end_frame (GdkDrawContext *context,
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_vulkan_context_wayland_empty_frame (GdkDrawContext *context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
|
||||
|
||||
if (!impl->has_pending_subsurface_commits)
|
||||
return;
|
||||
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_wayland_surface_commit (surface);
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_vulkan_context_class_init (GdkWaylandVulkanContextClass *klass)
|
||||
{
|
||||
@@ -97,7 +80,6 @@ gdk_wayland_vulkan_context_class_init (GdkWaylandVulkanContextClass *klass)
|
||||
|
||||
vulkan_context_class->create_surface = gdk_wayland_vulkan_context_create_surface;
|
||||
draw_context_class->end_frame = gdk_vulkan_context_wayland_end_frame;
|
||||
draw_context_class->empty_frame = gdk_vulkan_context_wayland_empty_frame;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -18,7 +18,6 @@ gdk_wayland_sources = files([
|
||||
'gdkprimary-wayland.c',
|
||||
'gdkseat-wayland.c',
|
||||
'gdksurface-wayland.c',
|
||||
'gdksubsurface-wayland.c',
|
||||
'gdktoplevel-wayland.c',
|
||||
'gdkpopup-wayland.c',
|
||||
'gdkvulkancontext-wayland.c',
|
||||
@@ -68,7 +67,6 @@ proto_sources = [
|
||||
['idle-inhibit', 'unstable', 'v1', ],
|
||||
['xdg-activation', 'staging', 'v1', ],
|
||||
['fractional-scale', 'staging', 'v1', ],
|
||||
['linux-dmabuf', 'unstable', 'v1', ],
|
||||
]
|
||||
|
||||
gdk_wayland_gen_headers = []
|
||||
|
||||
@@ -149,7 +149,7 @@ GTK might also call gdk_clipboard_store_async(), which instructs
|
||||
the W32 backend to put the data into the OS clipboard manager by
|
||||
sending WM_RENDERALLFORMATS to itself and then handling it normally.
|
||||
|
||||
Every time W32 backend gets WM_CLIPBOARDUPDATE,
|
||||
Every time W32 backend gets WM_DRAWCLIPBOARD or WM_CLIPBOARDUPDATE,
|
||||
it calls GetUpdatedClipboardFormats() and GetClipboardSequenceNumber()
|
||||
and caches the results of both. These calls do not require the clipboard
|
||||
to be opened.
|
||||
@@ -245,7 +245,7 @@ When clipboard owner changes, the old owner receives WM_DESTROYCLIPBOARD message
|
||||
the clipboard thread schedules a call to gdk_clipboard_claim_remote()
|
||||
in the main thread, with an empty list of formats,
|
||||
to indicate that the clipboard is now owned by a remote process.
|
||||
Later the OS will send WM_CLIPBOARDUPDATE to indicate
|
||||
Later the OS will send WM_DRAWCLIPBOARD or WM_CLIPBOARDUPDATE to indicate
|
||||
the new clipboard contents (see above).
|
||||
|
||||
DND:
|
||||
@@ -416,6 +416,8 @@ struct _GdkWin32ClipboardThread
|
||||
*/
|
||||
HWND clipboard_opened_for;
|
||||
|
||||
HWND hwnd_next_viewer;
|
||||
|
||||
/* We can't peek the queue or "unpop" queue items,
|
||||
* so the items that we can't act upon (yet) got
|
||||
* to be stored *somewhere*.
|
||||
@@ -1169,7 +1171,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_DESTROY: /* unregister the clipboard listener */
|
||||
case WM_DESTROY: /* remove us from chain */
|
||||
{
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
@@ -1177,15 +1179,34 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
RemoveClipboardFormatListener (hwnd);
|
||||
ChangeClipboardChain (hwnd, clipboard_thread_data->hwnd_next_viewer);
|
||||
PostQuitMessage (0);
|
||||
return 0;
|
||||
}
|
||||
case WM_CHANGECBCHAIN:
|
||||
{
|
||||
HWND hwndRemove = (HWND) wparam; /* handle of window being removed */
|
||||
HWND hwndNext = (HWND) lparam; /* handle of next window in chain */
|
||||
|
||||
if (clipboard_thread_data == NULL)
|
||||
{
|
||||
g_warning ("Clipboard thread got an actionable message with no thread data");
|
||||
return DefWindowProcW (hwnd, message, wparam, lparam);
|
||||
}
|
||||
|
||||
if (hwndRemove == clipboard_thread_data->hwnd_next_viewer)
|
||||
clipboard_thread_data->hwnd_next_viewer = hwndNext == hwnd ? NULL : hwndNext;
|
||||
else if (clipboard_thread_data->hwnd_next_viewer != NULL)
|
||||
return SendMessage (clipboard_thread_data->hwnd_next_viewer, message, wparam, lparam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case WM_DESTROYCLIPBOARD:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case WM_CLIPBOARDUPDATE:
|
||||
case WM_DRAWCLIPBOARD:
|
||||
{
|
||||
HWND hwnd_owner;
|
||||
HWND hwnd_opener;
|
||||
@@ -1207,7 +1228,8 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
|
||||
GDK_NOTE (DND, g_print (" drawclipboard owner: %p; opener %p ", hwnd_owner, hwnd_opener));
|
||||
|
||||
if (GDK_DEBUG_CHECK (DND))
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (_gdk_debug_flags & GDK_DEBUG_DND)
|
||||
{
|
||||
/* FIXME: grab and print clipboard formats without opening the clipboard
|
||||
if (clipboard_thread_data->clipboard_opened_for != INVALID_HANDLE_VALUE ||
|
||||
@@ -1227,6 +1249,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
GDK_NOTE (DND, g_print (" \n"));
|
||||
|
||||
@@ -1249,6 +1272,9 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_owner_changed, NULL, NULL);
|
||||
}
|
||||
|
||||
if (clipboard_thread_data->hwnd_next_viewer != NULL)
|
||||
return SendMessage (clipboard_thread_data->hwnd_next_viewer, message, wparam, lparam);
|
||||
|
||||
/* clear error to avoid confusing SetClipboardViewer() return */
|
||||
SetLastError (0);
|
||||
|
||||
@@ -1360,7 +1386,7 @@ inner_clipboard_window_procedure (HWND hwnd,
|
||||
* OpenClipboard() is required/possible
|
||||
*/
|
||||
GDK_NOTE (DND,
|
||||
g_print (" SetClipboardData (%s, %p)\n",
|
||||
g_print (" SetClipboardData (%s, %p)",
|
||||
_gdk_win32_cf_to_string (wparam),
|
||||
returned_render->main_thread_data_handle));
|
||||
|
||||
@@ -1400,7 +1426,7 @@ _clipboard_window_procedure (HWND hwnd,
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates a hidden window and add a clipboard listener
|
||||
* Creates a hidden window and adds it to the clipboard chain
|
||||
*/
|
||||
static gboolean
|
||||
register_clipboard_notification ()
|
||||
@@ -1426,8 +1452,9 @@ register_clipboard_notification ()
|
||||
goto failed;
|
||||
|
||||
SetLastError (0);
|
||||
clipboard_thread_data->hwnd_next_viewer = SetClipboardViewer (clipboard_thread_data->clipboard_window);
|
||||
|
||||
if (AddClipboardFormatListener (clipboard_thread_data->clipboard_window) == FALSE)
|
||||
if (clipboard_thread_data->hwnd_next_viewer == NULL && GetLastError() != NO_ERROR)
|
||||
{
|
||||
DestroyWindow (clipboard_thread_data->clipboard_window);
|
||||
goto failed;
|
||||
@@ -1435,6 +1462,11 @@ register_clipboard_notification ()
|
||||
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT, clipboard_window_created, (gpointer) clipboard_thread_data->clipboard_window, NULL);
|
||||
|
||||
/* FIXME: http://msdn.microsoft.com/en-us/library/ms649033(v=VS.85).aspx */
|
||||
/* This is only supported by Vista, and not yet by mingw64 */
|
||||
/* if (AddClipboardFormatListener (hwnd) == FALSE) */
|
||||
/* goto failed; */
|
||||
|
||||
return TRUE;
|
||||
|
||||
failed:
|
||||
|
||||
@@ -714,6 +714,8 @@ build_pointer_event_state (MSG *msg)
|
||||
return state;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
static void
|
||||
print_event_state (guint state)
|
||||
{
|
||||
@@ -858,6 +860,8 @@ decode_key_lparam (LPARAM lParam)
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
fixup_event (GdkEvent *event)
|
||||
{
|
||||
@@ -2932,6 +2936,7 @@ gdk_event_translate (MSG *msg,
|
||||
break;
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
char buf[256];
|
||||
GDK_NOTE (EVENTS, (windowpos = (WINDOWPOS *) msg->lParam,
|
||||
@@ -2946,6 +2951,7 @@ gdk_event_translate (MSG *msg,
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y,
|
||||
GetNextWindow (msg->hwnd, GW_HWNDPREV))));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GDK_SURFACE_IS_MAPPED (window))
|
||||
{
|
||||
@@ -2980,6 +2986,7 @@ gdk_event_translate (MSG *msg,
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
windowpos = (WINDOWPOS *) msg->lParam;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
char buf[256];
|
||||
GDK_NOTE (EVENTS, g_print (" %s %s %dx%d@%+d%+d",
|
||||
@@ -2992,6 +2999,7 @@ gdk_event_translate (MSG *msg,
|
||||
buf))))),
|
||||
windowpos->cx, windowpos->cy, windowpos->x, windowpos->y));
|
||||
}
|
||||
#endif
|
||||
|
||||
impl = GDK_WIN32_SURFACE (window);
|
||||
|
||||
|
||||
@@ -339,6 +339,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if G_ENABLE_DEBUG
|
||||
{
|
||||
int major, minor;
|
||||
gdk_gl_context_get_version (context, &major, &minor);
|
||||
@@ -356,6 +357,7 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
||||
display_win32->hasWglEXTSwapControl ? "yes" : "no",
|
||||
display_win32->hasWglOMLSyncControl ? "yes" : "no"));
|
||||
}
|
||||
#endif
|
||||
|
||||
wglMakeCurrent (NULL, NULL);
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ _gdk_other_api_failed (const char *where,
|
||||
}
|
||||
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
/*
|
||||
* Like g_strdup_printf, but to a static buffer. Return value does not
|
||||
* have to be g_free()d. The buffer is of bounded size and reused
|
||||
@@ -794,3 +796,5 @@ _gdk_win32_rect_to_string (const RECT *rect)
|
||||
(rect->right - rect->left), (rect->bottom - rect->top),
|
||||
rect->left, rect->top);
|
||||
}
|
||||
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
@@ -31,12 +31,20 @@
|
||||
|
||||
/* Old debug macros */
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
#define GDK_NOTE(type,action) \
|
||||
G_STMT_START { \
|
||||
if (GDK_DEBUG_CHECK (type)) \
|
||||
{ action; }; \
|
||||
} G_STMT_END
|
||||
|
||||
#else
|
||||
|
||||
#define GDK_NOTE(type,action)
|
||||
|
||||
#endif
|
||||
|
||||
/* According to
|
||||
* http://blog.airesoft.co.uk/2009/11/wm_messages/
|
||||
* this is the actual internal name MS uses for this undocumented message.
|
||||
@@ -94,6 +102,7 @@ gboolean _gdk_modal_blocked (GdkSurface *window);
|
||||
gboolean gdk_win32_ensure_com (void);
|
||||
gboolean gdk_win32_ensure_ole (void);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
void _gdk_win32_print_dc (HDC hdc);
|
||||
|
||||
char *_gdk_win32_surface_state_to_string (GdkToplevelState state);
|
||||
@@ -108,6 +117,7 @@ char *_gdk_win32_cf_to_string (UINT format);
|
||||
char *_gdk_win32_rect_to_string (const RECT *rect);
|
||||
|
||||
void _gdk_win32_print_event (GdkEvent *event);
|
||||
#endif
|
||||
|
||||
void _gdk_win32_api_failed (const char *where,
|
||||
const char *api);
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#include "gdkprivate.h"
|
||||
|
||||
#include <glib.h>
|
||||
#ifdef HAVE_DESKTOPAPPINFO
|
||||
#include <gio/gdesktopappinfo.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@@ -353,10 +355,11 @@ gdk_x11_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
|
||||
workspace_str = g_strdup_printf ("%d", ctx->workspace);
|
||||
else
|
||||
workspace_str = NULL;
|
||||
|
||||
#ifdef HAVE_DESKTOPAPPINFO
|
||||
if (G_IS_DESKTOP_APP_INFO (info))
|
||||
application_id = g_desktop_app_info_get_filename (G_DESKTOP_APP_INFO (info));
|
||||
else
|
||||
#endif
|
||||
application_id = NULL;
|
||||
|
||||
startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu",
|
||||
|
||||
@@ -65,6 +65,7 @@ print_atoms (GdkX11Clipboard *cb,
|
||||
const Atom *atoms,
|
||||
gsize n_atoms)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkDisplay *display = gdk_clipboard_get_display (GDK_CLIPBOARD (cb));
|
||||
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, CLIPBOARD))
|
||||
@@ -81,6 +82,7 @@ print_atoms (GdkX11Clipboard *cb,
|
||||
gdk_debug_message ("%s", str->str);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -328,12 +330,14 @@ gdk_x11_clipboard_request_targets_finish (GObject *source_object,
|
||||
formats = gdk_x11_clipboard_formats_from_atoms (display,
|
||||
g_bytes_get_data (bytes, NULL),
|
||||
g_bytes_get_size (bytes) / sizeof (Atom));
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, CLIPBOARD))
|
||||
{
|
||||
char *s = gdk_content_formats_to_string (formats);
|
||||
gdk_debug_message ("%s: got formats: %s", cb->selection, s);
|
||||
g_free (s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* union with previously loaded formats */
|
||||
formats = gdk_content_formats_union (formats, gdk_clipboard_get_formats (GDK_CLIPBOARD (cb)));
|
||||
@@ -477,16 +481,20 @@ gdk_x11_clipboard_xevent (GdkDisplay *display,
|
||||
|
||||
case SelectionRequest:
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *target, *property;
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.selection != cb->xselection)
|
||||
return FALSE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
target = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.target);
|
||||
if (xevent->xselectionrequest.property == None)
|
||||
property = target;
|
||||
else
|
||||
property = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.property);
|
||||
#endif
|
||||
|
||||
if (!gdk_clipboard_is_local (GDK_CLIPBOARD (cb)))
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char notify_modes[][19] = {
|
||||
"NotifyNormal",
|
||||
"NotifyGrab",
|
||||
@@ -56,6 +57,7 @@ static const char notify_details[][23] = {
|
||||
"NotifyPointerRoot",
|
||||
"NotifyDetailNone"
|
||||
};
|
||||
#endif
|
||||
|
||||
#define HAS_FOCUS(toplevel) \
|
||||
((toplevel)->has_focus || (toplevel)->has_pointer_focus)
|
||||
@@ -224,6 +226,7 @@ translate_valuator_class (GdkDisplay *display,
|
||||
}
|
||||
|
||||
_gdk_device_add_axis (device, use, min, max, resolution);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, INPUT))
|
||||
{
|
||||
const char *label;
|
||||
@@ -235,6 +238,7 @@ translate_valuator_class (GdkDisplay *display,
|
||||
|
||||
gdk_debug_message ("\n\taxis: %s %s", label, use == GDK_AXIS_IGNORE ? "(ignored)" : "(used)");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -517,6 +521,7 @@ create_device (GdkX11DeviceManagerXI2 *device_manager,
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, INPUT))
|
||||
{
|
||||
const char *type_names[] = { "logical", "physical", "floating" };
|
||||
@@ -528,6 +533,7 @@ create_device (GdkX11DeviceManagerXI2 *device_manager,
|
||||
dev->use == XIMasterPointer,
|
||||
num_touches);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dev->use != XIMasterKeyboard &&
|
||||
dev->use != XIMasterPointer)
|
||||
@@ -1913,6 +1919,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
GdkTouchpadGesturePhase phase;
|
||||
double x, y;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *event_name = "";
|
||||
switch (xev->evtype)
|
||||
{
|
||||
@@ -1928,6 +1935,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
GDK_DEBUG (EVENTS, "pinch gesture %s:\twindow %ld\n\tfinger_count: %u%s",
|
||||
event_name,
|
||||
@@ -1971,6 +1979,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
GdkTouchpadGesturePhase phase;
|
||||
double x, y;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *event_name = "";
|
||||
switch (xev->evtype)
|
||||
{
|
||||
@@ -1986,6 +1995,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
GDK_DEBUG (EVENTS, "swipe gesture %s:\twindow %ld\n\tfinger_count: %u%s",
|
||||
event_name,
|
||||
|
||||
@@ -745,6 +745,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
break;
|
||||
|
||||
case VisibilityNotify:
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, EVENTS))
|
||||
switch (xevent->xvisibility.state)
|
||||
{
|
||||
@@ -763,6 +764,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
/* not handled */
|
||||
break;
|
||||
|
||||
@@ -1227,11 +1229,13 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
|
||||
timings->refresh_interval = refresh_interval;
|
||||
|
||||
timings->complete = TRUE;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, FRAMES))
|
||||
_gdk_frame_clock_debug_print_timings (clock, timings);
|
||||
|
||||
if (GDK_PROFILER_IS_RUNNING)
|
||||
_gdk_frame_clock_add_timings_to_profiler (clock, timings);
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1658,16 +1658,20 @@ gdk_x11_drag_xevent (GdkDisplay *display,
|
||||
case SelectionRequest:
|
||||
{
|
||||
GdkContentFormats *formats;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
const char *target, *property;
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.selection != xselection)
|
||||
return FALSE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
target = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.target);
|
||||
if (xevent->xselectionrequest.property == None)
|
||||
property = target;
|
||||
else
|
||||
property = gdk_x11_get_xatom_name_for_display (display, xevent->xselectionrequest.property);
|
||||
#endif
|
||||
|
||||
if (xevent->xselectionrequest.requestor == None)
|
||||
{
|
||||
|
||||
@@ -293,6 +293,7 @@ gdk_x11_drop_finalize (GObject *object)
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static void
|
||||
print_target_list (GdkContentFormats *formats)
|
||||
{
|
||||
@@ -300,6 +301,7 @@ print_target_list (GdkContentFormats *formats)
|
||||
g_message ("DND formats: %s", name);
|
||||
g_free (name);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
/*************************************************************
|
||||
***************************** XDND **************************
|
||||
@@ -409,6 +411,7 @@ gdk_x11_drop_read_actions (GdkDrop *drop)
|
||||
|
||||
drop_x11->xdnd_have_actions = TRUE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, DND))
|
||||
{
|
||||
GString *action_str = g_string_new (NULL);
|
||||
@@ -425,6 +428,7 @@ gdk_x11_drop_read_actions (GdkDrop *drop)
|
||||
g_message("Xdnd actions = %s", action_str->str);
|
||||
g_string_free (action_str, TRUE);
|
||||
}
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
}
|
||||
|
||||
if (data)
|
||||
@@ -551,8 +555,10 @@ xdnd_enter_filter (GdkSurface *surface,
|
||||
content_formats = gdk_content_formats_new ((const char **) formats->pdata, formats->len);
|
||||
g_ptr_array_unref (formats);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, DND))
|
||||
print_target_list (content_formats);
|
||||
#endif /* G_ENABLE_DEBUG */
|
||||
|
||||
drag = gdk_x11_drag_find (display, source_window, GDK_SURFACE_XID (surface));
|
||||
|
||||
|
||||
@@ -176,7 +176,9 @@ gdk_x11_selection_input_stream_read (GInputStream *input_stream,
|
||||
GError **error)
|
||||
{
|
||||
GdkX11SelectionInputStream *stream = GDK_X11_SELECTION_INPUT_STREAM (input_stream);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GdkX11SelectionInputStreamPrivate *priv = gdk_x11_selection_input_stream_get_instance_private (stream);
|
||||
#endif
|
||||
gssize written;
|
||||
|
||||
GDK_DISPLAY_DEBUG (priv->display, SELECTION,
|
||||
|
||||
@@ -653,6 +653,7 @@ print_atoms (GdkDisplay *display,
|
||||
const Atom *atoms,
|
||||
gsize n_atoms)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GDK_DISPLAY_DEBUG_CHECK (display, CLIPBOARD))
|
||||
{
|
||||
GString *str;
|
||||
@@ -665,6 +666,7 @@ print_atoms (GdkDisplay *display,
|
||||
gdk_debug_message ("%s", str->str);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -273,7 +273,6 @@ collect_reused_child_nodes (GskRenderer *renderer,
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
|
||||
default:
|
||||
|
||||
@@ -804,11 +803,6 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer,
|
||||
}
|
||||
return;
|
||||
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
gsk_broadway_renderer_add_node (renderer,
|
||||
gsk_subsurface_node_get_child (node), offset_x, offset_y, clip_bounds);
|
||||
return;
|
||||
|
||||
/* Generic nodes */
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
|
||||
@@ -76,8 +76,7 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
|
||||
g_assert (self != NULL);
|
||||
g_assert (target == GL_TEXTURE_1D ||
|
||||
target == GL_TEXTURE_2D ||
|
||||
target == GL_TEXTURE_3D ||
|
||||
target == GL_TEXTURE_EXTERNAL_OES);
|
||||
target == GL_TEXTURE_3D);
|
||||
g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16);
|
||||
g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures));
|
||||
|
||||
|
||||
@@ -29,9 +29,6 @@ typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
|
||||
typedef struct _GskGLBindTexture GskGLBindTexture;
|
||||
|
||||
#define GSK_GL_N_FILTERS 3
|
||||
#define SAMPLER_EXTERNAL 9
|
||||
|
||||
G_STATIC_ASSERT (SAMPLER_EXTERNAL >= GSK_GL_N_FILTERS * GSK_GL_N_FILTERS);
|
||||
|
||||
static inline guint
|
||||
filter_index (GLint filter)
|
||||
|
||||
+18
-42
@@ -282,10 +282,7 @@ snapshot_attachments (const GskGLAttachmentState *state,
|
||||
{
|
||||
bind[count].id = state->textures[i].id;
|
||||
bind[count].texture = state->textures[i].texture;
|
||||
if (state->textures[i].target == GL_TEXTURE_EXTERNAL_OES)
|
||||
bind[count].sampler = SAMPLER_EXTERNAL;
|
||||
else
|
||||
bind[count].sampler = state->textures[i].sampler;
|
||||
bind[count].sampler = state->textures[i].sampler;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -609,7 +606,6 @@ gsk_gl_command_queue_begin_draw (GskGLCommandQueue *self,
|
||||
batch->any.next_batch_index = -1;
|
||||
batch->any.viewport.width = width;
|
||||
batch->any.viewport.height = height;
|
||||
batch->draw.blend = 1;
|
||||
batch->draw.framebuffer = 0;
|
||||
batch->draw.uniform_count = 0;
|
||||
batch->draw.uniform_offset = self->batch_uniforms.len;
|
||||
@@ -686,7 +682,6 @@ gsk_gl_command_queue_end_draw (GskGLCommandQueue *self)
|
||||
last_batch->any.program == batch->any.program &&
|
||||
last_batch->any.viewport.width == batch->any.viewport.width &&
|
||||
last_batch->any.viewport.height == batch->any.viewport.height &&
|
||||
last_batch->draw.blend == batch->draw.blend &&
|
||||
last_batch->draw.framebuffer == batch->draw.framebuffer &&
|
||||
last_batch->draw.vbo_offset + last_batch->draw.vbo_count == batch->draw.vbo_offset &&
|
||||
last_batch->draw.vbo_count + batch->draw.vbo_count <= 0xffff &&
|
||||
@@ -1062,8 +1057,10 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
|
||||
gsk_gl_command_queue_make_current (self);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
gsk_gl_profiler_begin_gpu_region (self->gl_profiler);
|
||||
gsk_profiler_timer_begin (self->profiler, self->metrics.cpu_time);
|
||||
#endif
|
||||
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
@@ -1106,7 +1103,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
(void *) G_STRUCT_OFFSET (GskGLDrawVertex, color2));
|
||||
|
||||
/* Setup initial scissor clip */
|
||||
if (scissor != NULL && cairo_region_num_rectangles (scissor) > 0)
|
||||
if (scissor != NULL)
|
||||
{
|
||||
cairo_rectangle_int_t r;
|
||||
|
||||
@@ -1193,23 +1190,12 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
s->sync = NULL;
|
||||
}
|
||||
|
||||
if (bind->sampler == SAMPLER_EXTERNAL)
|
||||
glBindTexture (GL_TEXTURE_EXTERNAL_OES, bind->id);
|
||||
else
|
||||
glBindTexture (GL_TEXTURE_2D, bind->id);
|
||||
glBindTexture (GL_TEXTURE_2D, bind->id);
|
||||
textures[bind->texture] = bind->id;
|
||||
if (!self->has_samplers)
|
||||
{
|
||||
if (bind->sampler == SAMPLER_EXTERNAL)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1219,16 +1205,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
glBindSampler (bind->texture, self->samplers[bind->sampler]);
|
||||
else
|
||||
{
|
||||
if (bind->sampler == SAMPLER_EXTERNAL)
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
|
||||
}
|
||||
samplers[bind->texture] = bind->sampler;
|
||||
}
|
||||
@@ -1249,13 +1227,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
n_uniforms += batch->draw.uniform_count;
|
||||
}
|
||||
|
||||
if (batch->draw.blend == 0)
|
||||
glDisable (GL_BLEND);
|
||||
|
||||
glDrawArrays (GL_TRIANGLES, batch->draw.vbo_offset, batch->draw.vbo_count);
|
||||
|
||||
if (batch->draw.blend == 0)
|
||||
glEnable (GL_BLEND);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1294,6 +1267,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
gdk_profiler_set_int_counter (self->metrics.n_uploads, self->n_uploads);
|
||||
gdk_profiler_set_int_counter (self->metrics.queue_depth, self->batches.len);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
{
|
||||
gint64 start_time G_GNUC_UNUSED = gsk_profiler_timer_get_start (self->profiler, self->metrics.cpu_time);
|
||||
gint64 cpu_time = gsk_profiler_timer_end (self->profiler, self->metrics.cpu_time);
|
||||
@@ -1305,6 +1279,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
|
||||
|
||||
gsk_profiler_push_samples (self->profiler);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1349,7 +1324,7 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
|
||||
if (self->attachments->textures[i].id != 0)
|
||||
{
|
||||
glActiveTexture (GL_TEXTURE0 + i);
|
||||
glBindTexture (self->attachments->textures[i].target, 0);
|
||||
glBindTexture (GL_TEXTURE_2D, 0);
|
||||
|
||||
self->attachments->textures[i].id = 0;
|
||||
self->attachments->textures[i].changed = FALSE;
|
||||
@@ -1426,7 +1401,7 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture_id);
|
||||
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
@@ -1454,9 +1429,8 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
|
||||
}
|
||||
|
||||
/* Restore the previous texture if it was set */
|
||||
if (self->attachments->textures[0].id != 0 &&
|
||||
self->attachments->textures[0].target == GL_TEXTURE_2D)
|
||||
glBindTexture (self->attachments->textures[0].target, self->attachments->textures[0].id);
|
||||
if (self->attachments->textures[0].id != 0)
|
||||
glBindTexture (GL_TEXTURE_2D, self->attachments->textures[0].id);
|
||||
|
||||
return (int)texture_id;
|
||||
}
|
||||
@@ -1622,7 +1596,7 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
|
||||
/* Only apply swizzle if really needed, might not even be
|
||||
* supported if default values are set
|
||||
*/
|
||||
if (gl_swizzle[0] != GL_RED || gl_swizzle[1] != GL_GREEN || gl_swizzle[2] != GL_BLUE || gl_swizzle[3] != GL_ALPHA)
|
||||
if (gl_swizzle[0] != GL_RED || gl_swizzle[1] != GL_GREEN || gl_swizzle[2] != GL_BLUE)
|
||||
{
|
||||
/* Set each channel independently since GLES 3.0 doesn't support the iv method */
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, gl_swizzle[0]);
|
||||
@@ -1719,6 +1693,7 @@ void
|
||||
gsk_gl_command_queue_set_profiler (GskGLCommandQueue *self,
|
||||
GskProfiler *profiler)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
|
||||
g_assert (GSK_IS_PROFILER (profiler));
|
||||
|
||||
@@ -1737,4 +1712,5 @@ gsk_gl_command_queue_set_profiler (GskGLCommandQueue *self,
|
||||
self->metrics.n_programs = gdk_profiler_define_int_counter ("programs", "Number of program changes");
|
||||
self->metrics.queue_depth = gdk_profiler_define_int_counter ("gl-queue-depth", "Depth of GL command batches");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ typedef struct _GskGLCommandBind
|
||||
*/
|
||||
guint texture : 4;
|
||||
|
||||
/* the sampler to use. We set sampler to 15 to indicate external textures */
|
||||
guint sampler : 4;
|
||||
|
||||
/* The identifier for the texture created with glGenTextures(). */
|
||||
@@ -101,15 +100,13 @@ typedef struct _GskGLCommandDraw
|
||||
{
|
||||
GskGLCommandBatchAny head;
|
||||
|
||||
guint blend : 1;
|
||||
|
||||
/* There doesn't seem to be a limit on the framebuffer identifier that
|
||||
* can be returned, so we have to use a whole unsigned for the framebuffer
|
||||
* we are drawing to. When processing batches, we check to see if this
|
||||
* changes and adjust the render target accordingly. Some sorting is
|
||||
* performed to reduce the amount we change framebuffers.
|
||||
*/
|
||||
guint framebuffer : 31;
|
||||
guint framebuffer;
|
||||
|
||||
/* The number of uniforms to change. This must be less than or equal to
|
||||
* GL_MAX_UNIFORM_LOCATIONS but only guaranteed up to 1024 by any OpenGL
|
||||
@@ -237,13 +234,8 @@ struct _GskGLCommandQueue
|
||||
|
||||
/* Array of samplers that we use for mag/min filter handling. It is indexed
|
||||
* by the sampler_index() function.
|
||||
*
|
||||
* Note that when samplers are not supported (hello GLES), we fall back to
|
||||
* setting the texture filter, but that needs to be done for every texture.
|
||||
*
|
||||
* Also note that we don't use all of these samplers since some combinations
|
||||
* are invalid. An index of SAMPLER_EXTERNAL is used to indicate an external
|
||||
* texture, which needs special sampler treatment.
|
||||
*/
|
||||
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
|
||||
|
||||
|
||||
+7
-15
@@ -54,7 +54,6 @@ struct _GskGLCompiler
|
||||
|
||||
guint gl3 : 1;
|
||||
guint gles : 1;
|
||||
guint gles3 : 1;
|
||||
guint legacy : 1;
|
||||
guint debug_shaders : 1;
|
||||
};
|
||||
@@ -135,10 +134,7 @@ gsk_gl_compiler_new (GskGLDriver *driver,
|
||||
gdk_gl_context_get_version (context, &maj, &min);
|
||||
|
||||
if (maj >= 3)
|
||||
{
|
||||
self->glsl_version = SHADER_VERSION_GLES3;
|
||||
self->gles3 = TRUE;
|
||||
}
|
||||
self->glsl_version = SHADER_VERSION_GLES3;
|
||||
else
|
||||
{
|
||||
self->glsl_version = SHADER_VERSION_GLES;
|
||||
@@ -547,7 +543,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
const char *legacy = "";
|
||||
const char *gl3 = "";
|
||||
const char *gles = "";
|
||||
const char *gles3 = "";
|
||||
int program_id;
|
||||
int vertex_id;
|
||||
int fragment_id;
|
||||
@@ -574,17 +569,15 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
if (self->gles)
|
||||
gles = "#define GSK_GLES 1\n";
|
||||
|
||||
if (self->gles3)
|
||||
gles3 = "#define GSK_GLES3 1\n";
|
||||
|
||||
if (self->gl3)
|
||||
gl3 = "#define GSK_GL3 1\n";
|
||||
|
||||
vertex_id = glCreateShader (GL_VERTEX_SHADER);
|
||||
glShaderSource (vertex_id,
|
||||
11,
|
||||
10,
|
||||
(const char *[]) {
|
||||
version, debug, legacy, gl3, gles, gles3, clip,
|
||||
version, debug, legacy, gl3, gles,
|
||||
clip,
|
||||
get_shader_string (self->all_preamble),
|
||||
get_shader_string (self->vertex_preamble),
|
||||
get_shader_string (self->vertex_source),
|
||||
@@ -596,7 +589,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
strlen (legacy),
|
||||
strlen (gl3),
|
||||
strlen (gles),
|
||||
strlen (gles3),
|
||||
strlen (clip),
|
||||
g_bytes_get_size (self->all_preamble),
|
||||
g_bytes_get_size (self->vertex_preamble),
|
||||
@@ -615,9 +607,10 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
|
||||
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
|
||||
glShaderSource (fragment_id,
|
||||
11,
|
||||
10,
|
||||
(const char *[]) {
|
||||
version, debug, legacy, gl3, gles, gles3, clip,
|
||||
version, debug, legacy, gl3, gles,
|
||||
clip,
|
||||
get_shader_string (self->all_preamble),
|
||||
get_shader_string (self->fragment_preamble),
|
||||
get_shader_string (self->fragment_source),
|
||||
@@ -629,7 +622,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
|
||||
strlen (legacy),
|
||||
strlen (gl3),
|
||||
strlen (gles),
|
||||
strlen (gles3),
|
||||
strlen (clip),
|
||||
g_bytes_get_size (self->all_preamble),
|
||||
g_bytes_get_size (self->fragment_preamble),
|
||||
|
||||
+33
-221
@@ -44,8 +44,6 @@
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
#include <gdk/gdkdmabuftextureprivate.h>
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
|
||||
|
||||
@@ -226,8 +224,6 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
GSK_GL_DELETE_PROGRAM(name); \
|
||||
GSK_GL_DELETE_PROGRAM(name ## _no_clip); \
|
||||
GSK_GL_DELETE_PROGRAM(name ## _rect_clip);
|
||||
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) \
|
||||
GSK_GL_DELETE_PROGRAM(name);
|
||||
#define GSK_GL_DELETE_PROGRAM(name) \
|
||||
G_STMT_START { \
|
||||
if (self->name) \
|
||||
@@ -242,7 +238,6 @@ gsk_gl_driver_dispose (GObject *object)
|
||||
#undef GSK_GL_SHADER_JOINED
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
|
||||
|
||||
if (self->shader_cache != NULL)
|
||||
{
|
||||
@@ -378,11 +373,6 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name, uniforms, "");
|
||||
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, sources, uniforms) \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \
|
||||
sources \
|
||||
GSK_GL_COMPILE_PROGRAM(name, uniforms, "#define NO_CLIP 1\n");
|
||||
#define GSK_GL_COMPILE_PROGRAM(name, uniforms, clip) \
|
||||
G_STMT_START { \
|
||||
GskGLProgram *program; \
|
||||
@@ -410,7 +400,6 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
} G_STMT_END;
|
||||
# include "gskglprograms.defs"
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_SHADER_SINGLE
|
||||
#undef GSK_GL_SHADER_JOINED
|
||||
@@ -713,165 +702,6 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
|
||||
static void
|
||||
set_viewport_for_size (GskGLDriver *self,
|
||||
GskGLProgram *program,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
float viewport[4] = { 0, 0, width, height };
|
||||
|
||||
gsk_gl_uniform_state_set4fv (program->uniforms,
|
||||
program->program_info,
|
||||
UNIFORM_SHARED_VIEWPORT, 0,
|
||||
1,
|
||||
(const float *)&viewport);
|
||||
self->stamps[UNIFORM_SHARED_VIEWPORT]++;
|
||||
}
|
||||
|
||||
#define ORTHO_NEAR_PLANE -10000
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
|
||||
static void
|
||||
set_projection_for_size (GskGLDriver *self,
|
||||
GskGLProgram *program,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
graphene_matrix_t projection;
|
||||
|
||||
graphene_matrix_init_ortho (&projection, 0, width, 0, height, ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE);
|
||||
graphene_matrix_scale (&projection, 1, -1, 1);
|
||||
|
||||
gsk_gl_uniform_state_set_matrix (program->uniforms,
|
||||
program->program_info,
|
||||
UNIFORM_SHARED_PROJECTION, 0,
|
||||
&projection);
|
||||
self->stamps[UNIFORM_SHARED_PROJECTION]++;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_modelview (GskGLDriver *self,
|
||||
GskGLProgram *program)
|
||||
{
|
||||
graphene_matrix_t modelview;
|
||||
|
||||
graphene_matrix_init_identity (&modelview);
|
||||
|
||||
gsk_gl_uniform_state_set_matrix (program->uniforms,
|
||||
program->program_info,
|
||||
UNIFORM_SHARED_MODELVIEW, 0,
|
||||
&modelview);
|
||||
self->stamps[UNIFORM_SHARED_MODELVIEW]++;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_rect (GskGLCommandQueue *command_queue,
|
||||
float min_x,
|
||||
float min_y,
|
||||
float max_x,
|
||||
float max_y)
|
||||
{
|
||||
GskGLDrawVertex *vertices = gsk_gl_command_queue_add_vertices (command_queue);
|
||||
float min_u = 0;
|
||||
float max_u = 1;
|
||||
float min_v = 1;
|
||||
float max_v = 0;
|
||||
guint16 c = FP16_ZERO;
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { min_u, min_v }, .color = { c, c, c, c } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { min_u, max_v }, .color = { c, c, c, c } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .uv = { max_u, max_v }, .color = { c, c, c, c } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { min_u, max_v }, .color = { c, c, c, c } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
|
||||
}
|
||||
|
||||
static unsigned int release_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target,
|
||||
gboolean release_texture,
|
||||
gboolean cache_texture);
|
||||
|
||||
static guint
|
||||
gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
GdkDmabufTexture *texture)
|
||||
{
|
||||
GdkGLContext *context = self->command_queue->context;
|
||||
int max_texture_size = self->command_queue->max_texture_size;
|
||||
const GdkDmabuf *dmabuf;
|
||||
guint texture_id;
|
||||
int width, height;
|
||||
GskGLProgram *program;
|
||||
GskGLRenderTarget *render_target;
|
||||
guint prev_fbo;
|
||||
gboolean external;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
width = gdk_texture_get_width (GDK_TEXTURE (texture));
|
||||
height = gdk_texture_get_height (GDK_TEXTURE (texture));
|
||||
|
||||
if (width > max_texture_size || height > max_texture_size)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_gl_context_get_display (context), DMABUF,
|
||||
"Can't import dmabuf bigger than MAX_TEXTURE_SIZE (%d)",
|
||||
max_texture_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf (context,
|
||||
width, height,
|
||||
dmabuf,
|
||||
&external);
|
||||
if (texture_id == 0)
|
||||
return 0;
|
||||
|
||||
if (!external)
|
||||
return texture_id;
|
||||
|
||||
gsk_gl_driver_autorelease_texture (self, texture_id);
|
||||
|
||||
program = self->external;
|
||||
|
||||
gsk_gl_driver_create_render_target (self, width, height, GL_RGBA8, &render_target);
|
||||
|
||||
prev_fbo = gsk_gl_command_queue_bind_framebuffer (self->command_queue, render_target->framebuffer_id);
|
||||
gsk_gl_command_queue_clear (self->command_queue, 0, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
if (gsk_gl_command_queue_begin_draw (self->command_queue, program->program_info, width, height))
|
||||
{
|
||||
set_projection_for_size (self, program, width, height);
|
||||
set_viewport_for_size (self, program, width, height);
|
||||
reset_modelview (self, program);
|
||||
|
||||
gsk_gl_program_set_uniform_texture (program,
|
||||
UNIFORM_EXTERNAL_SOURCE, 0,
|
||||
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
|
||||
|
||||
draw_rect (self->command_queue, 0, 0, width, height);
|
||||
|
||||
gsk_gl_command_queue_end_draw (self->command_queue);
|
||||
}
|
||||
|
||||
gsk_gl_command_queue_bind_framebuffer (self->command_queue, prev_fbo);
|
||||
|
||||
return release_render_target (self, render_target, FALSE, FALSE);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static guint
|
||||
gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
GdkDmabufTexture *texture)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_DMABUF && HAVE_EGL */
|
||||
|
||||
/**
|
||||
* gsk_gl_driver_load_texture:
|
||||
* @self: a `GdkTexture`
|
||||
@@ -928,11 +758,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
|
||||
return t->texture_id;
|
||||
}
|
||||
|
||||
if (GDK_IS_DMABUF_TEXTURE (texture))
|
||||
{
|
||||
texture_id = gsk_gl_driver_import_dmabuf_texture (self, GDK_DMABUF_TEXTURE (texture));
|
||||
}
|
||||
else if (GDK_IS_GL_TEXTURE (texture))
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
{
|
||||
GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
|
||||
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
|
||||
@@ -1135,47 +961,6 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
release_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target,
|
||||
gboolean release_texture,
|
||||
gboolean cache_texture)
|
||||
{
|
||||
guint texture_id;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
|
||||
g_return_val_if_fail (render_target != NULL, 0);
|
||||
|
||||
if (release_texture)
|
||||
{
|
||||
texture_id = 0;
|
||||
g_ptr_array_add (self->render_targets, render_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture_id = render_target->texture_id;
|
||||
|
||||
if (cache_texture)
|
||||
{
|
||||
GskGLTexture *texture;
|
||||
|
||||
texture = gsk_gl_texture_new (render_target->texture_id,
|
||||
render_target->width,
|
||||
render_target->height,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture_id),
|
||||
g_steal_pointer (&texture));
|
||||
}
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
g_free (render_target);
|
||||
|
||||
}
|
||||
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_gl_driver_release_render_target:
|
||||
* @self: a `GskGLDriver`
|
||||
@@ -1201,7 +986,36 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target,
|
||||
gboolean release_texture)
|
||||
{
|
||||
return release_render_target (self, render_target, release_texture, TRUE);
|
||||
guint texture_id;
|
||||
|
||||
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
|
||||
g_return_val_if_fail (render_target != NULL, 0);
|
||||
|
||||
if (release_texture)
|
||||
{
|
||||
texture_id = 0;
|
||||
g_ptr_array_add (self->render_targets, render_target);
|
||||
}
|
||||
else
|
||||
{
|
||||
GskGLTexture *texture;
|
||||
|
||||
texture_id = render_target->texture_id;
|
||||
|
||||
texture = gsk_gl_texture_new (render_target->texture_id,
|
||||
render_target->width,
|
||||
render_target->height,
|
||||
self->current_frame_id);
|
||||
g_hash_table_insert (self->textures,
|
||||
GUINT_TO_POINTER (texture_id),
|
||||
g_steal_pointer (&texture));
|
||||
|
||||
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
|
||||
g_free (render_target);
|
||||
|
||||
}
|
||||
|
||||
return texture_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1786,9 +1600,8 @@ create_texture_from_texture_destroy (gpointer data)
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
guint texture_id,
|
||||
GdkMemoryFormat format)
|
||||
gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
guint texture_id)
|
||||
{
|
||||
GskGLTextureState *state;
|
||||
GdkGLTextureBuilder *builder;
|
||||
@@ -1816,7 +1629,6 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
builder = gdk_gl_texture_builder_new ();
|
||||
gdk_gl_texture_builder_set_context (builder, self->command_queue->context);
|
||||
gdk_gl_texture_builder_set_id (builder, texture_id);
|
||||
gdk_gl_texture_builder_set_format (builder, format);
|
||||
gdk_gl_texture_builder_set_width (builder, texture->width);
|
||||
gdk_gl_texture_builder_set_height (builder, texture->height);
|
||||
gdk_gl_texture_builder_set_sync (builder, state->sync);
|
||||
|
||||
@@ -69,9 +69,7 @@ typedef struct {
|
||||
#define CONCAT_EXPANDED2(a,b) a##b
|
||||
#define GSK_GL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos,
|
||||
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms };
|
||||
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) enum { uniforms };
|
||||
# include "gskglprograms.defs"
|
||||
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_NO_UNIFORMS
|
||||
@@ -118,13 +116,10 @@ struct _GskGLDriver
|
||||
GskGLProgram *name ## _no_clip; \
|
||||
GskGLProgram *name ## _rect_clip; \
|
||||
GskGLProgram *name;
|
||||
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) \
|
||||
GskGLProgram *name;
|
||||
# include "gskglprograms.defs"
|
||||
#undef GSK_GL_NO_UNIFORMS
|
||||
#undef GSK_GL_ADD_UNIFORM
|
||||
#undef GSK_GL_DEFINE_PROGRAM
|
||||
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
|
||||
|
||||
gint64 current_frame_id;
|
||||
|
||||
@@ -154,8 +149,7 @@ void gsk_gl_driver_begin_frame (GskGLDriver *s
|
||||
void gsk_gl_driver_end_frame (GskGLDriver *self);
|
||||
void gsk_gl_driver_after_frame (GskGLDriver *self);
|
||||
GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
|
||||
guint texture_id,
|
||||
GdkMemoryFormat format);
|
||||
guint texture_id);
|
||||
void gsk_gl_driver_cache_texture (GskGLDriver *self,
|
||||
const GskTextureKey *key,
|
||||
guint texture_id);
|
||||
|
||||
@@ -119,11 +119,7 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
|
||||
|
||||
memset (pixel_data, 255, sizeof pixel_data);
|
||||
|
||||
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
|
||||
#endif
|
||||
)
|
||||
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ()))
|
||||
{
|
||||
gl_format = GL_RGBA;
|
||||
gl_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
@@ -111,11 +111,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
|
||||
"Uploading texture");
|
||||
|
||||
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
|
||||
#endif
|
||||
)
|
||||
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ()))
|
||||
{
|
||||
pixel_data = free_data = g_malloc (width * height * 4);
|
||||
gdk_memory_convert (pixel_data, width * 4,
|
||||
@@ -148,7 +144,6 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||
gl_format, gl_type,
|
||||
pixel_data);
|
||||
/* Padding left */
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x, packed_y + 1,
|
||||
1, height,
|
||||
@@ -162,6 +157,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
|
||||
pixel_data);
|
||||
|
||||
/* Padding right */
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
|
||||
glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
packed_x + width + 1, packed_y + 1,
|
||||
|
||||
@@ -87,13 +87,3 @@ GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
|
||||
GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
|
||||
GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
|
||||
GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
||||
/* Texture conversion shaders.
|
||||
*
|
||||
* Note: If you add new formats here, they need to be added
|
||||
* to the list of supported formats in gdk/gdkdmabuftexture.c.
|
||||
*/
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM_NO_CLIP (external,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("external.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, EXTERNAL_SOURCE, u_external_source))
|
||||
|
||||
+10
-22
@@ -24,13 +24,10 @@
|
||||
#include <gdk/gdkdisplayprivate.h>
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdksubsurfaceprivate.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gsk/gskdebugprivate.h>
|
||||
#include <gsk/gskrendererprivate.h>
|
||||
#include <gsk/gskrendernodeprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
|
||||
#include "gskglcommandqueueprivate.h"
|
||||
#include "gskgldriverprivate.h"
|
||||
@@ -138,8 +135,10 @@ gsk_gl_renderer_realize (GskRenderer *renderer,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), SHADERS))
|
||||
debug_shaders = TRUE;
|
||||
#endif
|
||||
|
||||
if (!(driver = gsk_gl_driver_for_display (display, debug_shaders, error)))
|
||||
goto failure;
|
||||
@@ -291,12 +290,6 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->context));
|
||||
scale = gdk_gl_context_get_scale (self->context);
|
||||
|
||||
if (cairo_region_is_empty (update_area))
|
||||
{
|
||||
gdk_draw_context_empty_frame (GDK_DRAW_CONTEXT (self->context));
|
||||
return;
|
||||
}
|
||||
|
||||
viewport.origin.x = 0;
|
||||
viewport.origin.y = 0;
|
||||
viewport.size.width = gdk_surface_get_width (surface) * scale;
|
||||
@@ -314,8 +307,10 @@ gsk_gl_renderer_render (GskRenderer *renderer,
|
||||
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
job = gsk_gl_render_job_new (self->driver, &viewport, scale, render_region, 0, clear_framebuffer);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||
#endif
|
||||
gsk_gl_render_job_render (job, root);
|
||||
gsk_gl_driver_end_frame (self->driver);
|
||||
gsk_gl_render_job_free (job);
|
||||
@@ -337,7 +332,6 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
GskGLRenderJob *job;
|
||||
GdkTexture *texture;
|
||||
guint texture_id;
|
||||
GdkMemoryFormat gdk_format;
|
||||
int width, height, max_size;
|
||||
int format;
|
||||
|
||||
@@ -381,15 +375,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
if (gsk_render_node_get_preferred_depth (root) != GDK_MEMORY_U8 &&
|
||||
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
|
||||
{
|
||||
gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
|
||||
format = GL_RGBA32F;
|
||||
}
|
||||
else
|
||||
{
|
||||
format = GL_RGBA8;
|
||||
gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
|
||||
}
|
||||
format = GL_RGBA32F;
|
||||
else
|
||||
format = GL_RGBA8;
|
||||
|
||||
gdk_gl_context_make_current (self->context);
|
||||
|
||||
@@ -400,11 +388,13 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
|
||||
{
|
||||
gsk_gl_driver_begin_frame (self->driver, self->command_queue);
|
||||
job = gsk_gl_render_job_new (self->driver, viewport, 1, NULL, render_target->framebuffer_id, TRUE);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (GSK_RENDERER (self), FALLBACK))
|
||||
gsk_gl_render_job_set_debug_fallback (job, TRUE);
|
||||
#endif
|
||||
gsk_gl_render_job_render_flipped (job, root);
|
||||
texture_id = gsk_gl_driver_release_render_target (self->driver, render_target, FALSE);
|
||||
texture = gsk_gl_driver_create_gdk_texture (self->driver, texture_id, gdk_format);
|
||||
texture = gsk_gl_driver_create_gdk_texture (self->driver, texture_id);
|
||||
gsk_gl_driver_end_frame (self->driver);
|
||||
gsk_gl_render_job_free (job);
|
||||
|
||||
@@ -438,8 +428,6 @@ gsk_gl_renderer_class_init (GskGLRendererClass *klass)
|
||||
|
||||
object_class->dispose = gsk_gl_renderer_dispose;
|
||||
|
||||
renderer_class->supports_offload = TRUE;
|
||||
|
||||
renderer_class->realize = gsk_gl_renderer_realize;
|
||||
renderer_class->unrealize = gsk_gl_renderer_unrealize;
|
||||
renderer_class->render = gsk_gl_renderer_render;
|
||||
|
||||
+21
-61
@@ -30,13 +30,9 @@
|
||||
#include <gsk/gskglshaderprivate.h>
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include <gdk/gdkmemorytextureprivate.h>
|
||||
#include <gdk/gdkdmabuftexture.h>
|
||||
#include <gdk/gdksurfaceprivate.h>
|
||||
#include <gdk/gdksubsurfaceprivate.h>
|
||||
#include <gsk/gsktransformprivate.h>
|
||||
#include <gsk/gskroundedrectprivate.h>
|
||||
#include <gsk/gskrectprivate.h>
|
||||
#include <gsk/gskrendererprivate.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -47,13 +43,10 @@
|
||||
#include "gskglprogramprivate.h"
|
||||
#include "gskglrenderjobprivate.h"
|
||||
#include "gskglshadowlibraryprivate.h"
|
||||
#include "gskdebugprivate.h"
|
||||
|
||||
#include "ninesliceprivate.h"
|
||||
#include "fp16private.h"
|
||||
|
||||
#define ALLOW_OFFLOAD_FOR_ANY_TEXTURE 1
|
||||
|
||||
#define ORTHO_NEAR_PLANE -10000
|
||||
#define ORTHO_FAR_PLANE 10000
|
||||
#define MAX_GRADIENT_STOPS 6
|
||||
@@ -302,7 +295,6 @@ node_supports_2d_transform (const GskRenderNode *node)
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
@@ -359,7 +351,6 @@ node_supports_transform (const GskRenderNode *node)
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
return TRUE;
|
||||
|
||||
case GSK_SHADOW_NODE:
|
||||
@@ -1233,6 +1224,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (job->debug_fallback)
|
||||
{
|
||||
cairo_move_to (cr, 0, 0);
|
||||
@@ -1248,6 +1240,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
cairo_set_source_rgba (cr, 1, 0, 0, 1);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
#endif
|
||||
cairo_destroy (cr);
|
||||
|
||||
/* Create texture to upload */
|
||||
@@ -2829,7 +2822,7 @@ equal_texture_nodes (const GskRenderNode *node1,
|
||||
gsk_texture_node_get_texture (node2))
|
||||
return FALSE;
|
||||
|
||||
return gsk_rect_equal (&node1->bounds, &node2->bounds);
|
||||
return graphene_rect_equal (&node1->bounds, &node2->bounds);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -3637,12 +3630,16 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
gboolean ensure_mipmap,
|
||||
GskGLRenderOffscreen *offscreen)
|
||||
{
|
||||
/* Don't put GL or dmabuf textures into icon caches, they are already on the GPU side */
|
||||
GdkGLTexture *gl_texture = NULL;
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture))
|
||||
gl_texture = GDK_GL_TEXTURE (texture);
|
||||
|
||||
if (!ensure_mipmap &&
|
||||
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
|
||||
texture->width,
|
||||
texture->height) &&
|
||||
!(GDK_IS_GL_TEXTURE (texture) || GDK_IS_DMABUF_TEXTURE (texture)))
|
||||
!gl_texture)
|
||||
{
|
||||
const GskGLIconData *icon_data;
|
||||
|
||||
@@ -3656,20 +3653,16 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
/* Only generate a mipmap if it does not make use reupload
|
||||
* a GL texture which we could otherwise use directly.
|
||||
*/
|
||||
if (GDK_IS_GL_TEXTURE (texture) &&
|
||||
gdk_gl_context_is_shared (gdk_gl_texture_get_context (GDK_GL_TEXTURE (texture)),
|
||||
job->command_queue->context))
|
||||
ensure_mipmap = gdk_gl_texture_has_mipmap (GDK_GL_TEXTURE (texture));
|
||||
else if (GDK_IS_DMABUF_TEXTURE (texture))
|
||||
ensure_mipmap = FALSE;
|
||||
if (gl_texture &&
|
||||
gdk_gl_context_is_shared (gdk_gl_texture_get_context (gl_texture), job->command_queue->context))
|
||||
ensure_mipmap = gdk_gl_texture_has_mipmap (gl_texture);
|
||||
|
||||
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
|
||||
init_full_texture_region (offscreen);
|
||||
offscreen->has_mipmap = ensure_mipmap;
|
||||
|
||||
if (GDK_IS_GL_TEXTURE (texture) &&
|
||||
offscreen->texture_id == gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture)))
|
||||
offscreen->sync = gdk_gl_texture_get_sync (GDK_GL_TEXTURE (texture));
|
||||
if (gl_texture && offscreen->texture_id == gdk_gl_texture_get_id (gl_texture))
|
||||
offscreen->sync = gdk_gl_texture_get_sync (gl_texture);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3791,6 +3784,12 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
|
||||
GskTextureKey key;
|
||||
guint texture_id;
|
||||
|
||||
if (filter == GSK_SCALING_FILTER_LINEAR)
|
||||
{
|
||||
gsk_gl_render_job_visit_texture (job, texture, bounds);
|
||||
return;
|
||||
}
|
||||
|
||||
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
|
||||
|
||||
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
|
||||
@@ -3956,7 +3955,7 @@ gsk_gl_render_job_visit_repeat_node (GskGLRenderJob *job,
|
||||
if (node_is_invisible (child))
|
||||
return;
|
||||
|
||||
if (!gsk_rect_equal (child_bounds, &child->bounds))
|
||||
if (!graphene_rect_equal (child_bounds, &child->bounds))
|
||||
{
|
||||
/* TODO: implement these repeat nodes. */
|
||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||
@@ -4003,40 +4002,6 @@ gsk_gl_render_job_visit_repeat_node (GskGLRenderJob *job,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_visit_subsurface_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
GdkSubsurface *subsurface;
|
||||
|
||||
subsurface = (GdkSubsurface *) gsk_subsurface_node_get_subsurface (node);
|
||||
|
||||
if (subsurface &&
|
||||
gdk_subsurface_get_texture (subsurface) &&
|
||||
gdk_subsurface_get_parent (subsurface) == gdk_gl_context_get_surface (job->command_queue->context))
|
||||
{
|
||||
if (!gdk_subsurface_is_above_parent (subsurface))
|
||||
{
|
||||
/* Clear the area so we can see through */
|
||||
if (gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color)))
|
||||
{
|
||||
GskGLCommandBatch *batch;
|
||||
guint16 color[4];
|
||||
rgba_to_half (&(GdkRGBA){0,0,0,0}, color);
|
||||
|
||||
batch = gsk_gl_command_queue_get_batch (job->command_queue);
|
||||
batch->draw.blend = 0;
|
||||
gsk_gl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_gl_render_job_visit_node (job, gsk_subsurface_node_get_child (node));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
const GskRenderNode *node)
|
||||
@@ -4233,10 +4198,6 @@ gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
gsk_gl_render_job_visit_as_fallback (job, node);
|
||||
break;
|
||||
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
gsk_gl_render_job_visit_subsurface_node (job, node);
|
||||
break;
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
@@ -4558,7 +4519,6 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
|
||||
gsk_gl_command_queue_clear (job->command_queue, 0, &job->viewport);
|
||||
gsk_gl_render_job_visit_node (job, root);
|
||||
gdk_gl_context_pop_debug_group (job->command_queue->context);
|
||||
|
||||
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Build GL command queue", "");
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -140,6 +140,7 @@ gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self,
|
||||
g_clear_pointer (&removed, g_ptr_array_unref);
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK (GLYPH_CACHE))
|
||||
{
|
||||
static gint64 last_message;
|
||||
@@ -152,6 +153,7 @@ gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self,
|
||||
self->atlases->len);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
// VERTEX_SHADER:
|
||||
// external.glsl
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
// external.glsl
|
||||
|
||||
#if defined(GSK_GLES) || defined(GSK_GLES3)
|
||||
uniform samplerExternalOES u_external_source;
|
||||
#else
|
||||
/* Just to make this compile, we won't use it without GLES */
|
||||
uniform sampler2D u_external_source;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
/* Open-code this here, since GskTexture() expects a sampler2D */
|
||||
#if defined(GSK_GLES) || defined(GSK_LEGACY)
|
||||
vec4 color = texture2D(u_external_source, vUv);
|
||||
#else
|
||||
vec4 color = texture(u_external_source, vUv);
|
||||
#endif
|
||||
gskSetOutputColor(color);
|
||||
}
|
||||
@@ -1,9 +1,3 @@
|
||||
#if defined(GSK_GLES3)
|
||||
#extension GL_OES_EGL_image_external_essl3 : require
|
||||
#elif defined (GSK_GLES)
|
||||
#extension GL_OES_EGL_image_external : require
|
||||
#endif
|
||||
|
||||
#ifndef GSK_LEGACY
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
#include "gskrendernodeprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
typedef struct {
|
||||
GQuark cpu_time;
|
||||
GQuark gpu_time;
|
||||
} ProfileTimers;
|
||||
#endif
|
||||
|
||||
struct _GskCairoRenderer
|
||||
{
|
||||
@@ -38,7 +40,9 @@ struct _GskCairoRenderer
|
||||
|
||||
GdkCairoContext *cairo_context;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
ProfileTimers profile_timers;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _GskCairoRendererClass
|
||||
@@ -74,19 +78,25 @@ gsk_cairo_renderer_do_render (GskRenderer *renderer,
|
||||
cairo_t *cr,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time;
|
||||
#endif
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
profiler = gsk_renderer_get_profiler (renderer);
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
gsk_render_node_draw (root, cr);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
|
||||
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
|
||||
|
||||
gsk_profiler_push_samples (profiler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
@@ -163,6 +173,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (renderer, GEOMETRY))
|
||||
{
|
||||
GdkSurface *surface = gsk_renderer_get_surface (renderer);
|
||||
@@ -176,6 +187,7 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
#endif
|
||||
|
||||
gsk_cairo_renderer_do_render (renderer, cr, root);
|
||||
|
||||
@@ -198,9 +210,11 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
|
||||
static void
|
||||
gsk_cairo_renderer_init (GskCairoRenderer *self)
|
||||
{
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler = gsk_renderer_get_profiler (GSK_RENDERER (self));
|
||||
|
||||
self->profile_timers.cpu_time = gsk_profiler_add_timer (profiler, "cpu-time", "CPU time", FALSE, TRUE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-9
@@ -1781,15 +1781,10 @@ gsk_conic_curve_segment (const GskCurve *curve,
|
||||
graphene_point_t ctrl_num, ctrl_denom;
|
||||
float mid;
|
||||
|
||||
if (start <= 0.0f || end >= 1.0f)
|
||||
{
|
||||
if (start <= 0.0f)
|
||||
gsk_conic_curve_split (curve, end, segment, NULL);
|
||||
else if (end >= 1.0f)
|
||||
gsk_conic_curve_split (curve, start, NULL, segment);
|
||||
|
||||
return;
|
||||
}
|
||||
if (start <= 0.0f)
|
||||
return gsk_conic_curve_split (curve, end, segment, NULL);
|
||||
else if (end >= 1.0f)
|
||||
return gsk_conic_curve_split (curve, start, NULL, segment);
|
||||
|
||||
gsk_conic_curve_ensure_coefficents (self);
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ static const GdkDebugKey gsk_debug_keys[] = {
|
||||
{ "full-redraw", GSK_DEBUG_FULL_REDRAW, "Force full redraws" },
|
||||
{ "sync", GSK_DEBUG_SYNC, "Sync after each frame" },
|
||||
{ "staging", GSK_DEBUG_STAGING, "Use a staging image for texture upload (Vulkan only)" },
|
||||
{ "offload-disable", GSK_DEBUG_OFFLOAD_DISABLE, "Disable graphics offload" },
|
||||
};
|
||||
|
||||
static guint gsk_debug_flags;
|
||||
|
||||
+12
-2
@@ -19,8 +19,7 @@ typedef enum {
|
||||
GSK_DEBUG_GEOMETRY = 1 << 9,
|
||||
GSK_DEBUG_FULL_REDRAW = 1 << 10,
|
||||
GSK_DEBUG_SYNC = 1 << 11,
|
||||
GSK_DEBUG_STAGING = 1 << 12,
|
||||
GSK_DEBUG_OFFLOAD_DISABLE = 1 << 13,
|
||||
GSK_DEBUG_STAGING = 1 << 12
|
||||
} GskDebugFlags;
|
||||
|
||||
#define GSK_DEBUG_ANY ((1 << 13) - 1)
|
||||
@@ -30,6 +29,8 @@ void gsk_set_debug_flags (GskDebugFlags flags);
|
||||
|
||||
gboolean gsk_check_debug_flags (GskDebugFlags flags);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
|
||||
#define GSK_DEBUG_CHECK(type) G_UNLIKELY (gsk_check_debug_flags (GSK_DEBUG_ ## type))
|
||||
#define GSK_RENDERER_DEBUG_CHECK(renderer,type) \
|
||||
G_UNLIKELY ((gsk_renderer_get_debug_flags (renderer) & GSK_DEBUG_ ## type) != 0)
|
||||
@@ -46,5 +47,14 @@ gboolean gsk_check_debug_flags (GskDebugFlags flags);
|
||||
gdk_debug_message (__VA_ARGS__); \
|
||||
} G_STMT_END
|
||||
|
||||
#else
|
||||
|
||||
#define GSK_DEBUG_CHECK(type) 0
|
||||
#define GSK_RENDERER_DEBUG_CHECK(renderer,type) 0
|
||||
#define GSK_RENDERER_DEBUG(display,type,...)
|
||||
#define GSK_DEBUG(type,...)
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+1
-3
@@ -53,7 +53,6 @@
|
||||
* @GSK_MASK_NODE: A node that masks one child with another (Since: 4.10)
|
||||
* @GSK_FILL_NODE: A node that fills a path
|
||||
* @GSK_STROKE_NODE: A node that strokes a path
|
||||
* @GSK_SUBSURFACE_NODE: A node possibly redirects part of the scene graph to a subsurface (Since: 4.14)
|
||||
|
||||
* The type of a node determines what the node is rendering.
|
||||
*/
|
||||
@@ -87,8 +86,7 @@ typedef enum {
|
||||
GSK_TEXTURE_SCALE_NODE,
|
||||
GSK_MASK_NODE,
|
||||
GSK_FILL_NODE,
|
||||
GSK_STROKE_NODE,
|
||||
GSK_SUBSURFACE_NODE,
|
||||
GSK_STROKE_NODE
|
||||
} GskRenderNodeType;
|
||||
|
||||
/**
|
||||
|
||||
@@ -162,6 +162,7 @@ uniform_type_from_glsl (const char *str)
|
||||
return GSK_GL_UNIFORM_TYPE_NONE;
|
||||
}
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
static const char *
|
||||
uniform_type_name (GskGLUniformType type)
|
||||
{
|
||||
@@ -194,6 +195,7 @@ uniform_type_name (GskGLUniformType type)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
uniform_type_size (GskGLUniformType type)
|
||||
@@ -397,6 +399,7 @@ gsk_gl_shader_constructed (GObject *object)
|
||||
|
||||
shader->n_textures = max_texture_seen;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_DEBUG_CHECK(SHADERS))
|
||||
{
|
||||
GString *s;
|
||||
@@ -414,6 +417,7 @@ gsk_gl_shader_constructed (GObject *object)
|
||||
s->str);
|
||||
g_string_free (s, TRUE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SPACE_RE "[ \\t]+" // Don't use \s, we don't want to match newlines
|
||||
|
||||
@@ -1,670 +0,0 @@
|
||||
/* gskoffload.c
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* This file 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 file 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 "gskoffloadprivate.h"
|
||||
|
||||
#include "gskrendernode.h"
|
||||
#include "gskrectprivate.h"
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gsktransform.h"
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
#include "gdksurfaceprivate.h"
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GskRoundedRect rect;
|
||||
guint is_rectilinear : 1;
|
||||
guint is_fully_contained : 1;
|
||||
guint is_empty : 1;
|
||||
guint is_complex : 1;
|
||||
} Clip;
|
||||
|
||||
struct _GskOffload
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GskOffloadInfo *subsurfaces;
|
||||
gsize n_subsurfaces;
|
||||
|
||||
GSList *transforms;
|
||||
GSList *clips;
|
||||
|
||||
Clip *current_clip;
|
||||
|
||||
GskOffloadInfo *last_info;
|
||||
gboolean can_raise;
|
||||
};
|
||||
|
||||
static GdkTexture *
|
||||
find_texture_to_attach (GskOffload *self,
|
||||
GdkSubsurface *subsurface,
|
||||
const GskRenderNode *node)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
switch ((int)GSK_RENDER_NODE_TYPE (node))
|
||||
{
|
||||
case GSK_DEBUG_NODE:
|
||||
node = gsk_debug_node_get_child (node);
|
||||
break;
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
if (gsk_container_node_get_n_children (node) != 1)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: too much content, container with %d children",
|
||||
subsurface, gsk_container_node_get_n_children (node));
|
||||
return NULL;
|
||||
}
|
||||
node = gsk_container_node_get_child (node, 0);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
{
|
||||
GskTransform *t = gsk_transform_node_get_transform (node);
|
||||
if (gsk_transform_get_category (t) < GSK_TRANSFORM_CATEGORY_2D_AFFINE)
|
||||
{
|
||||
char *s = gsk_transform_to_string (t);
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: transform %s is not just scale/translate",
|
||||
subsurface, s);
|
||||
g_free (s);
|
||||
return NULL;
|
||||
}
|
||||
node = gsk_transform_node_get_child (node);
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TEXTURE_NODE:
|
||||
return gsk_texture_node_get_texture (node);
|
||||
|
||||
default:
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: Only textures supported but found %s",
|
||||
subsurface, g_type_name_from_instance ((GTypeInstance *) node));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
push_transform (GskOffload *self,
|
||||
GskTransform *transform)
|
||||
{
|
||||
if (self->transforms)
|
||||
{
|
||||
GskTransform *t = self->transforms->data;
|
||||
t = gsk_transform_transform (gsk_transform_ref (t), transform);
|
||||
self->transforms = g_slist_prepend (self->transforms, t);
|
||||
}
|
||||
else
|
||||
self->transforms = g_slist_prepend (NULL, gsk_transform_ref (transform));
|
||||
}
|
||||
|
||||
static void
|
||||
pop_transform (GskOffload *self)
|
||||
{
|
||||
GSList *l = self->transforms;
|
||||
GskTransform *t = l->data;
|
||||
|
||||
g_assert (self->transforms != NULL);
|
||||
|
||||
self->transforms = self->transforms->next;
|
||||
|
||||
g_slist_free_1 (l);
|
||||
gsk_transform_unref (t);
|
||||
}
|
||||
|
||||
static inline void
|
||||
transform_bounds (GskOffload *self,
|
||||
const graphene_rect_t *bounds,
|
||||
graphene_rect_t *rect)
|
||||
{
|
||||
GskTransform *t = self->transforms ? self->transforms->data : NULL;
|
||||
float sx, sy, dx, dy;
|
||||
|
||||
g_assert (gsk_transform_get_category (t) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE);
|
||||
|
||||
gsk_transform_to_affine (t, &sx, &sy, &dx, &dy);
|
||||
|
||||
rect->origin.x = bounds->origin.x * sx + dx;
|
||||
rect->origin.y = bounds->origin.y * sy + dy;
|
||||
rect->size.width = bounds->size.width * sx;
|
||||
rect->size.height = bounds->size.height * sy;
|
||||
}
|
||||
|
||||
static inline void
|
||||
transform_rounded_rect (GskOffload *self,
|
||||
const GskRoundedRect *rect,
|
||||
GskRoundedRect *out_rect)
|
||||
{
|
||||
GskTransform *t = self->transforms ? self->transforms->data : NULL;
|
||||
float sx, sy, dx, dy;
|
||||
|
||||
g_assert (gsk_transform_get_category (t) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE);
|
||||
|
||||
gsk_transform_to_affine (t, &sx, &sy, &dx, &dy);
|
||||
gsk_rounded_rect_scale_affine (out_rect, rect, sx, sy, dx, dy);
|
||||
}
|
||||
|
||||
static void
|
||||
push_rect_clip (GskOffload *self,
|
||||
const GskRoundedRect *rect)
|
||||
{
|
||||
Clip *clip = g_new0 (Clip, 1);
|
||||
clip->rect = *rect;
|
||||
clip->is_rectilinear = gsk_rounded_rect_is_rectilinear (rect);
|
||||
clip->is_empty = rect->bounds.size.width == 0 && rect->bounds.size.height == 0;
|
||||
|
||||
self->clips = g_slist_prepend (self->clips, clip);
|
||||
self->current_clip = self->clips->data;
|
||||
}
|
||||
|
||||
static void
|
||||
push_empty_clip (GskOffload *self)
|
||||
{
|
||||
push_rect_clip (self, &GSK_ROUNDED_RECT_INIT (0, 0, 0, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
push_contained_clip (GskOffload *self)
|
||||
{
|
||||
Clip *current_clip = self->clips->data;
|
||||
Clip *clip = g_new0 (Clip, 1);
|
||||
|
||||
clip->rect = current_clip->rect;
|
||||
clip->is_rectilinear = TRUE;
|
||||
clip->is_fully_contained = TRUE;
|
||||
|
||||
self->clips = g_slist_prepend (self->clips, clip);
|
||||
self->current_clip = self->clips->data;
|
||||
}
|
||||
|
||||
static void
|
||||
push_complex_clip (GskOffload *self)
|
||||
{
|
||||
Clip *current_clip = self->clips->data;
|
||||
Clip *clip = g_new0 (Clip, 1);
|
||||
|
||||
clip->rect = current_clip->rect;
|
||||
clip->is_complex = TRUE;
|
||||
|
||||
self->clips = g_slist_prepend (self->clips, clip);
|
||||
self->current_clip = self->clips->data;
|
||||
}
|
||||
|
||||
static void
|
||||
pop_clip (GskOffload *self)
|
||||
{
|
||||
GSList *l = self->clips;
|
||||
Clip *clip = l->data;
|
||||
|
||||
g_assert (self->clips != NULL);
|
||||
|
||||
self->clips = self->clips->next;
|
||||
if (self->clips)
|
||||
self->current_clip = self->clips->data;
|
||||
|
||||
g_slist_free_1 (l);
|
||||
g_free (clip);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rounded_rect_get_inner (const GskRoundedRect *rect,
|
||||
graphene_rect_t *inner)
|
||||
{
|
||||
float left = MAX (rect->corner[GSK_CORNER_TOP_LEFT].width, rect->corner[GSK_CORNER_BOTTOM_LEFT].width);
|
||||
float right = MAX (rect->corner[GSK_CORNER_TOP_RIGHT].width, rect->corner[GSK_CORNER_BOTTOM_RIGHT].width);
|
||||
float top = MAX (rect->corner[GSK_CORNER_TOP_LEFT].height, rect->corner[GSK_CORNER_TOP_RIGHT].height);
|
||||
float bottom = MAX (rect->corner[GSK_CORNER_BOTTOM_LEFT].height, rect->corner[GSK_CORNER_BOTTOM_RIGHT].height);
|
||||
|
||||
inner->origin.x = rect->bounds.origin.x + left;
|
||||
inner->size.width = rect->bounds.size.width - (left + right);
|
||||
|
||||
inner->origin.y = rect->bounds.origin.y + top;
|
||||
inner->size.height = rect->bounds.size.height - (top + bottom);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
interval_contains (float p1, float w1,
|
||||
float p2, float w2)
|
||||
{
|
||||
if (p2 < p1)
|
||||
return FALSE;
|
||||
|
||||
if (p2 + w2 > p1 + w1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_clip (GskOffload *self,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
graphene_rect_t transformed_bounds;
|
||||
gboolean no_clip = FALSE;
|
||||
gboolean rect_clip = FALSE;
|
||||
|
||||
if (self->current_clip->is_fully_contained ||
|
||||
self->current_clip->is_empty ||
|
||||
self->current_clip->is_complex)
|
||||
return FALSE;
|
||||
|
||||
transform_bounds (self, bounds, &transformed_bounds);
|
||||
|
||||
if (!gsk_rect_intersects (&self->current_clip->rect.bounds, &transformed_bounds))
|
||||
{
|
||||
push_empty_clip (self);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (self->current_clip->is_rectilinear)
|
||||
{
|
||||
if (gsk_rect_contains_rect (&self->current_clip->rect.bounds, &transformed_bounds))
|
||||
no_clip = TRUE;
|
||||
else
|
||||
rect_clip = TRUE;
|
||||
}
|
||||
else if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, &transformed_bounds))
|
||||
{
|
||||
no_clip = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
graphene_rect_t inner;
|
||||
|
||||
rounded_rect_get_inner (&self->current_clip->rect, &inner);
|
||||
|
||||
if (interval_contains (inner.origin.x, inner.size.width,
|
||||
transformed_bounds.origin.x, transformed_bounds.size.width) ||
|
||||
interval_contains (inner.origin.y, inner.size.height,
|
||||
transformed_bounds.origin.y, transformed_bounds.size.height))
|
||||
rect_clip = TRUE;
|
||||
}
|
||||
|
||||
if (no_clip)
|
||||
{
|
||||
/* This node is completely contained inside the clip.
|
||||
* Record this fact on the clip stack, so we don't do
|
||||
* more work for child nodes.
|
||||
*/
|
||||
push_contained_clip (self);
|
||||
return TRUE;
|
||||
}
|
||||
else if (rect_clip && !self->current_clip->is_rectilinear)
|
||||
{
|
||||
graphene_rect_t rect;
|
||||
|
||||
/* The clip gets simpler for this node */
|
||||
|
||||
graphene_rect_intersection (&self->current_clip->rect.bounds, &transformed_bounds, &rect);
|
||||
push_rect_clip (self, &GSK_ROUNDED_RECT_INIT_FROM_RECT (rect));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GskOffloadInfo *
|
||||
find_subsurface_info (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
for (gsize i = 0; i < self->n_subsurfaces; i++)
|
||||
{
|
||||
GskOffloadInfo *info = &self->subsurfaces[i];
|
||||
if (info->subsurface == subsurface)
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
visit_node (GskOffload *self,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
gboolean has_clip;
|
||||
|
||||
if (self->last_info && self->can_raise)
|
||||
{
|
||||
graphene_rect_t transformed_bounds;
|
||||
|
||||
transform_bounds (self, &node->bounds, &transformed_bounds);
|
||||
if (gsk_rect_intersects (&transformed_bounds, &self->last_info->rect))
|
||||
{
|
||||
GskRenderNodeType type = GSK_RENDER_NODE_TYPE (node);
|
||||
|
||||
if (type != GSK_CONTAINER_NODE &&
|
||||
type != GSK_TRANSFORM_NODE &&
|
||||
type != GSK_CLIP_NODE &&
|
||||
type != GSK_ROUNDED_CLIP_NODE &&
|
||||
type != GSK_DEBUG_NODE)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't raise subsurface %p because a %s overlaps",
|
||||
self->last_info->subsurface,
|
||||
g_type_name_from_instance ((GTypeInstance *) node));
|
||||
self->can_raise = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
has_clip = update_clip (self, &node->bounds);
|
||||
|
||||
switch (GSK_RENDER_NODE_TYPE (node))
|
||||
{
|
||||
case GSK_BORDER_NODE:
|
||||
case GSK_COLOR_NODE:
|
||||
case GSK_CONIC_GRADIENT_NODE:
|
||||
case GSK_LINEAR_GRADIENT_NODE:
|
||||
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
|
||||
case GSK_RADIAL_GRADIENT_NODE:
|
||||
case GSK_REPEATING_RADIAL_GRADIENT_NODE:
|
||||
case GSK_TEXT_NODE:
|
||||
case GSK_TEXTURE_NODE:
|
||||
case GSK_TEXTURE_SCALE_NODE:
|
||||
case GSK_CAIRO_NODE:
|
||||
case GSK_INSET_SHADOW_NODE:
|
||||
case GSK_OUTSET_SHADOW_NODE:
|
||||
case GSK_GL_SHADER_NODE:
|
||||
case GSK_BLEND_NODE:
|
||||
case GSK_BLUR_NODE:
|
||||
case GSK_COLOR_MATRIX_NODE:
|
||||
case GSK_OPACITY_NODE:
|
||||
case GSK_CROSS_FADE_NODE:
|
||||
case GSK_SHADOW_NODE:
|
||||
case GSK_REPEAT_NODE:
|
||||
case GSK_MASK_NODE:
|
||||
case GSK_FILL_NODE:
|
||||
case GSK_STROKE_NODE:
|
||||
break;
|
||||
|
||||
case GSK_CLIP_NODE:
|
||||
{
|
||||
const graphene_rect_t *clip = gsk_clip_node_get_clip (node);
|
||||
graphene_rect_t transformed_clip;
|
||||
GskRoundedRect intersection;
|
||||
|
||||
transform_bounds (self, clip, &transformed_clip);
|
||||
|
||||
if (self->current_clip->is_rectilinear)
|
||||
{
|
||||
memset (&intersection.corner, 0, sizeof intersection.corner);
|
||||
graphene_rect_intersection (&transformed_clip,
|
||||
&self->current_clip->rect.bounds,
|
||||
&intersection.bounds);
|
||||
|
||||
push_rect_clip (self, &intersection);
|
||||
visit_node (self, gsk_clip_node_get_child (node));
|
||||
pop_clip (self);
|
||||
}
|
||||
else
|
||||
{
|
||||
GskRoundedRectIntersection result;
|
||||
|
||||
result = gsk_rounded_rect_intersect_with_rect (&self->current_clip->rect,
|
||||
&transformed_clip,
|
||||
&intersection);
|
||||
|
||||
if (result == GSK_INTERSECTION_EMPTY)
|
||||
push_empty_clip (self);
|
||||
else if (result == GSK_INTERSECTION_NONEMPTY)
|
||||
push_rect_clip (self, &intersection);
|
||||
else
|
||||
push_complex_clip (self);
|
||||
visit_node (self, gsk_clip_node_get_child (node));
|
||||
pop_clip (self);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_ROUNDED_CLIP_NODE:
|
||||
{
|
||||
const GskRoundedRect *clip = gsk_rounded_clip_node_get_clip (node);
|
||||
GskRoundedRect transformed_clip;
|
||||
|
||||
transform_rounded_rect (self, clip, &transformed_clip);
|
||||
|
||||
if (self->current_clip->is_rectilinear)
|
||||
{
|
||||
GskRoundedRect intersection;
|
||||
GskRoundedRectIntersection result;
|
||||
|
||||
result = gsk_rounded_rect_intersect_with_rect (&transformed_clip,
|
||||
&self->current_clip->rect.bounds,
|
||||
&intersection);
|
||||
|
||||
if (result == GSK_INTERSECTION_EMPTY)
|
||||
push_empty_clip (self);
|
||||
else if (result == GSK_INTERSECTION_NONEMPTY)
|
||||
push_rect_clip (self, &intersection);
|
||||
else
|
||||
goto complex_clip;
|
||||
visit_node (self, gsk_rounded_clip_node_get_child (node));
|
||||
pop_clip (self);
|
||||
}
|
||||
else
|
||||
{
|
||||
complex_clip:
|
||||
if (gsk_rounded_rect_contains_rect (&self->current_clip->rect, &transformed_clip.bounds))
|
||||
push_rect_clip (self, &transformed_clip);
|
||||
else
|
||||
push_complex_clip (self);
|
||||
visit_node (self, gsk_rounded_clip_node_get_child (node));
|
||||
pop_clip (self);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_NODE:
|
||||
{
|
||||
GskTransform *transform = gsk_transform_node_get_transform (node);
|
||||
const GskTransformCategory category = gsk_transform_get_category (transform);
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
visit_node (self, gsk_transform_node_get_child (node));
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
push_transform (self, transform);
|
||||
visit_node (self, gsk_transform_node_get_child (node));
|
||||
pop_transform (self);
|
||||
break;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_CONTAINER_NODE:
|
||||
for (gsize i = 0; i < gsk_container_node_get_n_children (node); i++)
|
||||
visit_node (self, gsk_container_node_get_child (node, i));
|
||||
break;
|
||||
|
||||
case GSK_DEBUG_NODE:
|
||||
visit_node (self, gsk_debug_node_get_child (node));
|
||||
break;
|
||||
|
||||
case GSK_SUBSURFACE_NODE:
|
||||
{
|
||||
GdkSubsurface *subsurface = gsk_subsurface_node_get_subsurface (node);
|
||||
|
||||
GskOffloadInfo *info = find_subsurface_info (self, subsurface);
|
||||
|
||||
if (info == NULL)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload: unknown subsurface %p",
|
||||
subsurface);
|
||||
}
|
||||
else if (!self->current_clip->is_fully_contained)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (gdk_surface_get_display (self->surface), OFFLOAD,
|
||||
"Can't offload subsurface %p: clipped",
|
||||
subsurface);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->texture = find_texture_to_attach (self, subsurface, gsk_subsurface_node_get_child (node));
|
||||
if (info->texture)
|
||||
{
|
||||
info->can_offload = TRUE;
|
||||
transform_bounds (self, &node->bounds, &info->rect);
|
||||
info->place_above = self->last_info ? self->last_info->subsurface : NULL;
|
||||
self->last_info = info;
|
||||
self->can_raise = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GSK_NOT_A_RENDER_NODE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (has_clip)
|
||||
pop_clip (self);
|
||||
}
|
||||
|
||||
GskOffload *
|
||||
gsk_offload_new (GdkSurface *surface,
|
||||
GskRenderNode *root)
|
||||
{
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
GskOffload *self;
|
||||
|
||||
self = g_new0 (GskOffload, 1);
|
||||
|
||||
self->surface = surface;
|
||||
self->transforms = NULL;
|
||||
self->clips = NULL;
|
||||
|
||||
self->last_info = NULL;
|
||||
|
||||
self->n_subsurfaces = gdk_surface_get_n_subsurfaces (self->surface);
|
||||
self->subsurfaces = g_new0 (GskOffloadInfo, self->n_subsurfaces);
|
||||
|
||||
for (gsize i = 0; i < self->n_subsurfaces; i++)
|
||||
{
|
||||
GskOffloadInfo *info = &self->subsurfaces[i];
|
||||
info->subsurface = gdk_surface_get_subsurface (self->surface, i);
|
||||
info->was_offloaded = gdk_subsurface_get_texture (info->subsurface) != NULL;
|
||||
/* Stack them all below, initially */
|
||||
gdk_subsurface_place_below (info->subsurface, NULL);
|
||||
}
|
||||
|
||||
if (self->n_subsurfaces > 0)
|
||||
{
|
||||
push_rect_clip (self, &GSK_ROUNDED_RECT_INIT (0, 0,
|
||||
gdk_surface_get_width (surface),
|
||||
gdk_surface_get_height (surface)));
|
||||
|
||||
visit_node (self, root);
|
||||
|
||||
pop_clip (self);
|
||||
}
|
||||
|
||||
for (gsize i = 0; i < self->n_subsurfaces; i++)
|
||||
{
|
||||
GskOffloadInfo *info = &self->subsurfaces[i];
|
||||
|
||||
if (info->can_offload)
|
||||
{
|
||||
info->is_offloaded = gdk_subsurface_attach (info->subsurface,
|
||||
info->texture,
|
||||
&info->rect);
|
||||
|
||||
if (info->place_above)
|
||||
gdk_subsurface_place_above (info->subsurface, info->place_above);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->is_offloaded = FALSE;
|
||||
if (info->was_offloaded)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Hiding subsurface %p", info->subsurface);
|
||||
gdk_subsurface_detach (info->subsurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (self->can_raise && self->last_info)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Raising subsurface %p", self->last_info->subsurface);
|
||||
gdk_subsurface_place_above (self->last_info->subsurface, NULL);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_offload_free (GskOffload *self)
|
||||
{
|
||||
g_free (self->subsurfaces);
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
GskOffloadInfo *
|
||||
gsk_offload_get_subsurface_info (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
return find_subsurface_info (self, subsurface);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_offload_subsurface_was_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
GskOffloadInfo *info = find_subsurface_info (self, subsurface);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
return info->was_offloaded;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_offload_subsurface_is_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface)
|
||||
{
|
||||
GskOffloadInfo *info = find_subsurface_info (self, subsurface);
|
||||
|
||||
if (!info)
|
||||
return FALSE;
|
||||
|
||||
return info->is_offloaded;
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/* gskoffloadprivate.h
|
||||
*
|
||||
* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* 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 Lesser 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 <gdk/gdk.h>
|
||||
#include "gdk/gdksubsurfaceprivate.h"
|
||||
#include "gskrendernode.h"
|
||||
|
||||
typedef struct _GskOffload GskOffload;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GdkSubsurface *subsurface;
|
||||
GdkTexture *texture;
|
||||
GdkSubsurface *place_above;
|
||||
graphene_rect_t rect;
|
||||
guint was_offloaded : 1;
|
||||
guint can_offload : 1;
|
||||
guint is_offloaded : 1;
|
||||
} GskOffloadInfo;
|
||||
|
||||
GskOffload * gsk_offload_new (GdkSurface *surface,
|
||||
GskRenderNode *root);
|
||||
void gsk_offload_free (GskOffload *self);
|
||||
|
||||
GskOffloadInfo * gsk_offload_get_subsurface_info (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
gboolean gsk_offload_subsurface_was_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
gboolean gsk_offload_subsurface_is_offloaded (GskOffload *self,
|
||||
GdkSubsurface *subsurface);
|
||||
|
||||
@@ -36,12 +36,3 @@ gsk_rect_to_float (const graphene_rect_t *rect,
|
||||
values[3] = rect->size.height;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_rect_equal (const graphene_rect_t *r1,
|
||||
const graphene_rect_t *r2)
|
||||
{
|
||||
return r1->origin.x == r2->origin.x &&
|
||||
r1->origin.y == r2->origin.y &&
|
||||
r1->size.width == r2->size.width &&
|
||||
r1->size.height == r2->size.height;
|
||||
}
|
||||
|
||||
+22
-34
@@ -41,7 +41,6 @@
|
||||
#include "gl/gskglrenderer.h"
|
||||
#include "gskprofilerprivate.h"
|
||||
#include "gskrendernodeprivate.h"
|
||||
#include "gskoffloadprivate.h"
|
||||
|
||||
#include "gskenumtypes.h"
|
||||
|
||||
@@ -78,6 +77,7 @@ typedef struct
|
||||
|
||||
GdkSurface *surface;
|
||||
GskRenderNode *prev_node;
|
||||
GskRenderNode *root_node;
|
||||
|
||||
GskProfiler *profiler;
|
||||
|
||||
@@ -363,6 +363,9 @@ gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
|
||||
g_return_val_if_fail (priv->is_realized, NULL);
|
||||
g_return_val_if_fail (GSK_IS_RENDER_NODE (root), NULL);
|
||||
g_return_val_if_fail (priv->root_node == NULL, NULL);
|
||||
|
||||
priv->root_node = gsk_render_node_ref (root);
|
||||
|
||||
if (viewport == NULL)
|
||||
{
|
||||
@@ -374,6 +377,7 @@ gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
texture = GSK_RENDERER_GET_CLASS (renderer)->render_texture (renderer, root, viewport);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (renderer, RENDERER))
|
||||
{
|
||||
GString *buf = g_string_new ("*** Texture stats ***\n\n");
|
||||
@@ -388,6 +392,9 @@ gsk_renderer_render_texture (GskRenderer *renderer,
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -418,25 +425,16 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
|
||||
GskRendererClass *renderer_class;
|
||||
cairo_region_t *clip;
|
||||
GskOffload *offload;
|
||||
|
||||
g_return_if_fail (GSK_IS_RENDERER (renderer));
|
||||
g_return_if_fail (priv->is_realized);
|
||||
g_return_if_fail (GSK_IS_RENDER_NODE (root));
|
||||
g_return_if_fail (priv->root_node == NULL);
|
||||
|
||||
if (priv->surface == NULL)
|
||||
return;
|
||||
|
||||
renderer_class = GSK_RENDERER_GET_CLASS (renderer);
|
||||
|
||||
if (renderer_class->supports_offload &&
|
||||
!GSK_RENDERER_DEBUG_CHECK (renderer, OFFLOAD_DISABLE))
|
||||
offload = gsk_offload_new (priv->surface, root);
|
||||
else
|
||||
offload = NULL;
|
||||
|
||||
if (region == NULL || priv->prev_node == NULL || GSK_RENDERER_DEBUG_CHECK (renderer, FULL_REDRAW))
|
||||
{
|
||||
clip = cairo_region_create_rectangle (&(GdkRectangle) {
|
||||
@@ -448,12 +446,20 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
else
|
||||
{
|
||||
clip = cairo_region_copy (region);
|
||||
gsk_render_node_diff (priv->prev_node, root, clip);
|
||||
|
||||
gsk_render_node_diff (priv->prev_node, root, clip, offload);
|
||||
if (cairo_region_is_empty (clip))
|
||||
{
|
||||
cairo_region_destroy (clip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
renderer_class->render (renderer, root, clip);
|
||||
priv->root_node = gsk_render_node_ref (root);
|
||||
|
||||
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root, clip);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (GSK_RENDERER_DEBUG_CHECK (renderer, RENDERER))
|
||||
{
|
||||
GString *buf = g_string_new ("*** Frame stats ***\n\n");
|
||||
@@ -468,11 +474,12 @@ gsk_renderer_render (GskRenderer *renderer,
|
||||
|
||||
g_string_free (buf, TRUE);
|
||||
}
|
||||
#endif
|
||||
|
||||
g_clear_pointer (&priv->prev_node, gsk_render_node_unref);
|
||||
cairo_region_destroy (clip);
|
||||
g_clear_pointer (&offload, gsk_offload_free);
|
||||
priv->prev_node = gsk_render_node_ref (root);
|
||||
priv->prev_node = priv->root_node;
|
||||
priv->root_node = NULL;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
@@ -677,22 +684,3 @@ gsk_renderer_set_debug_flags (GskRenderer *renderer,
|
||||
|
||||
priv->debug_flags = flags;
|
||||
}
|
||||
|
||||
/* Feed a texture through a renderer and return the resulting 'native' texture. */
|
||||
GdkTexture *
|
||||
gsk_renderer_convert_texture (GskRenderer *self,
|
||||
GdkTexture *texture)
|
||||
{
|
||||
int width, height;
|
||||
GskRenderNode *node;
|
||||
GdkTexture *result;
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
|
||||
node = gsk_texture_node_new (texture, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
result = gsk_renderer_render_texture (self, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "gskrenderer.h"
|
||||
#include "gskprofilerprivate.h"
|
||||
#include "gskdebugprivate.h"
|
||||
#include "gskoffloadprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -38,8 +37,6 @@ struct _GskRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean supports_offload;
|
||||
|
||||
gboolean (* realize) (GskRenderer *renderer,
|
||||
GdkSurface *surface,
|
||||
GError **error);
|
||||
@@ -59,8 +56,5 @@ GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer
|
||||
void gsk_renderer_set_debug_flags (GskRenderer *renderer,
|
||||
GskDebugFlags flags);
|
||||
|
||||
GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
|
||||
GdkTexture *texture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user