Compare commits

..

6 Commits

Author SHA1 Message Date
Matthias Clasen a77fde155d testsubsurface: Add dmabuf support 2023-10-28 22:22:45 -04:00
Matthias Clasen 004c2b8cc2 wayland: Add dmabuf support for subsurfaces
Allow attaching dmabuf textures without downloading.

Currently, this is using create_immed, so failure to import a
dmabuf will be deadly.
2023-10-28 22:22:44 -04:00
Matthias Clasen 0605888ac6 Add testsubsurface
A very simple test that just checks that re(attaching) textures
to subsurfaces and changing stacking order works.
2023-10-28 22:20:45 -04:00
Matthias Clasen ef5b1ba044 wayland: Implement subsurface api
So far, this just allows attaching shm wl_buffers,
so textures will be downloaded and copied.
2023-10-28 22:20:43 -04:00
Matthias Clasen 5fa7457171 gdk: Add private subsurface api
Add api to allow creating subsurfaces, and attaching textures
to them. This is just the api, there is no implementation yet.
2023-10-28 20:57:07 -04:00
Matthias Clasen f50edb6910 wayland: Get format info for dmabufs
For now, all we do with it is dump the formats if you
set GDK_DEBUG=misc. In the future, this will be used
when attaching dmabufs to subsurfaces.
2023-10-25 23:22:55 -04:00
218 changed files with 11035 additions and 17269 deletions
+1 -34
View File
@@ -1,39 +1,6 @@
Overview of Changes in 4.13.3, 15-11-2023
Overview of Changes in 4.13.3, 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
=========================================
-41
View File
@@ -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
-2
View File
@@ -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')
-1
View File
@@ -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>
+6 -5
View 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
^^^^^^^^^
+1 -1
View File
@@ -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)
-6
View File
@@ -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
+2
View File
@@ -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
}
}
+4
View File
@@ -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))
+34 -20
View 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
View File
@@ -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,
+5 -4
View File
@@ -392,7 +392,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);
@@ -1428,6 +1427,7 @@ gdk_display_get_gl_context (GdkDisplay *self)
}
#ifdef HAVE_EGL
#ifdef G_ENABLE_DEBUG
static int
strvcmp (gconstpointer p1,
gconstpointer p2)
@@ -1484,6 +1484,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)
@@ -1784,6 +1785,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 +1809,7 @@ gdk_display_init_egl (GdkDisplay *self,
g_free (std_cfg);
g_free (ext);
}
#endif
gdk_profiler_end_mark (start_time, "init EGL", NULL);
@@ -1885,7 +1888,7 @@ gdk_display_init_dmabuf (GdkDisplay *self)
builder = gdk_dmabuf_formats_builder_new ();
#ifdef HAVE_DMABUF
if (!GDK_DISPLAY_DEBUG_CHECK (self, DMABUF_DISABLE))
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
{
gdk_display_prepare_gl (self, NULL);
@@ -1917,8 +1920,6 @@ gdk_display_init_dmabuf (GdkDisplay *self)
* 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
-1
View File
@@ -122,7 +122,6 @@ struct _GdkDisplay
/* Cached data the EGL dmabuf downloader */
gpointer egl_gsk_renderer;
GdkDmabufFormats *egl_dmabuf_formats;
GdkDmabufFormats *egl_external_formats;
};
+23 -34
View File
@@ -367,24 +367,6 @@ 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
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
@@ -394,10 +376,9 @@ 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_DEBUG (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,
@@ -444,10 +425,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;
@@ -459,9 +439,9 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
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 %.4s:%#lx)",
(char *)&dmabuf->fourcc, dmabuf->modifier);
for (i = 0; i < dmabuf->n_planes; i++)
{
@@ -530,7 +510,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 +523,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,
@@ -579,10 +559,11 @@ gdk_dmabuf_get_direct_downloader (void)
*
* 1. Disallow any dmabuf format that we do not know.
*
* 2. Ignore non-linear modifiers.
* 1. Reject the INVALID modifier, accept the LINEAR one.
*
* 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 ***
*
@@ -611,6 +592,14 @@ gdk_dmabuf_sanitize (GdkDmabuf *dest,
return FALSE;
}
if (src->modifier == DRM_FORMAT_MOD_INVALID)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"GTK does not support the INVALID modifier.");
return FALSE;
}
info = get_drm_format_info (src->fourcc);
if (info == NULL)
+188 -117
View File
@@ -40,130 +40,168 @@
* 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;
GdkGLContext *context = gdk_display_get_gl_context (display);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
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);
gdk_gl_context_make_current (context);
if (egl_display != EGL_NO_DISPLAY &&
display->have_egl_dma_buf_import &&
gdk_gl_context_has_image_storage (context))
{
int num_fourccs;
int *fourccs;
guint64 *modifiers;
unsigned int *external_only;
int n_mods;
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;
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);
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_DEBUG (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 (builder, fourccs[i], modifiers[j]);
}
if (external_only[j])
gdk_dmabuf_formats_builder_add_format (external, fourccs[i], modifiers[j]);
}
}
g_free (modifiers);
g_free (external_only);
g_free (fourccs);
retval = TRUE;
}
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 GdkMemoryFormat
get_memory_format (guint32 fourcc,
gboolean premultiplied)
{
switch (fourcc)
{
case DRM_FORMAT_ARGB8888:
case DRM_FORMAT_ABGR8888:
case DRM_FORMAT_XRGB8888_A8:
case DRM_FORMAT_XBGR8888_A8:
return premultiplied ? GDK_MEMORY_A8R8G8B8_PREMULTIPLIED : GDK_MEMORY_A8R8G8B8;
case DRM_FORMAT_RGBA8888:
case DRM_FORMAT_RGBX8888_A8:
return premultiplied ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED : GDK_MEMORY_R8G8B8A8;
case DRM_FORMAT_BGRA8888:
return premultiplied ? GDK_MEMORY_B8G8R8A8_PREMULTIPLIED : GDK_MEMORY_B8G8R8A8;
case DRM_FORMAT_RGB888:
case DRM_FORMAT_XRGB8888:
case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_RGBX8888:
case DRM_FORMAT_BGRX8888:
return GDK_MEMORY_R8G8B8;
case DRM_FORMAT_BGR888:
return GDK_MEMORY_B8G8R8;
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
case DRM_FORMAT_RGBX1010102:
case DRM_FORMAT_BGRX1010102:
case DRM_FORMAT_XRGB16161616:
case DRM_FORMAT_XBGR16161616:
return GDK_MEMORY_R16G16B16;
case DRM_FORMAT_ARGB2101010:
case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_RGBA1010102:
case DRM_FORMAT_BGRA1010102:
case DRM_FORMAT_ARGB16161616:
case DRM_FORMAT_ABGR16161616:
return premultiplied ? GDK_MEMORY_R16G16B16A16_PREMULTIPLIED : GDK_MEMORY_R16G16B16A16;
case DRM_FORMAT_ARGB16161616F:
case DRM_FORMAT_ABGR16161616F:
return premultiplied ? GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED : GDK_MEMORY_R16G16B16A16_FLOAT;
case DRM_FORMAT_XRGB16161616F:
case DRM_FORMAT_XBGR16161616F:
return GDK_MEMORY_R16G16B16_FLOAT;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_XYUV8888:
#ifdef DRM_FORMAT_XVUY8888
case DRM_FORMAT_XVUY8888:
#endif
case DRM_FORMAT_VUY888:
return GDK_MEMORY_R8G8B8;
/* Add more formats here */
default:
return premultiplied ? GDK_MEMORY_A8R8G8B8_PREMULTIPLIED : GDK_MEMORY_A8R8G8B8;
}
}
static gboolean
gdk_dmabuf_egl_downloader_supports (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
@@ -172,10 +210,49 @@ gdk_dmabuf_egl_downloader_supports (const GdkDmabufDownloader *downloader,
GdkMemoryFormat *out_format,
GError **error)
{
if (gdk_dmabuf_formats_contains (display->egl_dmabuf_formats, dmabuf->fourcc, dmabuf->modifier))
EGLDisplay egl_display;
GdkGLContext *context;
int num_modifiers;
guint64 *modifiers;
unsigned int *external_only;
egl_display = gdk_display_get_egl_display (display);
if (egl_display == EGL_NO_DISPLAY)
{
*out_format = gdk_dmabuf_get_memory_format (display, dmabuf->fourcc, premultiplied);
return TRUE;
g_set_error_literal (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"EGL not available");
return FALSE;
}
context = gdk_display_get_gl_context (display);
gdk_gl_context_make_current (context);
eglQueryDmaBufModifiersEXT (egl_display,
dmabuf->fourcc,
0,
NULL,
NULL,
&num_modifiers);
modifiers = g_newa (uint64_t, num_modifiers);
external_only = g_newa (unsigned int, num_modifiers);
eglQueryDmaBufModifiersEXT (egl_display,
dmabuf->fourcc,
num_modifiers,
modifiers,
external_only,
&num_modifiers);
for (int i = 0; i < num_modifiers; i++)
{
if (modifiers[i] == dmabuf->modifier)
{
*out_format = get_memory_format (dmabuf->fourcc, premultiplied);
return TRUE;
}
}
g_set_error (error,
@@ -309,20 +386,14 @@ gdk_dmabuf_egl_downloader_download (const GdkDmabufDownloader *downloader,
gsize stride)
{
Download download;
const GdkDmabuf *dmabuf;
GDK_DEBUG (DMABUF, "Using %s for downloading a dmabuf", downloader->name);
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);
}
-4
View File
@@ -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.
*
+9
View File
@@ -22,6 +22,9 @@
#include "gdkdmabufformatsprivate.h"
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
@@ -118,6 +121,12 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier)
{
#ifdef HAVE_DMABUF
g_return_if_fail (modifier != DRM_FORMAT_MOD_INVALID);
#else
g_return_if_reached ();
#endif
gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
}
-4
View File
@@ -51,8 +51,4 @@ gboolean gdk_dmabuf_sanitize (GdkDmabuf
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
GdkMemoryFormat gdk_dmabuf_get_memory_format (GdkDisplay *display,
guint32 fourcc,
gboolean premultiplied);
#endif
+2 -2
View File
@@ -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,
+33 -34
View File
@@ -29,6 +29,8 @@
#include <cairo-gobject.h>
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#else
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
@@ -83,15 +85,12 @@ 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_fourcc.h](https://github.com/torvalds/linux/blob/master/include/uapi/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.
@@ -107,12 +106,6 @@ struct _GdkDmabufTextureBuilderClass
* `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 +254,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 +266,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 +278,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 +290,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 +328,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 +343,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 +355,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 +439,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 +458,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 +483,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 +502,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 +527,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 +548,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
*
@@ -613,6 +606,13 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (modifier == DRM_FORMAT_MOD_INVALID)
{
g_critical ("GTK does not support the INVALID modifier. "
"If you use code that produces it, it should include "
"instructions how to transform it into a regular modifier.");
return;
}
if (self->dmabuf.modifier == modifier)
return;
@@ -623,7 +623,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 +685,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 +846,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 +865,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 +888,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 +907,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 +991,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;
}
-21
View File
@@ -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);
}
-1
View File
@@ -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
-5
View File
@@ -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
+2
View File
@@ -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;
+3
View File
@@ -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 */
+6
View File
@@ -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:
+2
View File
@@ -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;
+37 -103
View File
@@ -115,6 +115,7 @@ typedef struct {
guint has_unpack_subimage : 1;
guint has_debug_output : 1;
guint has_bgra : 1;
guint has_image_storage : 1;
guint extensions_checked : 1;
guint debug_enabled : 1;
guint forward_compatible : 1;
@@ -1563,6 +1564,9 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
epoxy_has_gl_extension ("GL_ARB_sync") ||
epoxy_has_gl_extension ("GL_APPLE_sync");
priv->has_image_storage = epoxy_has_gl_extension ("GL_EXT_EGL_image_storage");
#ifdef G_ENABLE_DEBUG
{
int max_texture_size;
glGetIntegerv (GL_MAX_TEXTURE_SIZE, &max_texture_size);
@@ -1573,9 +1577,10 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s\n"
" - GL_EXT_texture_format_BGRA8888: %s\n"
" - GL_EXT_EGL_image_storage: %s\n"
" - half float: %s\n"
" - sync: %s\n"
" - bgra: %s",
" - sync: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
gdk_gl_version_get_major (&priv->gl_version), gdk_gl_version_get_minor (&priv->gl_version),
priv->is_legacy ? "legacy" : "core",
@@ -1583,10 +1588,12 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
max_texture_size,
priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "yes" : "no",
priv->has_bgra ? "yes" : "no",
priv->has_image_storage ? "yes" : "no",
priv->has_half_float ? "yes" : "no",
priv->has_sync ? "yes" : "no",
priv->has_bgra ? "yes" : "no");
priv->has_sync ? "yes" : "no");
}
#endif
priv->extensions_checked = TRUE;
}
@@ -1900,6 +1907,14 @@ gdk_gl_context_has_vertex_arrays (GdkGLContext *self)
}
}
gboolean
gdk_gl_context_has_image_storage (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_image_storage;
}
/* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean
@@ -1981,12 +1996,12 @@ 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)
guint
gdk_gl_context_import_dmabuf (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);
@@ -2003,15 +2018,11 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
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;
}
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);
GDK_DEBUG (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;
@@ -2022,10 +2033,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
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) \
{ \
@@ -2060,9 +2067,7 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
if (image == EGL_NO_IMAGE)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating EGLImage for dmabuf failed: %#x",
eglGetError ());
GDK_DEBUG (DMABUF, "Creating EGLImage for dmabuf failed: %#x", eglGetError ());
return 0;
}
@@ -2080,70 +2085,6 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
#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,
@@ -2170,13 +2111,9 @@ gdk_gl_context_export_dmabuf (GdkGLContext *self,
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;
}
return 0;
GDK_DISPLAY_DEBUG (display, DMABUF, "Exporting GL texture to dmabuf");
GDK_DEBUG (DMABUF, "Exporting GL texture to dmabuf");
i = 0;
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
@@ -2192,8 +2129,7 @@ gdk_gl_context_export_dmabuf (GdkGLContext *self,
if (image == EGL_NO_IMAGE)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating EGLImage for dmabuf failed: %#x", eglGetError ());
GDK_DEBUG (DMABUF, "Creating EGLImage for dmabuf failed: %#x", eglGetError ());
return FALSE;
}
@@ -2203,15 +2139,13 @@ gdk_gl_context_export_dmabuf (GdkGLContext *self,
&n_planes,
&modifier))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"eglExportDMABUFImageQueryMESA failed: %#x", eglGetError ());
GDK_DEBUG (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);
GDK_DEBUG (DMABUF, "dmabufs with %d planes are not supported", n_planes);
goto out;
}
@@ -2245,8 +2179,8 @@ gdk_gl_context_export_dmabuf (GdkGLContext *self,
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)",
GDK_DEBUG (DMABUF,
"Exported GL texture to dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %d)",
(char *)&fourcc, modifier, n_planes);
result = TRUE;
+3 -1
View File
@@ -162,13 +162,15 @@ gboolean gdk_gl_context_has_bgra (GdkGLContext
gboolean gdk_gl_context_has_vertex_arrays (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_image_storage (GdkGLContext *self) G_GNUC_PURE;
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);
int target);
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
unsigned int texture_id,
+27 -27
View File
@@ -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
*
+5 -5
View File
@@ -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,
},
-124
View File
@@ -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);
}
-83
View File
@@ -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
+26 -27
View File
@@ -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
@@ -499,8 +496,6 @@ gdk_surface_real_get_scale (GdkSurface *surface)
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;
}
@@ -769,10 +764,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);
}
@@ -3074,28 +3065,36 @@ gdk_surface_leave_monitor (GdkSurface *surface,
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;
return GDK_SURFACE_GET_CLASS (surface)->create_subsurface (surface);
}
gsize
gdk_surface_get_n_subsurfaces (GdkSurface *surface)
void
gdk_subsurface_destroy (GdkSubsurface *subsurface)
{
return surface->subsurfaces->len;
subsurface->class->destroy (subsurface);
}
GdkSubsurface *
gdk_surface_get_subsurface (GdkSurface *surface,
gsize idx)
void
gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *bounds)
{
return g_ptr_array_index (surface->subsurfaces, idx);
subsurface->class->attach (subsurface, texture, bounds);
}
/* If sibling is NULL, place the subsurface above its parent */
void
gdk_subsurface_place_above (GdkSubsurface *subsurface,
GdkSubsurface *sibling)
{
subsurface->class->place_above (subsurface, sibling);
}
/* If sibling is NULL, place the subsurface below its parent */
void
gdk_subsurface_place_below (GdkSubsurface *subsurface,
GdkSubsurface *sibling)
{
subsurface->class->place_below (subsurface, sibling);
}
+28 -7
View File
@@ -97,8 +97,6 @@ struct _GdkSurface
cairo_region_t *opaque_region;
GdkSeat *current_shortcuts_inhibited_seat;
GPtrArray *subsurfaces;
};
struct _GdkSurfaceClass
@@ -345,10 +343,33 @@ 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);
typedef struct _GdkSubsurfaceClass GdkSubsurfaceClass;
struct _GdkSubsurfaceClass
{
void (* destroy) (GdkSubsurface *subsurface);
void (* attach) (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *bounds);
void (* place_above) (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
void (* place_below) (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
};
struct _GdkSubsurface
{
const GdkSubsurfaceClass *class;
};
void gdk_subsurface_destroy (GdkSubsurface *subsurface);
void gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *bounds);
void gdk_subsurface_place_above (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
void gdk_subsurface_place_below (GdkSubsurface *subsurface,
GdkSubsurface *sibling);
G_END_DECLS
+2
View File
@@ -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,
+10 -2
View File
@@ -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 ();
-1
View File
@@ -55,7 +55,6 @@ gdk_public_sources = files([
'gdktexture.c',
'gdktexturedownloader.c',
'gdkvulkancontext.c',
'gdksubsurface.c',
'gdksurface.c',
'gdkpopuplayout.c',
'gdkprofiler.c',
-18
View File
@@ -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;
+4
View File
@@ -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;
+12 -9
View File
@@ -274,10 +274,7 @@ 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);
GDK_DEBUG (MISC, "supported shm pixel format %.4s (0x%X)", (char *) &format, format);
}
static const struct wl_shm_listener wl_shm_listener = {
@@ -310,7 +307,7 @@ 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;
dev_t dev = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf main device: %u %u", major (dev), minor (dev));
}
@@ -327,7 +324,7 @@ 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;
dev_t dev = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf tranche target device: %u %u", major (dev), minor (dev));
}
@@ -344,9 +341,9 @@ linux_dmabuf_tranche_formats (void *data,
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;
LinuxDmabufFormat *fmt = &display_wayland->linux_dmabuf_formats[*pos];
uint32_t f = fmt->fourcc;
uint64_t m = fmt->modifier;
GDK_DEBUG (MISC, " %.4s:%#" G_GINT64_MODIFIER "x", (char *) &f, m);
}
}
@@ -377,11 +374,13 @@ server_decoration_manager_default_mode (void
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;
@@ -2320,6 +2319,8 @@ gdk_wayland_display_get_setting (GdkDisplay *display,
return FALSE;
}
#ifdef G_ENABLE_DEBUG
static const char *
subpixel_to_string (int layout)
{
@@ -2366,6 +2367,8 @@ transform_to_string (int transform)
return NULL;
}
#endif
static void
update_scale (GdkDisplay *display)
{
+2
View File
@@ -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++)
+2
View File
@@ -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)
-17
View File
@@ -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;
}
+2
View File
@@ -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
+6
View File
@@ -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)
{
+1
View File
@@ -35,6 +35,7 @@
#include <gdk/wayland/gdkdisplay-wayland.h>
#include <gdk/wayland/gdkseat-wayland.h>
#include <gsk/gsk.h>
#include <xkbcommon/xkbcommon.h>
+14
View File
@@ -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);
-407
View File
@@ -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, &params_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);
}
+2 -4
View File
@@ -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;
@@ -87,6 +86,8 @@ struct _GdkWaylandSurface
uint32_t last_configure_serial;
int state_freeze_count;
GPtrArray *subsurfaces;
};
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
@@ -123,9 +124,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;
+244 -83
View File
@@ -34,11 +34,10 @@
#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>
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include <stdlib.h>
#include <stdio.h>
@@ -51,8 +50,6 @@
#include "gdksurface-wayland-private.h"
#include "gdktoplevel-wayland-private.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
/**
* GdkWaylandSurface:
@@ -160,11 +157,15 @@ wl_region_from_cairo_region (GdkWaylandDisplay *display,
/* }}} */
/* {{{ Surface implementation */
static void gdk_wayland_subsurface_destroy (GdkSubsurface *sub);
static void
gdk_wayland_surface_init (GdkWaylandSurface *impl)
{
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (1);
impl->viewport_dirty = TRUE;
impl->subsurfaces = g_ptr_array_new ();
}
void
@@ -199,7 +200,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 +265,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 +280,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 +315,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 +385,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 +410,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 +418,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);
@@ -580,6 +559,7 @@ gdk_wayland_surface_finalize (GObject *object)
g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
g_clear_pointer (&impl->input_region, cairo_region_destroy);
g_clear_pointer (&impl->subsurfaces, g_ptr_array_unref);
G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->finalize (object);
}
@@ -640,25 +620,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 +1019,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;
@@ -1181,6 +1143,17 @@ gdk_wayland_surface_set_input_region (GdkSurface *surface,
impl->input_region_dirty = TRUE;
}
static void
gdk_wayland_surface_destroy_subsurfaces (GdkWaylandSurface *impl)
{
for (gsize i = 0; i < impl->subsurfaces->len; i++)
{
GdkSubsurface *sub = g_ptr_array_index (impl->subsurfaces, i);
gdk_subsurface_destroy (sub);
}
g_ptr_array_set_size (impl->subsurfaces, 0);
}
static void
gdk_wayland_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy)
@@ -1197,6 +1170,7 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
if (GDK_IS_TOPLEVEL (surface))
gdk_wayland_toplevel_destroy (GDK_TOPLEVEL (surface));
gdk_wayland_surface_destroy_subsurfaces (GDK_WAYLAND_SURFACE (surface));
gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE (surface));
frame_clock = gdk_surface_get_frame_clock (surface);
@@ -1356,46 +1330,233 @@ gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
/* }}}} */
/* {{{ Subsurface */
typedef struct {
GdkSubsurface subsurface;
GdkWaylandSurface *parent;
struct wl_surface *wl_surface;
struct wl_subsurface *wl_subsurface;
struct wp_viewport *wp_viewport;
} GdkWaylandSubsurface;
static void
dmabuf_buffer_release (void *data,
struct wl_buffer *wl_buffer)
{
GdkTexture *texture = data;
g_object_unref (texture);
wl_buffer_destroy (wl_buffer);
}
static const struct wl_buffer_listener dmabuf_buffer_listener = {
dmabuf_buffer_release,
};
static struct wl_buffer *
get_dmabuf_wl_buffer (GdkWaylandSubsurface *self,
GdkTexture *texture)
{
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self->parent)));
const GdkDmabuf *dmabuf;
struct zwp_linux_buffer_params_v1 *params;
struct wl_buffer *wl_buffer;
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);
wl_buffer = zwp_linux_buffer_params_v1_create_immed (params,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf->fourcc,
0);
wl_buffer_add_listener (wl_buffer, &dmabuf_buffer_listener, g_object_ref (texture));
return wl_buffer;
}
static void
shm_buffer_release (void *data,
struct wl_buffer *wl_buffer)
{
cairo_surface_t *surface = data;
/* Note: the wl_buffer is destroyed as cairo user data */
cairo_surface_destroy (surface);
}
static const struct wl_buffer_listener shm_buffer_listener = {
shm_buffer_release,
};
static struct wl_buffer *
get_shm_wl_buffer (GdkWaylandSubsurface *self,
GdkTexture *texture)
{
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (GDK_SURFACE (self->parent)));
int width, height;
cairo_surface_t *surface;
GdkTextureDownloader *downloader;
struct wl_buffer *wl_buffer;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
surface = gdk_wayland_display_create_shm_surface (display, width, height, &GDK_FRACTIONAL_SCALE_INIT_INT (1));
downloader = gdk_texture_downloader_new (texture);
gdk_texture_downloader_download_into (downloader,
cairo_image_surface_get_data (surface),
cairo_image_surface_get_stride (surface));
gdk_texture_downloader_free (downloader);
wl_buffer = _gdk_wayland_shm_surface_get_wl_buffer (surface);
wl_buffer_add_listener (wl_buffer, &shm_buffer_listener, surface);
return wl_buffer;
}
static struct wl_buffer *
get_wl_buffer (GdkWaylandSubsurface *self,
GdkTexture *texture)
{
if (GDK_IS_DMABUF_TEXTURE (texture))
return get_dmabuf_wl_buffer (self, texture);
else
return get_shm_wl_buffer (self, texture);
}
static void
gdk_wayland_subsurface_attach (GdkSubsurface *sub,
GdkTexture *texture,
const graphene_rect_t *rect)
{
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
GDK_DEBUG (DMABUF,
"Attaching texture %p at %f %f %f %f",
texture,
rect->origin.x, rect->origin.y, rect->size.width, rect->size.height);
if (rect)
{
wl_subsurface_set_position (self->wl_subsurface,
floorf (rect->origin.x),
floorf (rect->origin.y));
wp_viewport_set_destination (self->wp_viewport,
ceilf (rect->origin.x + rect->size.width) - floorf (rect->origin.x),
ceilf (rect->origin.y + rect->size.height) - floorf (rect->origin.y));
}
if (texture)
{
wl_surface_attach (self->wl_surface, get_wl_buffer (self, texture), 0, 0);
wl_surface_damage_buffer (self->wl_surface,
0, 0,
gdk_texture_get_width (texture),
gdk_texture_get_height (texture));
}
else
{
wl_surface_attach (self->wl_surface, NULL, 0, 0);
}
wl_surface_commit (self->wl_surface);
}
static void
gdk_wayland_subsurface_destroy (GdkSubsurface *sub)
{
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
g_clear_pointer (&self->wp_viewport, wp_viewport_destroy);
g_clear_pointer (&self->wl_subsurface, wl_subsurface_destroy);
g_clear_pointer (&self->wl_surface, wl_surface_destroy);
g_ptr_array_remove (self->parent->subsurfaces, self);
g_free (self);
}
static void
gdk_wayland_subsurface_place_above (GdkSubsurface *sub,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
GdkWaylandSubsurface *sib = (GdkWaylandSubsurface *)sibling;
g_return_if_fail (sib == NULL || self->parent == sib->parent);
wl_subsurface_place_above (self->wl_subsurface,
sib ? sib->wl_surface : self->parent->display_server.wl_surface);
}
static void
gdk_wayland_subsurface_place_below (GdkSubsurface *sub,
GdkSubsurface *sibling)
{
GdkWaylandSubsurface *self = (GdkWaylandSubsurface *)sub;
GdkWaylandSubsurface *sib = (GdkWaylandSubsurface *)sibling;
g_return_if_fail (sib == NULL || self->parent == sib->parent);
wl_subsurface_place_below (self->wl_subsurface,
sib ? sib->wl_surface : self->parent->display_server.wl_surface);
}
static const GdkSubsurfaceClass subsurface_class = {
gdk_wayland_subsurface_destroy,
gdk_wayland_subsurface_attach,
gdk_wayland_subsurface_place_above,
gdk_wayland_subsurface_place_below,
};
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);
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSubsurface *sub;
struct wl_region *region;
struct wl_region *wl_region;
if (disp->viewporter == NULL)
if (display->viewporter == NULL)
{
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Can't use subsurfaces without viewporter");
GDK_DEBUG (DMABUF, "Can't use subsurfaces without viewporter");
return NULL;
}
sub = g_object_new (GDK_TYPE_WAYLAND_SUBSURFACE, NULL);
sub = g_new0 (GdkWaylandSubsurface, 1);
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);
sub->subsurface.class = &subsurface_class;
/* No input, please */
region = wl_compositor_create_region (disp->compositor);
wl_surface_set_input_region (sub->surface, region);
wl_region_destroy (region);
sub->parent = impl;
g_ptr_array_add (sub->parent->subsurfaces, sub);
/* 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->wl_surface = wl_compositor_create_surface (display->compositor);
wl_region = wl_compositor_create_region (display->compositor);
wl_surface_set_input_region (sub->wl_surface, wl_region);
wl_region_destroy (wl_region);
sub->wl_subsurface = wl_subcompositor_get_subsurface (display->subcompositor,
sub->wl_surface,
impl->display_server.wl_surface);
sub->wp_viewport = wp_viewporter_get_viewport (display->viewporter, sub->wl_surface);
sub->above_parent = TRUE;
GDK_DEBUG (DMABUF, "Subsurface created");
GDK_DISPLAY_DEBUG (display, OFFLOAD, "Subsurface %p of surface %p created", sub, impl);
return GDK_SUBSURFACE (sub);
return (GdkSubsurface *) sub;
}
/* }}} */
-18
View File
@@ -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
-1
View File
@@ -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',
+40 -8
View File
@@ -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:
+8
View File
@@ -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);
+2
View File
@@ -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);
+4
View File
@@ -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 */
+10
View File
@@ -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);
+4 -1
View File
@@ -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",
+8
View File
@@ -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)))
{
+10
View File
@@ -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,
+4
View File
@@ -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 */
}
}
}
+4
View File
@@ -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)
{
+6
View File
@@ -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));
+2
View File
@@ -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,
+2
View File
@@ -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
-6
View File
@@ -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:
+8 -9
View File
@@ -609,7 +609,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 +685,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 +1060,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 +1106,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;
@@ -1249,13 +1249,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 +1289,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 +1301,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
gsk_profiler_push_samples (self->profiler);
}
#endif
}
void
@@ -1622,7 +1619,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 +1716,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 +1735,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
}
+1 -3
View File
@@ -101,15 +101,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
+25 -10
View File
@@ -798,6 +798,7 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
GdkDmabufTexture *texture)
{
GdkGLContext *context = self->command_queue->context;
GdkDisplay *display = gdk_gl_context_get_display (context);
int max_texture_size = self->command_queue->max_texture_size;
const GdkDmabuf *dmabuf;
guint texture_id;
@@ -805,7 +806,6 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
GskGLProgram *program;
GskGLRenderTarget *render_target;
guint prev_fbo;
gboolean external;
gdk_gl_context_make_current (context);
@@ -814,24 +814,39 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
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);
GDK_DEBUG (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,
GDK_DEBUG (DMABUF, "DMA-buf Format %.4s:%#lx", (char *) &dmabuf->fourcc, dmabuf->modifier);
gdk_display_init_dmabuf (display);
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
{
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_2D texture");
return gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
GL_TEXTURE_2D);
}
if (!gdk_gl_context_get_use_es (context))
{
GDK_DEBUG (DMABUF, "Can't import external_only dmabuf outside of GLES");
return 0;
}
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_EXTERNAL_OES texture");
texture_id = gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
&external);
GL_TEXTURE_EXTERNAL_OES);
if (texture_id == 0)
return 0;
if (!external)
return texture_id;
gsk_gl_driver_autorelease_texture (self, texture_id);
program = self->external;
+1 -1
View File
@@ -148,7 +148,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 +161,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,
+7 -12
View File
@@ -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);
@@ -385,7 +380,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
format = GL_RGBA32F;
}
else
else
{
format = GL_RGBA8;
gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
@@ -400,8 +395,10 @@ 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);
@@ -438,8 +435,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;
+4 -50
View File
@@ -31,12 +31,9 @@
#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,12 +44,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
@@ -302,7 +297,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 +353,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 +1226,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 +1242,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 +2824,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
@@ -3660,8 +3655,6 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
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;
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
init_full_texture_region (offscreen);
@@ -3956,7 +3949,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 +3996,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 +4192,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 +4513,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
+2
View File
@@ -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;
}
+14
View File
@@ -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
View File
@@ -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);
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
/**
+4
View File
@@ -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
-670
View File
@@ -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;
}
-52
View File
@@ -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);
-9
View File
@@ -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 -15
View File
@@ -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 >
-3
View File
@@ -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);
+14 -37
View File
@@ -154,9 +154,9 @@ gsk_render_node_real_can_diff (const GskRenderNode *node1,
static void
gsk_render_node_real_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -392,6 +392,7 @@ gsk_render_node_draw (GskRenderNode *node,
GSK_RENDER_NODE_GET_CLASS (node)->draw (node, cr);
#ifdef G_ENABLE_DEBUG
if (GSK_DEBUG_CHECK (GEOMETRY))
{
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
@@ -401,6 +402,7 @@ gsk_render_node_draw (GskRenderNode *node,
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
cairo_stroke (cr);
}
#endif
cairo_restore (cr);
@@ -457,14 +459,14 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
void
gsk_render_node_diff_impossible (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
cairo_rectangle_int_t rect;
rectangle_init_from_graphene (&rect, &node1->bounds);
cairo_region_union_rectangle (data->region, &rect);
cairo_region_union_rectangle (region, &rect);
rectangle_init_from_graphene (&rect, &node2->bounds);
cairo_region_union_rectangle (data->region, &rect);
cairo_region_union_rectangle (region, &rect);
}
/**
@@ -472,7 +474,6 @@ gsk_render_node_diff_impossible (GskRenderNode *node1,
* @node1: a `GskRenderNode`
* @node2: the `GskRenderNode` to compare with
* @region: a `cairo_region_t` to add the differences to
* @subsurfaces: (nullable): array to add offload info to
*
* Compares @node1 and @node2 trying to compute the minimal region of changes.
*
@@ -485,48 +486,24 @@ gsk_render_node_diff_impossible (GskRenderNode *node1,
*
* Note that the passed in @region may already contain previous results from
* previous node comparisons, so this function call will only add to it.
*
* If @subsurface_nodes is not `NULL`, then we treat subsurface nodes as
* identical if they refer to the same subsurface and have the same bounds.
* In this case, we collect subsurface nodes we see in @subsurface_nodes,
* for later updating of the attached textures.
*
* If @subsurface_area is not `NULL`, it will collect the full area of all
* subsurface nodes we meet.
*/
**/
void
gsk_render_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
cairo_region_t *region,
GskOffload *offload)
{
gsk_render_node_data_diff (node1, node2, &(GskDiffData) { region, offload });
}
void
gsk_render_node_data_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
if (node1 == node2)
return;
if (_gsk_render_node_get_node_type (node1) == _gsk_render_node_get_node_type (node2))
{
GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, data);
}
GSK_RENDER_NODE_GET_CLASS (node1)->diff (node1, node2, region);
else if (_gsk_render_node_get_node_type (node1) == GSK_CONTAINER_NODE)
{
gsk_container_node_diff_with (node1, node2, data);
}
gsk_container_node_diff_with (node1, node2, region);
else if (_gsk_render_node_get_node_type (node2) == GSK_CONTAINER_NODE)
{
gsk_container_node_diff_with (node2, node1, data);
}
gsk_container_node_diff_with (node2, node1, region);
else
{
gsk_render_node_diff_impossible (node1, node2, data);
}
gsk_render_node_diff_impossible (node1, node2, region);
}
/**
-12
View File
@@ -166,7 +166,6 @@ GskRenderNode * gsk_render_node_deserialize (GBytes
#define GSK_TYPE_BLUR_NODE (gsk_blur_node_get_type())
#define GSK_TYPE_MASK_NODE (gsk_mask_node_get_type())
#define GSK_TYPE_GL_SHADER_NODE (gsk_gl_shader_node_get_type())
#define GSK_TYPE_SUBSURFACE_NODE (gsk_subsurface_node_get_type())
typedef struct _GskDebugNode GskDebugNode;
typedef struct _GskColorNode GskColorNode;
@@ -197,7 +196,6 @@ typedef struct _GskTextNode GskTextNode;
typedef struct _GskBlurNode GskBlurNode;
typedef struct _GskMaskNode GskMaskNode;
typedef struct _GskGLShaderNode GskGLShaderNode;
typedef struct _GskSubsurfaceNode GskSubsurfaceNode;
GDK_AVAILABLE_IN_ALL
GType gsk_debug_node_get_type (void) G_GNUC_CONST;
@@ -592,16 +590,6 @@ GBytes * gsk_gl_shader_node_get_args (const GskRender
GDK_AVAILABLE_IN_ALL
GskGLShader * gsk_gl_shader_node_get_shader (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
GType gsk_subsurface_node_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GskRenderNode * gsk_subsurface_node_new (GskRenderNode *child,
gpointer subsurface);
GDK_AVAILABLE_IN_4_14
GskRenderNode * gsk_subsurface_node_get_child (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
gpointer gsk_subsurface_node_get_subsurface (const GskRenderNode *node);
/**
* GSK_VALUE_HOLDS_RENDER_NODE:
* @value: a `GValue`
+117 -282
View File
@@ -31,13 +31,11 @@
#include "gskroundedrectprivate.h"
#include "gskstrokeprivate.h"
#include "gsktransformprivate.h"
#include "gskoffloadprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
#include "gdk/gdkprivate.h"
#include "gdk/gdkrectangleprivate.h"
#include "gdk/gdksubsurfaceprivate.h"
#include <cairo.h>
#ifdef CAIRO_HAS_SVG_SURFACE
@@ -128,16 +126,16 @@ gsk_color_node_draw (GskRenderNode *node,
static void
gsk_color_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskColorNode *self1 = (GskColorNode *) node1;
GskColorNode *self2 = (GskColorNode *) node2;
if (gsk_rect_equal (&node1->bounds, &node2->bounds) &&
if (graphene_rect_equal (&node1->bounds, &node2->bounds) &&
gdk_rgba_equal (&self1->color, &self2->color))
return;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -284,7 +282,7 @@ gsk_linear_gradient_node_draw (GskRenderNode *node,
static void
gsk_linear_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskLinearGradientNode *self1 = (GskLinearGradientNode *) node1;
GskLinearGradientNode *self2 = (GskLinearGradientNode *) node2;
@@ -304,14 +302,14 @@ gsk_linear_gradient_node_diff (GskRenderNode *node1,
gdk_rgba_equal (&stop1->color, &stop2->color))
continue;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
return;
}
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -613,7 +611,7 @@ gsk_radial_gradient_node_draw (GskRenderNode *node,
static void
gsk_radial_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskRadialGradientNode *self1 = (GskRadialGradientNode *) node1;
GskRadialGradientNode *self2 = (GskRadialGradientNode *) node2;
@@ -636,14 +634,14 @@ gsk_radial_gradient_node_diff (GskRenderNode *node1,
gdk_rgba_equal (&stop1->color, &stop2->color))
continue;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
return;
}
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -1104,7 +1102,7 @@ gsk_conic_gradient_node_draw (GskRenderNode *node,
static void
gsk_conic_gradient_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskConicGradientNode *self1 = (GskConicGradientNode *) node1;
GskConicGradientNode *self2 = (GskConicGradientNode *) node2;
@@ -1114,7 +1112,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1,
self1->rotation != self2->rotation ||
self1->n_stops != self2->n_stops)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -1126,7 +1124,7 @@ gsk_conic_gradient_node_diff (GskRenderNode *node1,
if (stop1->offset != stop2->offset ||
!gdk_rgba_equal (&stop1->color, &stop2->color))
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
}
@@ -1456,7 +1454,7 @@ gsk_border_node_draw (GskRenderNode *node,
static void
gsk_border_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskBorderNode *self1 = (GskBorderNode *) node1;
GskBorderNode *self2 = (GskBorderNode *) node2;
@@ -1473,7 +1471,7 @@ gsk_border_node_diff (GskRenderNode *node1,
/* Different uniformity -> diff impossible */
if (uniform1 ^ uniform2)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -1488,7 +1486,7 @@ gsk_border_node_diff (GskRenderNode *node1,
gsk_rounded_rect_equal (&self1->outline, &self2->outline))
return;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -1681,17 +1679,17 @@ gsk_texture_node_draw (GskRenderNode *node,
static void
gsk_texture_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskTextureNode *self1 = (GskTextureNode *) node1;
GskTextureNode *self2 = (GskTextureNode *) node2;
cairo_region_t *sub;
if (!gsk_rect_equal (&node1->bounds, &node2->bounds) ||
if (!graphene_rect_equal (&node1->bounds, &node2->bounds) ||
gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) ||
gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture))
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -1700,7 +1698,7 @@ gsk_texture_node_diff (GskRenderNode *node1,
sub = cairo_region_create ();
gdk_texture_diff (self1->texture, self2->texture, sub);
region_union_region_affine (data->region,
region_union_region_affine (region,
sub,
node1->bounds.size.width / gdk_texture_get_width (self1->texture),
node1->bounds.size.height / gdk_texture_get_height (self1->texture),
@@ -1840,7 +1838,6 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
cairo_matrix_init_scale (&matrix,
gdk_texture_get_width (self->texture) / node->bounds.size.width,
gdk_texture_get_height (self->texture) / node->bounds.size.height);
cairo_matrix_translate (&matrix, -node->bounds.origin.x, -node->bounds.origin.y);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_pattern_set_filter (pattern, filters[self->filter]);
@@ -1848,15 +1845,23 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface);
gsk_cairo_rectangle (cr2, &node->bounds);
cairo_rectangle (cr2, 0, 0, node->bounds.size.width, node->bounds.size.height);
cairo_fill (cr2);
cairo_destroy (cr2);
cairo_save (cr);
cairo_set_source_surface (cr, surface2, 0, 0);
cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
pattern = cairo_pattern_create_for_surface (surface2);
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
cairo_matrix_init_identity (&matrix);
cairo_matrix_translate (&matrix,
-node->bounds.origin.x,
-node->bounds.origin.y);
cairo_pattern_set_matrix (pattern, &matrix);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
cairo_surface_destroy (surface2);
gsk_cairo_rectangle (cr, &node->bounds);
@@ -1868,18 +1873,18 @@ gsk_texture_scale_node_draw (GskRenderNode *node,
static void
gsk_texture_scale_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskTextureScaleNode *self1 = (GskTextureScaleNode *) node1;
GskTextureScaleNode *self2 = (GskTextureScaleNode *) node2;
cairo_region_t *sub;
if (!gsk_rect_equal (&node1->bounds, &node2->bounds) ||
if (!graphene_rect_equal (&node1->bounds, &node2->bounds) ||
self1->filter != self2->filter ||
gdk_texture_get_width (self1->texture) != gdk_texture_get_width (self2->texture) ||
gdk_texture_get_height (self1->texture) != gdk_texture_get_height (self2->texture))
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -1888,7 +1893,7 @@ gsk_texture_scale_node_diff (GskRenderNode *node1,
sub = cairo_region_create ();
gdk_texture_diff (self1->texture, self2->texture, sub);
region_union_region_affine (data->region,
region_union_region_affine (region,
sub,
node1->bounds.size.width / gdk_texture_get_width (self1->texture),
node1->bounds.size.height / gdk_texture_get_height (self1->texture),
@@ -2343,7 +2348,10 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
* We could remove the part of "box" where the blur doesn't
* reach, but computing that is a bit tricky since the
* rounded corners are on the "inside" of it. */
rectangle_init_from_graphene (&r, &clip_box.bounds);
r.x = floor (clip_box.bounds.origin.x);
r.y = floor (clip_box.bounds.origin.y);
r.width = ceil (clip_box.bounds.origin.x + clip_box.bounds.size.width) - r.x;
r.height = ceil (clip_box.bounds.origin.y + clip_box.bounds.size.height) - r.y;
remaining = cairo_region_create_rectangle (&r);
/* First do the corners of box */
@@ -2391,7 +2399,7 @@ gsk_inset_shadow_node_draw (GskRenderNode *node,
static void
gsk_inset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskInsetShadowNode *self1 = (GskInsetShadowNode *) node1;
GskInsetShadowNode *self2 = (GskInsetShadowNode *) node2;
@@ -2404,7 +2412,7 @@ gsk_inset_shadow_node_diff (GskRenderNode *node1,
self1->blur_radius == self2->blur_radius)
return;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -2704,7 +2712,7 @@ gsk_outset_shadow_node_draw (GskRenderNode *node,
static void
gsk_outset_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskOutsetShadowNode *self1 = (GskOutsetShadowNode *) node1;
GskOutsetShadowNode *self2 = (GskOutsetShadowNode *) node2;
@@ -2717,7 +2725,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
self1->blur_radius == self2->blur_radius)
return;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -3084,10 +3092,8 @@ gsk_container_node_compare_func (gconstpointer elem1, gconstpointer elem2, gpoin
static GskDiffResult
gsk_container_node_keep_func (gconstpointer elem1, gconstpointer elem2, gpointer data)
{
GskDiffData *gd = data;
gsk_render_node_data_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, gd);
if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF)
gsk_render_node_diff ((GskRenderNode *) elem1, (GskRenderNode *) elem2, data);
if (cairo_region_num_rectangles (data) > MAX_RECTS_IN_DIFF)
return GSK_DIFF_ABORTED;
return GSK_DIFF_OK;
@@ -3097,12 +3103,12 @@ static GskDiffResult
gsk_container_node_change_func (gconstpointer elem, gsize idx, gpointer data)
{
const GskRenderNode *node = elem;
GskDiffData *gd = data;
cairo_region_t *region = data;
cairo_rectangle_int_t rect;
rectangle_init_from_graphene (&rect, &node->bounds);
cairo_region_union_rectangle (gd->region, &rect);
if (cairo_region_num_rectangles (gd->region) > MAX_RECTS_IN_DIFF)
cairo_region_union_rectangle (region, &rect);
if (cairo_region_num_rectangles (region) > MAX_RECTS_IN_DIFF)
return GSK_DIFF_ABORTED;
return GSK_DIFF_OK;
@@ -3130,18 +3136,18 @@ gsk_render_node_diff_multiple (GskRenderNode **nodes1,
gsize n_nodes1,
GskRenderNode **nodes2,
gsize n_nodes2,
GskDiffData *data)
cairo_region_t *region)
{
return gsk_diff ((gconstpointer *) nodes1, n_nodes1,
(gconstpointer *) nodes2, n_nodes2,
gsk_container_node_get_diff_settings (),
data) == GSK_DIFF_OK;
region) == GSK_DIFF_OK;
}
void
gsk_container_node_diff_with (GskRenderNode *container,
GskRenderNode *other,
GskDiffData *data)
cairo_region_t *region)
{
GskContainerNode *self = (GskContainerNode *) container;
@@ -3149,16 +3155,16 @@ gsk_container_node_diff_with (GskRenderNode *container,
self->n_children,
&other,
1,
data))
region))
return;
gsk_render_node_diff_impossible (container, other, data);
gsk_render_node_diff_impossible (container, other, region);
}
static void
gsk_container_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskContainerNode *self1 = (GskContainerNode *) node1;
GskContainerNode *self2 = (GskContainerNode *) node2;
@@ -3167,10 +3173,10 @@ gsk_container_node_diff (GskRenderNode *node1,
self1->n_children,
self2->children,
self2->n_children,
data))
region))
return;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -3390,14 +3396,14 @@ gsk_transform_node_can_diff (const GskRenderNode *node1,
static void
gsk_transform_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskTransformNode *self1 = (GskTransformNode *) node1;
GskTransformNode *self2 = (GskTransformNode *) node2;
if (!gsk_transform_equal (self1->transform, self2->transform))
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -3407,7 +3413,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
switch (gsk_transform_get_category (self1->transform))
{
case GSK_TRANSFORM_CATEGORY_IDENTITY:
gsk_render_node_data_diff (self1->child, self2->child, data);
gsk_render_node_diff (self1->child, self2->child, region);
break;
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
@@ -3416,7 +3422,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
float dx, dy;
gsk_transform_to_translate (self1->transform, &dx, &dy);
sub = cairo_region_create ();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
cairo_region_translate (sub, floorf (dx), floorf (dy));
if (floorf (dx) != dx)
{
@@ -3432,7 +3438,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
cairo_region_union (sub, tmp);
cairo_region_destroy (tmp);
}
cairo_region_union (data->region, sub);
cairo_region_union (region, sub);
cairo_region_destroy (sub);
}
break;
@@ -3443,8 +3449,8 @@ gsk_transform_node_diff (GskRenderNode *node1,
float scale_x, scale_y, dx, dy;
gsk_transform_to_affine (self1->transform, &scale_x, &scale_y, &dx, &dy);
sub = cairo_region_create ();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
region_union_region_affine (data->region, sub, scale_x, scale_y, dx, dy);
gsk_render_node_diff (self1->child, self2->child, sub);
region_union_region_affine (region, sub, scale_x, scale_y, dx, dy);
cairo_region_destroy (sub);
}
break;
@@ -3454,7 +3460,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
case GSK_TRANSFORM_CATEGORY_3D:
case GSK_TRANSFORM_CATEGORY_2D:
default:
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
break;
}
}
@@ -3609,15 +3615,15 @@ gsk_opacity_node_draw (GskRenderNode *node,
static void
gsk_opacity_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskOpacityNode *self1 = (GskOpacityNode *) node1;
GskOpacityNode *self2 = (GskOpacityNode *) node2;
if (self1->opacity == self2->opacity)
gsk_render_node_data_diff (self1->child, self2->child, data);
gsk_render_node_diff (self1->child, self2->child, region);
else
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -3824,7 +3830,7 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
static void
gsk_color_matrix_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskColorMatrixNode *self1 = (GskColorMatrixNode *) node1;
GskColorMatrixNode *self2 = (GskColorMatrixNode *) node2;
@@ -3835,11 +3841,11 @@ gsk_color_matrix_node_diff (GskRenderNode *node1,
if (!graphene_matrix_equal_fast (&self1->color_matrix, &self2->color_matrix))
goto nope;
gsk_render_node_data_diff (self1->child, self2->child, data);
gsk_render_node_diff (self1->child, self2->child, region);
return;
nope:
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -4144,26 +4150,26 @@ gsk_clip_node_draw (GskRenderNode *node,
static void
gsk_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskClipNode *self1 = (GskClipNode *) node1;
GskClipNode *self2 = (GskClipNode *) node2;
if (gsk_rect_equal (&self1->clip, &self2->clip))
if (graphene_rect_equal (&self1->clip, &self2->clip))
{
cairo_region_t *sub;
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
rectangle_init_from_graphene (&clip_rect, &self1->clip);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_union (region, sub);
cairo_region_destroy (sub);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -4292,7 +4298,7 @@ gsk_rounded_clip_node_draw (GskRenderNode *node,
static void
gsk_rounded_clip_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskRoundedClipNode *self1 = (GskRoundedClipNode *) node1;
GskRoundedClipNode *self2 = (GskRoundedClipNode *) node2;
@@ -4303,15 +4309,15 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
rectangle_init_from_graphene (&clip_rect, &self1->clip.bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_union (region, sub);
cairo_region_destroy (sub);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -4466,7 +4472,7 @@ gsk_fill_node_draw (GskRenderNode *node,
static void
gsk_fill_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskFillNode *self1 = (GskFillNode *) node1;
GskFillNode *self2 = (GskFillNode *) node2;
@@ -4477,15 +4483,15 @@ gsk_fill_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
rectangle_init_from_graphene (&clip_rect, &node1->bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_union (region, sub);
cairo_region_destroy (sub);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -4670,7 +4676,7 @@ gsk_stroke_node_draw (GskRenderNode *node,
static void
gsk_stroke_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskStrokeNode *self1 = (GskStrokeNode *) node1;
GskStrokeNode *self2 = (GskStrokeNode *) node2;
@@ -4682,15 +4688,15 @@ gsk_stroke_node_diff (GskRenderNode *node1,
cairo_rectangle_int_t clip_rect;
sub = cairo_region_create();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
rectangle_init_from_graphene (&clip_rect, &node1->bounds);
cairo_region_intersect_rectangle (sub, &clip_rect);
cairo_region_union (data->region, sub);
cairo_region_union (region, sub);
cairo_region_destroy (sub);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -4886,7 +4892,7 @@ gsk_shadow_node_draw (GskRenderNode *node,
static void
gsk_shadow_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskShadowNode *self1 = (GskShadowNode *) node1;
GskShadowNode *self2 = (GskShadowNode *) node2;
@@ -4897,7 +4903,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
if (self1->n_shadows != self2->n_shadows)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -4912,7 +4918,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
shadow1->dy != shadow2->dy ||
shadow1->radius != shadow2->radius)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
@@ -4924,7 +4930,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
}
sub = cairo_region_create ();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) { sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
n = cairo_region_num_rectangles (sub);
for (i = 0; i < n; i++)
@@ -4934,7 +4940,7 @@ gsk_shadow_node_diff (GskRenderNode *node1,
rect.y -= top;
rect.width += left + right;
rect.height += top + bottom;
cairo_region_union_rectangle (data->region, &rect);
cairo_region_union_rectangle (region, &rect);
}
cairo_region_destroy (sub);
}
@@ -5159,19 +5165,19 @@ gsk_blend_node_draw (GskRenderNode *node,
static void
gsk_blend_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskBlendNode *self1 = (GskBlendNode *) node1;
GskBlendNode *self2 = (GskBlendNode *) node2;
if (self1->blend_mode == self2->blend_mode)
{
gsk_render_node_data_diff (self1->top, self2->top, data);
gsk_render_node_data_diff (self1->bottom, self2->bottom, data);
gsk_render_node_diff (self1->top, self2->top, region);
gsk_render_node_diff (self1->bottom, self2->bottom, region);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -5326,19 +5332,19 @@ gsk_cross_fade_node_draw (GskRenderNode *node,
static void
gsk_cross_fade_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskCrossFadeNode *self1 = (GskCrossFadeNode *) node1;
GskCrossFadeNode *self2 = (GskCrossFadeNode *) node2;
if (self1->progress == self2->progress)
{
gsk_render_node_data_diff (self1->start, self2->start, data);
gsk_render_node_data_diff (self1->end, self2->end, data);
gsk_render_node_diff (self1->start, self2->start, region);
gsk_render_node_diff (self1->end, self2->end, region);
return;
}
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -5497,7 +5503,7 @@ gsk_text_node_draw (GskRenderNode *node,
static void
gsk_text_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskTextNode *self1 = (GskTextNode *) node1;
GskTextNode *self2 = (GskTextNode *) node2;
@@ -5522,14 +5528,14 @@ gsk_text_node_diff (GskRenderNode *node1,
info1->attr.is_color == info2->attr.is_color)
continue;
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
return;
}
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
static void
@@ -5935,7 +5941,7 @@ gsk_blur_node_draw (GskRenderNode *node,
static void
gsk_blur_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskBlurNode *self1 = (GskBlurNode *) node1;
GskBlurNode *self2 = (GskBlurNode *) node2;
@@ -5948,7 +5954,7 @@ gsk_blur_node_diff (GskRenderNode *node1,
clip_radius = ceil (gsk_cairo_blur_compute_pixels (self1->radius / 2.0));
sub = cairo_region_create ();
gsk_render_node_data_diff (self1->child, self2->child, &(GskDiffData) {sub, data->offload });
gsk_render_node_diff (self1->child, self2->child, sub);
n = cairo_region_num_rectangles (sub);
for (i = 0; i < n; i++)
@@ -5958,13 +5964,13 @@ gsk_blur_node_diff (GskRenderNode *node1,
rect.y -= clip_radius;
rect.width += 2 * clip_radius;
rect.height += 2 * clip_radius;
cairo_region_union_rectangle (data->region, &rect);
cairo_region_union_rectangle (region, &rect);
}
cairo_region_destroy (sub);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -6179,19 +6185,19 @@ gsk_mask_node_draw (GskRenderNode *node,
static void
gsk_mask_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskMaskNode *self1 = (GskMaskNode *) node1;
GskMaskNode *self2 = (GskMaskNode *) node2;
if (self1->mask_mode != self2->mask_mode)
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
return;
}
gsk_render_node_data_diff (self1->source, self2->source, data);
gsk_render_node_data_diff (self1->mask, self2->mask, data);
gsk_render_node_diff (self1->source, self2->source, region);
gsk_render_node_diff (self1->mask, self2->mask, region);
}
static void
@@ -6354,12 +6360,12 @@ gsk_debug_node_can_diff (const GskRenderNode *node1,
static void
gsk_debug_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskDebugNode *self1 = (GskDebugNode *) node1;
GskDebugNode *self2 = (GskDebugNode *) node2;
gsk_render_node_data_diff (self1->child, self2->child, data);
gsk_render_node_diff (self1->child, self2->child, region);
}
static void
@@ -6490,26 +6496,26 @@ gsk_gl_shader_node_draw (GskRenderNode *node,
static void
gsk_gl_shader_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
cairo_region_t *region)
{
GskGLShaderNode *self1 = (GskGLShaderNode *) node1;
GskGLShaderNode *self2 = (GskGLShaderNode *) node2;
if (gsk_rect_equal (&node1->bounds, &node2->bounds) &&
if (graphene_rect_equal (&node1->bounds, &node2->bounds) &&
self1->shader == self2->shader &&
g_bytes_compare (self1->args, self2->args) == 0 &&
self1->n_children == self2->n_children)
{
cairo_region_t *child_region = cairo_region_create();
for (guint i = 0; i < self1->n_children; i++)
gsk_render_node_data_diff (self1->children[i], self2->children[i], &(GskDiffData) {child_region, data->offload });
gsk_render_node_diff (self1->children[i], self2->children[i], child_region);
if (!cairo_region_is_empty (child_region))
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
cairo_region_destroy (child_region);
}
else
{
gsk_render_node_diff_impossible (node1, node2, data);
gsk_render_node_diff_impossible (node1, node2, region);
}
}
@@ -6663,171 +6669,6 @@ gsk_gl_shader_node_get_args (const GskRenderNode *node)
return self->args;
}
/* }}} */
/* {{{ GSK_SUBSURFACE_NODE */
/**
* GskSubsurfaceNode:
*
* A render node that potentially diverts a part of the scene graph to a subsurface.
*/
struct _GskSubsurfaceNode
{
GskRenderNode render_node;
GskRenderNode *child;
GdkSubsurface *subsurface;
};
static void
gsk_subsurface_node_finalize (GskRenderNode *node)
{
GskSubsurfaceNode *self = (GskSubsurfaceNode *) node;
GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_SUBSURFACE_NODE));
gsk_render_node_unref (self->child);
g_clear_object (&self->subsurface);
parent_class->finalize (node);
}
static void
gsk_subsurface_node_draw (GskRenderNode *node,
cairo_t *cr)
{
GskSubsurfaceNode *self = (GskSubsurfaceNode *) node;
gsk_render_node_draw (self->child, cr);
}
static gboolean
gsk_subsurface_node_can_diff (const GskRenderNode *node1,
const GskRenderNode *node2)
{
GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1;
GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2;
return self1->subsurface == self2->subsurface;
}
static void
gsk_subsurface_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data)
{
GskSubsurfaceNode *self1 = (GskSubsurfaceNode *) node1;
GskSubsurfaceNode *self2 = (GskSubsurfaceNode *) node2;
if (data->offload)
{
/* Include the full area if the offload status changed. */
if (gsk_offload_subsurface_was_offloaded (data->offload, self1->subsurface) !=
gsk_offload_subsurface_is_offloaded (data->offload, self1->subsurface))
{
gsk_render_node_diff_impossible (node1, node2, data);
}
else if (gsk_offload_subsurface_is_offloaded (data->offload, self1->subsurface))
{
if (!gsk_rect_equal (&node1->bounds, &node2->bounds))
gsk_render_node_diff_impossible (node1, node2, data);
}
else
{
gsk_render_node_data_diff (self1->child, self2->child, data);
}
}
else
gsk_render_node_data_diff (self1->child, self2->child, data);
}
static void
gsk_subsurface_node_class_init (gpointer g_class,
gpointer class_data)
{
GskRenderNodeClass *node_class = g_class;
node_class->node_type = GSK_SUBSURFACE_NODE;
node_class->finalize = gsk_subsurface_node_finalize;
node_class->draw = gsk_subsurface_node_draw;
node_class->can_diff = gsk_subsurface_node_can_diff;
node_class->diff = gsk_subsurface_node_diff;
}
/**
* gsk_subsurface_node_new:
* @child: The child to divert to a subsurface
* @subsurface: (nullable): the subsurface to use
*
* Creates a `GskRenderNode` that will possibly divert the child
* node to a subsurface.
*
* Returns: (transfer full) (type GskSubsurfaceNode): A new `GskRenderNode`
*
* Since: 4.14
*/
GskRenderNode *
gsk_subsurface_node_new (GskRenderNode *child,
gpointer subsurface)
{
GskSubsurfaceNode *self;
GskRenderNode *node;
g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL);
self = gsk_render_node_alloc (GSK_SUBSURFACE_NODE);
node = (GskRenderNode *) self;
node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
if (subsurface)
self->subsurface = g_object_ref (subsurface);
else
self->subsurface = NULL;
graphene_rect_init_from_rect (&node->bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
return node;
}
/**
* gsk_subsurface_node_get_child:
* @node: (type GskSubsurfaceNode): a debug `GskRenderNode`
*
* Gets the child node that is getting drawn by the given @node.
*
* Returns: (transfer none): the child `GskRenderNode`
*
* Since: 4.14
*/
GskRenderNode *
gsk_subsurface_node_get_child (const GskRenderNode *node)
{
const GskSubsurfaceNode *self = (const GskSubsurfaceNode *) node;
return self->child;
}
/**
* gsk_subsurface_node_get_subsurface:
* @node: (type GskDebugNode): a debug `GskRenderNode`
*
* Gets the subsurface that was set on this node
*
* Returns: (transfer none) (nullable): the subsurface
*
* Since: 4.14
*/
gpointer
gsk_subsurface_node_get_subsurface (const GskRenderNode *node)
{
const GskSubsurfaceNode *self = (const GskSubsurfaceNode *) node;
return self->subsurface;
}
/* }}} */
GType gsk_render_node_types[GSK_RENDER_NODE_TYPE_N_TYPES];
@@ -6873,7 +6714,6 @@ GSK_DEFINE_RENDER_NODE_TYPE (gsk_blur_node, GSK_BLUR_NODE)
GSK_DEFINE_RENDER_NODE_TYPE (gsk_mask_node, GSK_MASK_NODE)
GSK_DEFINE_RENDER_NODE_TYPE (gsk_gl_shader_node, GSK_GL_SHADER_NODE)
GSK_DEFINE_RENDER_NODE_TYPE (gsk_debug_node, GSK_DEBUG_NODE)
GSK_DEFINE_RENDER_NODE_TYPE (gsk_subsurface_node, GSK_SUBSURFACE_NODE)
static void
gsk_render_node_init_types_once (void)
@@ -7024,11 +6864,6 @@ gsk_render_node_init_types_once (void)
sizeof (GskStrokeNode),
gsk_stroke_node_class_init);
gsk_render_node_types[GSK_STROKE_NODE] = node_type;
node_type = gsk_render_node_type_register_static (I_("GskSubsurfaceNode"),
sizeof (GskSubsurfaceNode),
gsk_subsurface_node_class_init);
gsk_render_node_types[GSK_SUBSURFACE_NODE] = node_type;
}
static void
+1 -37
View File
@@ -65,7 +65,7 @@ struct _Declaration
};
static void
context_init (Context *context)
context_init (Context *context)
{
memset (context, 0, sizeof (Context));
}
@@ -2405,27 +2405,6 @@ parse_debug_node (GtkCssParser *parser,
return result;
}
static GskRenderNode *
parse_subsurface_node (GtkCssParser *parser,
Context *context)
{
GskRenderNode *child = NULL;
const Declaration declarations[] = {
{ "child", parse_node, clear_node, &child },
};
GskRenderNode *result;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
if (child == NULL)
child = create_default_render_node ();
result = gsk_subsurface_node_new (child, NULL);
gsk_render_node_unref (child);
return result;
}
static gboolean
parse_node (GtkCssParser *parser,
Context *context,
@@ -2464,7 +2443,6 @@ parse_node (GtkCssParser *parser,
{ "transform", parse_transform_node },
{ "glshader", parse_glshader_node },
{ "mask", parse_mask_node },
{ "subsurface", parse_subsurface_node },
};
GskRenderNode **node_p = out_node;
const GtkCssToken *token;
@@ -2601,7 +2579,6 @@ gsk_render_node_deserialize_from_bytes (GBytes *bytes,
parser = gtk_css_parser_new_for_bytes (bytes, NULL, gsk_render_node_parser_error,
&error_func_pair, NULL);
context_init (&context);
root = parse_container_node (parser, &context);
if (root && gsk_container_node_get_n_children (root) == 1)
@@ -2620,7 +2597,6 @@ gsk_render_node_deserialize_from_bytes (GBytes *bytes,
}
typedef struct
{
int indentation_level;
@@ -2759,10 +2735,6 @@ printer_init_duplicates_for_node (Printer *printer,
}
break;
case GSK_SUBSURFACE_NODE:
printer_init_duplicates_for_node (printer, gsk_subsurface_node_get_child (node));
break;
default:
case GSK_NOT_A_RENDER_NODE:
g_assert_not_reached ();
@@ -4070,14 +4042,6 @@ render_node_print (Printer *p,
}
break;
case GSK_SUBSURFACE_NODE:
{
start_node (p, "subsurface", node_name);
append_node_param (p, "child", gsk_subsurface_node_get_child (node));
}
break;
default:
g_error ("Unhandled node: %s", g_type_name_from_instance ((GTypeInstance *) node));
break;
+5 -16
View File
@@ -1,7 +1,6 @@
#pragma once
#include "gskrendernode.h"
#include "gskoffloadprivate.h"
#include <cairo.h>
#include "gdk/gdkmemoryformatprivate.h"
@@ -15,7 +14,7 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass;
* We don't add an "n-types" value to avoid having to handle
* it in every single switch.
*/
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_SUBSURFACE_NODE + 1)
#define GSK_RENDER_NODE_TYPE_N_TYPES (GSK_STROKE_NODE + 1)
extern GType gsk_render_node_types[];
@@ -37,12 +36,6 @@ struct _GskRenderNode
guint offscreen_for_opacity : 1;
};
typedef struct
{
cairo_region_t *region;
GskOffload *offload;
} GskDiffData;
struct _GskRenderNodeClass
{
GTypeClass parent_class;
@@ -56,7 +49,7 @@ struct _GskRenderNodeClass
const GskRenderNode *node2);
void (* diff) (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data);
cairo_region_t *region);
};
void gsk_render_node_init_types (void);
@@ -73,17 +66,13 @@ gboolean gsk_render_node_can_diff (const GskRenderNode
const GskRenderNode *node2) G_GNUC_PURE;
void gsk_render_node_diff (GskRenderNode *node1,
GskRenderNode *node2,
cairo_region_t *region,
GskOffload *offload);
void gsk_render_node_data_diff (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data);
cairo_region_t *region);
void gsk_render_node_diff_impossible (GskRenderNode *node1,
GskRenderNode *node2,
GskDiffData *data);
cairo_region_t *region);
void gsk_container_node_diff_with (GskRenderNode *container,
GskRenderNode *other,
GskDiffData *data);
cairo_region_t *region);
bool gsk_border_node_get_uniform (const GskRenderNode *self);
bool gsk_border_node_get_uniform_color (const GskRenderNode *self);
-1
View File
@@ -27,7 +27,6 @@ gsk_public_sources = files([
'gskcairorenderer.c',
'gskdiff.c',
'gskglshader.c',
'gskoffload.c',
'gskpath.c',
'gskpathbuilder.c',
'gskpathmeasure.c',
+2
View File
@@ -1455,6 +1455,7 @@ gtk_at_spi_context_realize (GtkATContext *context)
if (self->connection == NULL)
return;
#ifdef G_ENABLE_DEBUG
if (GTK_DEBUG_CHECK (A11Y))
{
GtkAccessible *accessible = gtk_at_context_get_accessible (context);
@@ -1466,6 +1467,7 @@ gtk_at_spi_context_realize (GtkATContext *context)
role_name);
g_free (role_name);
}
#endif
gtk_at_spi_root_queue_register (self->root, self, register_object);
}
+1
View File
@@ -186,6 +186,7 @@ gtk_css_parser_resolve_url (GtkCssParser *self,
g_free (scheme);
return file;
}
g_free (scheme);
if (self->directory == NULL)
return NULL;
-1
View File
@@ -970,7 +970,6 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer *tokenizer,
{
gtk_css_tokenizer_read_bad_url (tokenizer, token);
gtk_css_tokenizer_parse_error (error, "Whitespace only allowed at start and end of url");
g_string_free (url, TRUE);
return FALSE;
}
}

Some files were not shown because too many files have changed in this diff Show More