Compare commits

..

10 Commits

Author SHA1 Message Date
Matthias Clasen 79835c7e57 wayland: Try again to fix the version check 2023-10-09 13:27:27 -04:00
Matthias Clasen 1740aeab40 gsk: Don't pass DRM_FORMAT_MOD_INVALID to egl
Pascal pointed out that this may not work with
some drivers (specifically, Raspberry Pi was
mentioned).
2023-10-09 09:25:46 -04:00
Matthias Clasen 589a662052 wayland: Only use version 4 of the dmabuf protocol 2023-10-09 08:24:08 -04:00
Matthias Clasen 349e0156b3 gsk: Try harder to import 'simple' formats
Even RGBA formats can have multiple planes
(depending on the modifier), so pass all the
planes to EGL when importing them.
2023-10-09 08:23:12 -04:00
Matthias Clasen a9fb224b8d dmabuf: Reshuffle APIs a bit
Give the builder an n-planes property, and
add private api to the texture to access
the per-plane properties as arrays.
2023-10-09 08:22:14 -04:00
Matthias Clasen e2162c13ee 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-08 11:07:24 -04:00
Matthias Clasen 17103d765f gsk: Support dmabuf textures
Support dmabuf textures in the GL renderer.

This copies the approach taken by mutter for
yuv dmabuf conversion.
2023-10-08 11:07:24 -04:00
Matthias Clasen c1bf9e3320 display: Limit dmabuf formats
We only want to return formats that we can actually
support in GdkDmabufTexture, which requires that we
are able to download them.
2023-10-08 11:07:24 -04:00
Matthias Clasen 6f913eac15 Add GdkDmabufTexture
Add a new GdkTexture subclass for supporting
dmabuf buffers on Linux. Also add a builder
called GdkDmabufTextureBuilder.

For downloading these textures, we rely on GSK
being able to render them to a GL texture. The
support for that will be added in the following
commits.
2023-10-08 11:07:24 -04:00
Matthias Clasen f9b0b55361 display: Get supported dmabuf formats
These are the dmabuf formats that we can import
into a GL context as an EGLImage.
2023-10-08 10:51:31 -04:00
108 changed files with 2468 additions and 6271 deletions
+5 -12
View File
@@ -217,32 +217,25 @@ macos-x86_64:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
EXTRA_MESON_FLAGS: "-Dgobject-introspection:werror=false"
before_script:
# Not using ccache on purpose as it accelerates the build so much that it
# can trigger race conditions in the gobject-introspection subproject.
- bash .gitlab-ci/show-info-osx.sh
- /opt/macports/bin/python3.10 -m venv .venv
- python3 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/pkg-config/bin/pkg-config .venv/bin
- ln -s /opt/bison/bin/bison .venv/bin
- ln -s /opt/ccache/ccache .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install /Users/Shared/build/pkgs/PyGObject-3.44.0-cp310-cp310-macosx_10_13_x86_64.whl
/Users/Shared/build/pkgs/pycairo-1.23.0-cp310-cp310-macosx_10_13_x86_64.whl
script:
- meson setup
${COMMON_MESON_FLAGS}
${EXTRA_MESON_FLAGS}
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false
-Dbroadway-backend=true
-Dmacos-backend=true
-Dmedia-gstreamer=disabled
-Dintrospection=enabled
-Dintrospection=disabled
-Dcpp_std=c++11
-Dpixman:tests=disabled
-Dlibjpeg-turbo:simd=disabled
+1 -29
View File
@@ -1,34 +1,6 @@
Overview of Changes in 4.13.3, xx-xx-xxxx
Overview of Changes in 4.13.2, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.2, 22-10-2023
=========================================
* GtkPrintdialog:
- New async-style api to replace GtkPrintOperation
* GtkEmojiChooser:
- Add more languages: Bengali, Hindi, Japanese, Finnish,
Thai and Norwegian bokmål
* Accessibility:
- Fix some utf8 handling issues
* GDK:
- Add support for dmabuf textures, with GdkDmabufTextureBuilder
- Add a few more supported memory formats for textures
* GSK:
- Add a fast-path for masking color
- Add support for importing dmabuf textures
- Handle GLES better by using some extensions
* Translation updates:
Catalan
Russian
Turkish
Overview of Changes in 4.13.1, 28-09-2023
=========================================
+2 -4
View File
@@ -34,7 +34,7 @@ transition (GtkWidget *widget,
{
DemoWidget *self = DEMO_WIDGET (widget);
DemoLayout *demo_layout = DEMO_LAYOUT (gtk_widget_get_layout_manager (widget));
gint64 now = gdk_frame_clock_get_frame_time (frame_clock);
gint64 now = g_get_monotonic_time ();
gtk_widget_queue_allocate (widget);
@@ -66,13 +66,11 @@ clicked (GtkGestureClick *gesture,
gpointer data)
{
DemoWidget *self = data;
GdkFrameClock *frame_clock;
if (self->tick_id != 0)
return;
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
self->start_time = gdk_frame_clock_get_frame_time (frame_clock);
self->start_time = g_get_monotonic_time ();
self->tick_id = gtk_widget_add_tick_callback (GTK_WIDGET (self), transition, NULL, NULL);
}
+13 -28
View File
@@ -170,41 +170,35 @@ This variable can be set to a list of debug options, which cause GDK to
print out different types of debugging information. Some of these options
are only available when GTK has been configured with `-Ddebug=true`.
`misc`
: Miscellaneous information
`events`
: Information about events
`dnd`
: Information about drag-and-drop
`input`
: Information about input (mostly Windows)
`cursor`
: Information about cursor objects (only win32)
`eventloop`
: Information about event loop operation (mostly macOS)
`misc`
: Miscellaneous information
`frames`
: Information about the frame clock
`settings`
: Information about xsettings
`opengl`
: Information about OpenGL
`vulkan`
: Information about Vulkan
`selection`
: Information about selections
`clipboard`
: Information about clipboards
`dmabuf`
: Information about dmabuf handling (Linux-only)
`dnd`
: Information about drag-and-drop
`opengl`
: Information about OpenGL
`vulkan`
: Information about Vulkan
A number of options affect behavior instead of logging:
@@ -223,9 +217,6 @@ A number of options affect behavior instead of logging:
`gl-fractional`
: Enable fractional scaling for OpenGL. This is experimental
`gl-debug`
: Insert debugging information in OpenGL
`gl-legacy`
: Use a legacy OpenGL context
@@ -253,12 +244,6 @@ A number of options affect behavior instead of logging:
`high-depth`
: Use high bit depth rendering if possible
`no-vsync`
: Repaint instantly (uses 100% CPU with animations)
`dmabuf-disable`
: Disable dmabuf support
The special value `all` can be used to turn on all debug options. The special
value `help` can be used to obtain a list of all supported debug options.
-3
View File
@@ -117,8 +117,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "vulkan", GDK_DEBUG_VULKAN, "Information about Vulkan" },
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "dmabuf", GDK_DEBUG_DMABUF, "Information about dmabuf buffers" },
{ "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 },
@@ -135,7 +133,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "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 },
};
-1
View File
@@ -42,7 +42,6 @@
#include <gdk/gdkdevicetool.h>
#include <gdk/gdkdisplay.h>
#include <gdk/gdkdisplaymanager.h>
#include <gdk/gdkdmabufformats.h>
#include <gdk/gdkdmabuftexture.h>
#include <gdk/gdkdmabuftexturebuilder.h>
#include <gdk/gdkdrag.h>
-4
View File
@@ -215,11 +215,7 @@ gdk_array(splice) (GdkArray *self,
gsize pos,
gsize removed,
gboolean stolen,
#ifdef GDK_ARRAY_BY_VALUE
const _T_ *additions,
#else
_T_ *additions,
#endif
gsize added)
{
gsize size;
+16 -19
View File
@@ -36,26 +36,23 @@ typedef enum {
GDK_DEBUG_VULKAN = 1 << 8,
GDK_DEBUG_SELECTION = 1 << 9,
GDK_DEBUG_CLIPBOARD = 1 << 10,
GDK_DEBUG_DMABUF = 1 << 11,
/* flags below are influencing behavior */
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,
GDK_DEBUG_NOGRABS = 1 << 11,
GDK_DEBUG_PORTALS = 1 << 12,
GDK_DEBUG_NO_PORTALS = 1 << 13,
GDK_DEBUG_GL_DISABLE = 1 << 14,
GDK_DEBUG_GL_FRACTIONAL = 1 << 15,
GDK_DEBUG_GL_LEGACY = 1 << 16,
GDK_DEBUG_GL_GLES = 1 << 17,
GDK_DEBUG_GL_DEBUG = 1 << 18,
GDK_DEBUG_GL_EGL = 1 << 19,
GDK_DEBUG_GL_GLX = 1 << 20,
GDK_DEBUG_GL_WGL = 1 << 21,
GDK_DEBUG_VULKAN_DISABLE = 1 << 22,
GDK_DEBUG_VULKAN_VALIDATE = 1 << 23,
GDK_DEBUG_DEFAULT_SETTINGS= 1 << 24,
GDK_DEBUG_HIGH_DEPTH = 1 << 25,
GDK_DEBUG_NO_VSYNC = 1 << 26,
} GdkDebugFlags;
extern guint _gdk_debug_flags;
+89 -91
View File
@@ -31,15 +31,13 @@
#include "gdkclipboardprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdisplaymanagerprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkeventsprivate.h"
#include "gdkframeclockidleprivate.h"
#include "gdkglcontextprivate.h"
#include "gdkmonitorprivate.h"
#include "gdkrectangle.h"
#include "gdkvulkancontext.h"
#include "gdkdmabuftextureprivate.h"
#ifdef HAVE_EGL
#include <epoxy/egl.h>
@@ -72,7 +70,6 @@ enum
PROP_COMPOSITED,
PROP_RGBA,
PROP_INPUT_SHAPES,
PROP_DMABUF_FORMATS,
LAST_PROP
};
@@ -142,10 +139,6 @@ gdk_display_get_property (GObject *object,
g_value_set_boolean (value, gdk_display_supports_input_shapes (display));
break;
case PROP_DMABUF_FORMATS:
g_value_set_boxed (value, gdk_display_get_dmabuf_formats (display));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -247,11 +240,6 @@ gdk_display_class_init (GdkDisplayClass *class)
TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
props[PROP_DMABUF_FORMATS] =
g_param_spec_boxed ("dmabuf-formats", NULL, NULL,
GDK_TYPE_DMABUF_FORMATS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, LAST_PROP, props);
/**
@@ -391,9 +379,6 @@ gdk_display_dispose (GObject *object)
g_queue_clear (&display->queued_events);
g_clear_object (&display->egl_gsk_renderer);
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
g_clear_object (&priv->gl_context);
#ifdef HAVE_EGL
g_clear_pointer (&priv->egl_display, eglTerminate);
@@ -420,7 +405,7 @@ gdk_display_finalize (GObject *object)
g_list_free_full (display->seats, g_object_unref);
g_clear_pointer (&display->dmabuf_formats, gdk_dmabuf_formats_unref);
g_free (display->egl_dmabuf_formats);
G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object);
}
@@ -1277,6 +1262,68 @@ gdk_display_create_vulkan_context (GdkDisplay *self,
NULL);
}
/* To support a drm format, we must be able to import it into GL
* using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK).
*/
static void
init_dmabuf_formats (GdkDisplay *self)
{
GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
if (priv->egl_display != EGL_NO_DISPLAY)
{
int num_formats;
int *formats;
GArray *array;
eglQueryDmaBufFormatsEXT (priv->egl_display, 0, NULL, &num_formats);
formats = g_new (int, num_formats);
eglQueryDmaBufFormatsEXT (priv->egl_display, num_formats, formats, &num_formats);
array = g_array_new (FALSE, FALSE, sizeof (GdkDmabufFormat));
for (int i = 0; i < num_formats; i++)
{
int num_modifiers;
uint64_t *modifiers;
unsigned int *external_only;
if (!gdk_dmabuf_texture_may_support ((unsigned int)formats[i]))
continue;
eglQueryDmaBufModifiersEXT (priv->egl_display, formats[i], 0, NULL, NULL, &num_modifiers);
modifiers = g_new (uint64_t, num_modifiers);
external_only = g_new (unsigned int, num_modifiers);
eglQueryDmaBufModifiersEXT (priv->egl_display, formats[i], num_modifiers, modifiers, external_only, &num_modifiers);
if (num_modifiers == 0)
g_array_append_val (array, ((GdkDmabufFormat){ formats[i], 0 }));
else
{
for (int j = 0; j < num_modifiers; j++)
g_array_append_val (array, ((GdkDmabufFormat){ formats[i], modifiers[j] }));
}
g_free (modifiers);
}
g_free (formats);
self->egl_dmabuf_n_formats = array->len;
self->egl_dmabuf_formats = (GdkDmabufFormat *) g_array_free (array, FALSE);
}
GDK_DEBUG (MISC, "Supported EGL dmabuf formats: (%lu)", self->egl_dmabuf_n_formats);
for (gsize i = 0; i < self->egl_dmabuf_n_formats; i++)
{
uint32_t f = self->egl_dmabuf_formats[i].fourcc;
uint64_t m = self->egl_dmabuf_formats[i].modifier;
GDK_DEBUG (MISC, " %c%c%c%c:%#lx", f & 0xff, (f >> 8) & 0xff, (f >> 16) & 0xff, (f >> 24) & 0xff, m);
}
}
static void
gdk_display_init_gl (GdkDisplay *self)
{
@@ -1318,6 +1365,10 @@ gdk_display_init_gl (GdkDisplay *self)
gdk_gl_backend_use (GDK_GL_CONTEXT_GET_CLASS (context)->backend_type);
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
gdk_gl_context_make_current (context);
init_dmabuf_formats (self);
}
/**
@@ -1773,10 +1824,6 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_pixel_format_float");
self->have_egl_dma_buf_import =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_image_dma_buf_import_modifiers");
self->have_egl_dma_buf_export =
epoxy_has_egl_extension (priv->egl_display, "EGL_MESA_image_dma_buf_export");
if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self,
@@ -1846,90 +1893,41 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif
}
#ifdef HAVE_DMABUF
static void
gdk_display_add_dmabuf_downloader (GdkDisplay *display,
const GdkDmabufDownloader *downloader,
GdkDmabufFormatsBuilder *builder)
{
gsize i;
if (!downloader->add_formats (downloader, display, builder))
return;
/* dmabuf_downloaders is NULL-terminated */
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
{
if (display->dmabuf_downloaders[i] == NULL)
break;
}
g_assert (i < G_N_ELEMENTS (display->dmabuf_downloaders));
display->dmabuf_downloaders[i] = downloader;
}
#endif
/* To support a drm format, we must be able to import it into GL
* using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK).
/**
* GdkDmabufFormat:
* @fourcc: the format code
* @modifiers: the format modifier
*
* The `GdkDmabufFormat` struct represents a dma-buf format
* as defined in the `drm_fourcc.h` header.
*
* Since: 4.14
*/
void
gdk_display_init_dmabuf (GdkDisplay *self)
{
GdkDmabufFormatsBuilder *builder;
if (self->dmabuf_formats != NULL)
return;
GDK_DISPLAY_DEBUG (self, DMABUF,
"Beginning initialization of dmabuf support");
builder = gdk_dmabuf_formats_builder_new ();
#ifdef HAVE_DMABUF
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
{
gdk_display_prepare_gl (self, NULL);
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder);
#ifdef HAVE_EGL
if (gdk_display_prepare_gl (self, NULL))
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (), builder);
#endif
}
#endif
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder);
GDK_DISPLAY_DEBUG (self, DMABUF,
"Initialized support for %zu dmabuf formats",
gdk_dmabuf_formats_get_n_formats (self->dmabuf_formats));
}
/**
* gdk_display_get_dmabuf_formats:
* @display: a `GdkDisplay`
* @n_formats: return location for the number of formats
*
* Returns the dma-buf formats that are supported on this display.
*
* GTK may use OpenGL or Vulkan to support some formats.
* Calling this function will then initialize them if they aren't yet.
* Note that GTK uses EGL to convert some formats, so the list
* of supported formats depends on the GL API that is used on
* the display.
*
* The formats returned by this function can be used for negotiating
* buffer formats with producers such as v4l, pipewire or GStreamer.
*
* Returns: (transfer none): a `GdkDmabufFormats` object
* Returns: (transfer none): an array of `GdkDmabufFormat` structs.
* The length of the array is returned in @n_formats
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display)
const GdkDmabufFormat *
gdk_display_get_dmabuf_formats (GdkDisplay *display,
gsize *n_formats)
{
gdk_display_init_dmabuf (display);
gdk_display_prepare_gl (display, NULL);
return display->dmabuf_formats;
*n_formats = display->egl_dmabuf_n_formats;
return display->egl_dmabuf_formats;
}
GdkDebugFlags
+9 -2
View File
@@ -134,9 +134,16 @@ gboolean gdk_display_get_setting (GdkDisplay *display,
const char *name,
GValue *value);
typedef struct
{
uint32_t fourcc;
uint64_t modifier;
} GdkDmabufFormat;
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display);
const GdkDmabufFormat *
gdk_display_get_dmabuf_formats (GdkDisplay *display,
gsize *n_formats);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDisplay, g_object_unref)
+2 -11
View File
@@ -25,7 +25,6 @@
#include "gdksurfaceprivate.h"
#include "gdkkeysprivate.h"
#include "gdkdeviceprivate.h"
#include "gdkdmabufprivate.h"
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
@@ -114,15 +113,9 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 1;
guint have_egl_dma_buf_import : 1;
guint have_egl_dma_buf_export : 1;
GdkDmabufFormats *dmabuf_formats;
const GdkDmabufDownloader *dmabuf_downloaders[4];
/* Cached data the EGL dmabuf downloader */
gpointer egl_gsk_renderer;
GdkDmabufFormats *egl_external_formats;
GdkDmabufFormat *egl_dmabuf_formats;
gsize egl_dmabuf_n_formats;
};
struct _GdkDisplayClass
@@ -217,8 +210,6 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_events (GdkDisplay *display);
void gdk_display_init_dmabuf (GdkDisplay *self);
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GError **error);
-745
View File
@@ -1,745 +0,0 @@
/* gdkdmabuf.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdkdmabufprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#ifdef HAVE_DMABUF
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#include <drm_fourcc.h>
#include <epoxy/egl.h>
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
struct _GdkDrmFormatInfo
{
guint32 fourcc;
GdkMemoryFormat premultiplied_memory_format;
GdkMemoryFormat unpremultiplied_memory_format;
void (* download) (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES]);
};
static void
download_memcpy (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
const guchar *src_data;
gsize src_stride;
guint bpp;
bpp = gdk_memory_format_bytes_per_pixel (dst_format);
src_stride = dmabuf->planes[0].stride;
src_data = src_datas[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + (height - 1) * dst_stride + width * bpp);
if (dst_stride == src_stride)
memcpy (dst_data, src_data, (height - 1) * dst_stride + width * bpp);
else
{
gsize i;
for (i = 0; i < height; i++)
memcpy (dst_data + i * dst_stride, src_data + i * src_stride, width * bpp);
}
}
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
//static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static void
download_nv12 (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
const guchar *y_data, *uv_data;
gsize x, y, y_stride, uv_stride;
gsize U, V, X_SUB, Y_SUB;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_NV12:
U = 0; V = 1; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_NV21:
U = 1; V = 0; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_NV16:
U = 0; V = 1; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_NV61:
U = 1; V = 0; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_NV24:
U = 0; V = 1; X_SUB = 1; Y_SUB = 1;
break;
case DRM_FORMAT_NV42:
U = 1; V = 0; X_SUB = 1; Y_SUB = 1;
break;
default:
g_assert_not_reached ();
return;
}
y_stride = dmabuf->planes[0].stride;
y_data = src_data[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
uv_stride = dmabuf->planes[1].stride;
uv_data = src_data[1] + dmabuf->planes[1].offset;
g_return_if_fail (sizes[1] >= dmabuf->planes[1].offset + (height + Y_SUB - 1) / Y_SUB * uv_stride);
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_wide, uv_data[x / X_SUB * 2 + U], uv_data[x / X_SUB * 2 + V], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
uv_data += uv_stride;
}
}
static void
download_yuv_3 (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
const guchar *y_data, *u_data, *v_data;
gsize x, y, y_stride, u_stride, v_stride;
gsize U, V, X_SUB, Y_SUB;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_YUV410:
U = 1; V = 2; X_SUB = 4; Y_SUB = 4;
break;
case DRM_FORMAT_YVU410:
U = 2; V = 1; X_SUB = 4; Y_SUB = 4;
break;
case DRM_FORMAT_YUV411:
U = 1; V = 2; X_SUB = 4; Y_SUB = 1;
break;
case DRM_FORMAT_YVU411:
U = 2; V = 1; X_SUB = 4; Y_SUB = 1;
break;
case DRM_FORMAT_YUV420:
U = 1; V = 2; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_YVU420:
U = 2; V = 1; X_SUB = 2; Y_SUB = 2;
break;
case DRM_FORMAT_YUV422:
U = 1; V = 2; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_YVU422:
U = 2; V = 1; X_SUB = 2; Y_SUB = 1;
break;
case DRM_FORMAT_YUV444:
U = 1; V = 2; X_SUB = 1; Y_SUB = 1;
break;
case DRM_FORMAT_YVU444:
U = 2; V = 1; X_SUB = 1; Y_SUB = 1;
break;
default:
g_assert_not_reached ();
return;
}
y_stride = dmabuf->planes[0].stride;
y_data = src_data[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * y_stride);
u_stride = dmabuf->planes[U].stride;
u_data = src_data[U] + dmabuf->planes[U].offset;
g_return_if_fail (sizes[U] >= dmabuf->planes[U].offset + (height + Y_SUB - 1) / Y_SUB * u_stride);
v_stride = dmabuf->planes[V].stride;
v_data = src_data[V] + dmabuf->planes[V].offset;
g_return_if_fail (sizes[V] >= dmabuf->planes[V].offset + (height + Y_SUB - 1) / Y_SUB * v_stride);
for (y = 0; y < height; y += Y_SUB)
{
for (x = 0; x < width; x += X_SUB)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_wide, u_data[x / X_SUB], v_data[x / X_SUB], &r, &g, &b);
for (ys = 0; ys < Y_SUB && y + ys < height; ys++)
for (xs = 0; xs < X_SUB && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += Y_SUB * dst_stride;
y_data += Y_SUB * y_stride;
u_data += u_stride;
v_data += v_stride;
}
}
static void
download_yuyv (guchar *dst_data,
gsize dst_stride,
GdkMemoryFormat dst_format,
gsize width,
gsize height,
const GdkDmabuf *dmabuf,
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
gsize sizes[GDK_DMABUF_MAX_PLANES])
{
const guchar *src_data;
gsize x, y, src_stride;
gsize Y1, Y2, U, V;
switch (dmabuf->fourcc)
{
case DRM_FORMAT_YUYV:
Y1 = 0; U = 1; Y2 = 2; V = 3;
break;
case DRM_FORMAT_YVYU:
Y1 = 0; V = 1; Y2 = 2; U = 3;
break;
case DRM_FORMAT_UYVY:
U = 0; Y1 = 1; V = 2; Y2 = 3;
break;
case DRM_FORMAT_VYUY:
V = 0; Y1 = 1; U = 2; Y2 = 3;
break;
default:
g_assert_not_reached ();
return;
}
src_stride = dmabuf->planes[0].stride;
src_data = src_datas[0] + dmabuf->planes[0].offset;
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + height * src_stride);
for (y = 0; y < height; y ++)
{
for (x = 0; x < width; x += 2)
{
int r, g, b;
get_uv_values (&itu601_wide, src_data[2 * x + U], src_data[2 * x + V], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + Y1], r, g, b);
if (x + 1 < width)
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + Y2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
}
}
static const GdkDrmFormatInfo supported_formats[] = {
{ DRM_FORMAT_BGRA8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8, download_memcpy },
{ DRM_FORMAT_ABGR8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8, download_memcpy },
{ DRM_FORMAT_ARGB8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8, download_memcpy },
{ DRM_FORMAT_RGBA8888, GDK_MEMORY_A8B8G8R8_PREMULTIPLIED, GDK_MEMORY_A8B8G8R8, download_memcpy },
{ DRM_FORMAT_BGRX8888, GDK_MEMORY_X8R8G8B8, GDK_MEMORY_X8R8G8B8, download_memcpy },
{ DRM_FORMAT_XBGR8888, GDK_MEMORY_R8G8B8X8, GDK_MEMORY_R8G8B8X8, download_memcpy },
{ DRM_FORMAT_XRGB8888, GDK_MEMORY_B8G8R8X8, GDK_MEMORY_B8G8R8X8, download_memcpy },
{ DRM_FORMAT_RGBX8888, GDK_MEMORY_X8B8G8R8, GDK_MEMORY_X8B8G8R8, download_memcpy },
{ DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT, download_memcpy },
{ DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_memcpy },
{ DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8, download_memcpy },
/* YUV formats */
{ DRM_FORMAT_NV12, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_NV21, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_NV16, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_NV61, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_NV24, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_NV42, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_nv12 },
{ DRM_FORMAT_YUYV, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
{ DRM_FORMAT_YVYU, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
{ DRM_FORMAT_VYUY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
{ DRM_FORMAT_UYVY, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuyv },
{ DRM_FORMAT_YUV410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YVU410, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YUV411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YVU411, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YUV420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YVU420, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YUV422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YVU422, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YUV444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
{ DRM_FORMAT_YVU444, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8, download_yuv_3 },
};
static const GdkDrmFormatInfo *
get_drm_format_info (guint32 fourcc)
{
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (supported_formats[i].fourcc == fourcc)
return &supported_formats[i];
}
return NULL;
}
static gboolean
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{
gsize i;
for (i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
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,
DRM_FORMAT_MOD_LINEAR);
}
return TRUE;
}
static gboolean
gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error)
{
const GdkDrmFormatInfo *info;
info = get_drm_format_info (dmabuf->fourcc);
if (!info)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format %.4s",
(char *) &dmabuf->fourcc);
return FALSE;
}
if (dmabuf->modifier != DRM_FORMAT_MOD_LINEAR)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf modifier %#lx (only linear buffers are supported)",
dmabuf->modifier);
return FALSE;
}
*out_format = premultiplied ? info->premultiplied_memory_format
: info->unpremultiplied_memory_format;
return TRUE;
}
static void
gdk_dmabuf_direct_downloader_do_download (GdkTexture *texture,
guchar *data,
gsize stride)
{
const GdkDrmFormatInfo *info;
const GdkDmabuf *dmabuf;
const guchar *src_data[GDK_DMABUF_MAX_PLANES];
gsize sizes[GDK_DMABUF_MAX_PLANES];
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
gsize i, j;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
info = get_drm_format_info (dmabuf->fourcc);
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++)
{
for (j = 0; j < i; j++)
{
if (dmabuf->planes[i].fd == dmabuf->planes[j].fd)
break;
}
if (j < i)
{
src_data[i] = src_data[j];
sizes[i] = sizes[j];
continue;
}
sizes[i] = lseek (dmabuf->planes[i].fd, 0, SEEK_END);
if (sizes[i] == (off_t) -1)
{
g_warning ("Failed to seek dmabuf: %s", g_strerror (errno));
goto out;
}
/* be a good citizen and seek back to the start, as the dos recommend */
lseek (dmabuf->planes[i].fd, 0, SEEK_SET);
if (ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
src_data[i] = mmap (NULL, sizes[i], PROT_READ, MAP_SHARED, dmabuf->planes[i].fd, dmabuf->planes[i].offset);
if (src_data[i] == NULL)
{
g_warning ("Failed to mmap dmabuf: %s", g_strerror (errno));
goto out;
}
needs_unmap[i] = TRUE;
}
info->download (data,
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
out:
for (i = 0; i < dmabuf->n_planes; i++)
{
if (!needs_unmap[i])
continue;
munmap ((void *)src_data[i], sizes[i]);
if (ioctl (dmabuf->planes[i].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dmabuf: %s", g_strerror (errno));
}
}
static void
gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
if (format == src_format)
gdk_dmabuf_direct_downloader_do_download (texture, data, stride);
else
{
unsigned int width, height;
guchar *src_data;
gsize src_stride;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
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 (texture, src_data, src_stride);
gdk_memory_convert (data, stride, format,
src_data, src_stride, src_format,
width, height);
g_free (src_data);
}
}
const GdkDmabufDownloader *
gdk_dmabuf_get_direct_downloader (void)
{
static const GdkDmabufDownloader downloader = {
"mmap",
gdk_dmabuf_direct_downloader_add_formats,
gdk_dmabuf_direct_downloader_supports,
gdk_dmabuf_direct_downloader_download,
};
return &downloader;
}
/*
* Tries to sanitize the dmabuf to conform to the values expected
* by Vulkan/EGL which should also be the values expected by
* Wayland compositors
*
* We put these sanitized values into the GdkDmabufTexture, by
* sanitizing the input from GdkDmabufTextureBuilder, which are
* controlled by the callers.
*
* Things we do here:
*
* 1. Disallow any dmabuf format that we do not know.
*
* 1. Reject the INVALID modifier, accept the LINEAR one.
*
* 2. Ignore all other modifiers.
*
* 3. Try and fix various inconsistencies between V4L and Mesa, like NV12.
*
* *** WARNING ***
*
* This function is not absolutely perfect, you do not have a
* perfect dmabuf afterwards.
*
* In particular, it doesn't check sizes.
*
* *** WARNING ***
*/
gboolean
gdk_dmabuf_sanitize (GdkDmabuf *dest,
gsize width,
gsize height,
const GdkDmabuf *src,
GError **error)
{
const GdkDrmFormatInfo *info;
if (src->n_planes > GDK_DMABUF_MAX_PLANES)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"GTK only support dmabufs with %u planes, not %u",
GDK_DMABUF_MAX_PLANES, src->n_planes);
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)
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format %.4s",
(char *) &src->fourcc);
return FALSE;
}
*dest = *src;
if (src->modifier)
return TRUE;
switch (dest->fourcc)
{
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
if (dest->n_planes == 1)
{
dest->n_planes = 2;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = dest->planes[0].stride;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
}
break;
case DRM_FORMAT_NV24:
case DRM_FORMAT_NV42:
if (dest->n_planes == 1)
{
dest->n_planes = 2;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = dest->planes[0].stride * 2;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
}
break;
case DRM_FORMAT_YUV410:
case DRM_FORMAT_YVU410:
if (dest->n_planes == 1)
{
dest->n_planes = 3;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
dest->planes[2].fd = dest->planes[1].fd;
dest->planes[2].stride = dest->planes[1].stride;
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 3) / 4);
}
break;
case DRM_FORMAT_YUV411:
case DRM_FORMAT_YVU411:
if (dest->n_planes == 1)
{
dest->n_planes = 3;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = (dest->planes[0].stride + 3) / 4;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
dest->planes[2].fd = dest->planes[1].fd;
dest->planes[2].stride = dest->planes[1].stride;
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
}
break;
case DRM_FORMAT_YUV420:
case DRM_FORMAT_YVU420:
if (dest->n_planes == 1)
{
dest->n_planes = 3;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
dest->planes[2].fd = dest->planes[1].fd;
dest->planes[2].stride = dest->planes[1].stride;
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * ((height + 1) / 2);
}
break;
case DRM_FORMAT_YUV422:
case DRM_FORMAT_YVU422:
if (dest->n_planes == 1)
{
dest->n_planes = 3;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = (dest->planes[0].stride + 1) / 2;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
dest->planes[2].fd = dest->planes[1].fd;
dest->planes[2].stride = dest->planes[1].stride;
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
}
break;
case DRM_FORMAT_YUV444:
case DRM_FORMAT_YVU444:
if (dest->n_planes == 1)
{
dest->n_planes = 3;
dest->planes[1].fd = dest->planes[0].fd;
dest->planes[1].stride = dest->planes[0].stride;
dest->planes[1].offset = dest->planes[0].offset + dest->planes[0].stride * height;
dest->planes[2].fd = dest->planes[1].fd;
dest->planes[2].stride = dest->planes[1].stride;
dest->planes[2].offset = dest->planes[1].offset + dest->planes[1].stride * height;
}
break;
default:
break;
}
return TRUE;
}
/*
* gdk_dmabuf_is_disjoint:
* @dmabuf: a sanitized GdkDmabuf
*
* A dmabuf is considered disjoint if it uses more than
* 1 file descriptor.
*
* Returns: %TRUE if the dmabuf is disjoint
**/
gboolean
gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf)
{
unsigned i;
for (i = 1; i < dmabuf->n_planes; i++)
{
if (dmabuf->planes[0].fd != dmabuf->planes[i].fd)
return TRUE;
}
return FALSE;
}
#endif /* HAVE_DMABUF */
-413
View File
@@ -1,413 +0,0 @@
/* gdkdmabufegl.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
#include "gdkdmabufprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkglcontextprivate.h"
#include "gdktexturedownloader.h"
#include <graphene.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#include <drm_fourcc.h>
#include <epoxy/egl.h>
/* A dmabuf downloader implementation that downloads buffers via
* gsk_renderer_render_texture + GL texture download.
*/
static gboolean
gdk_dmabuf_egl_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{
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_external_formats == NULL);
external = gdk_dmabuf_formats_builder_new ();
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_external_formats = gdk_dmabuf_formats_builder_free_to_formats (external);
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,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error)
{
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)
{
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,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
(char *) &dmabuf->fourcc, dmabuf->modifier);
return FALSE;
}
/* Hack. We don't include gsk/gsk.h here to avoid a build order problem
* with the generated header gskenumtypes.h, so we need to hack around
* a bit to access the gsk api we need.
*/
typedef gpointer GskRenderer;
extern GskRenderer * gsk_gl_renderer_new (void);
extern gboolean gsk_renderer_realize (GskRenderer *renderer,
GdkSurface *surface,
GError **error);
extern GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
GdkTexture *texture);
typedef void (* InvokeFunc) (gpointer data);
typedef struct _InvokeData
{
volatile int spinlock;
InvokeFunc func;
gpointer data;
} InvokeData;
static gboolean
gdk_dmabuf_egl_downloader_invoke_callback (gpointer data)
{
InvokeData *invoke = data;
GdkGLContext *previous;
previous = gdk_gl_context_get_current ();
invoke->func (invoke->data);
if (previous)
gdk_gl_context_make_current (previous);
else
gdk_gl_context_clear_current ();
g_atomic_int_set (&invoke->spinlock, 1);
return FALSE;
}
/* Run func in the main thread, taking care not to disturb
* the current GL context of the caller.
*/
static void
gdk_dmabuf_egl_downloader_run (InvokeFunc func,
gpointer data)
{
InvokeData invoke = { 0, func, data };
g_main_context_invoke (NULL, gdk_dmabuf_egl_downloader_invoke_callback, &invoke);
while (g_atomic_int_get (&invoke.spinlock) == 0) ;
}
typedef struct _Download Download;
struct _Download
{
GdkDmabufTexture *texture;
GdkMemoryFormat format;
guchar *data;
gsize stride;
};
static GskRenderer *
get_gsk_renderer (GdkDisplay *display)
{
if (!display->egl_gsk_renderer)
{
GskRenderer *renderer;
GError *error = NULL;
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, &error))
{
g_warning ("Failed to realize GL renderer: %s", error->message);
g_error_free (error);
g_object_unref (renderer);
return NULL;
}
display->egl_gsk_renderer = renderer;
}
return display->egl_gsk_renderer;
}
static void
gdk_dmabuf_egl_downloader_do_download (gpointer data)
{
Download *download = data;
GdkDisplay *display;
GskRenderer *renderer;
GdkTexture *native;
GdkTextureDownloader *downloader;
display = gdk_dmabuf_texture_get_display (download->texture);
renderer = get_gsk_renderer (display);
native = gsk_renderer_convert_texture (renderer, GDK_TEXTURE (download->texture));
downloader = gdk_texture_downloader_new (native);
gdk_texture_downloader_set_format (downloader, download->format);
gdk_texture_downloader_download_into (downloader, download->data, download->stride);
gdk_texture_downloader_free (downloader);
g_object_unref (native);
}
static void
gdk_dmabuf_egl_downloader_download (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
Download download;
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;
gdk_dmabuf_egl_downloader_run (gdk_dmabuf_egl_downloader_do_download, &download);
}
const GdkDmabufDownloader *
gdk_dmabuf_get_egl_downloader (void)
{
static const GdkDmabufDownloader downloader = {
"egl",
gdk_dmabuf_egl_downloader_add_formats,
gdk_dmabuf_egl_downloader_supports,
gdk_dmabuf_egl_downloader_download,
};
return &downloader;
}
#endif /* HAVE_DMABUF && HAVE_EGL */
-215
View File
@@ -1,215 +0,0 @@
/* gdkdmabufformats.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <glib-object.h>
#include "gdkdmabufformatsprivate.h"
/**
* GdkDmabufFormats:
*
* The `GdkDmabufFormats struct provides information about
* supported DMA buffer formats.
*
* You can query whether a given format is supported with
* [method@Gdk.DmabufFormats.contains] and you can iterate
* over the list of all supported formats with
* [method@Gdk.DmabufFormats.get_n_formats] and
* [method@Gdk.DmabufFormats.get_format].
*
* The list of supported formats is sorted by preference,
* with the best formats coming first.
*
* See [class@Gdk.DmabufTextureBuilder] for more information
* about DMA buffers.
*
* Note that DMA buffers only exist on Linux.
*
* Since: 4.14
*/
struct _GdkDmabufFormats
{
int ref_count;
gsize n_formats;
GdkDmabufFormat *formats;
};
G_DEFINE_BOXED_TYPE (GdkDmabufFormats, gdk_dmabuf_formats, gdk_dmabuf_formats_ref, gdk_dmabuf_formats_unref)
/**
* gdk_dmabuf_formats_ref:
* @formats: a `GdkDmabufFormats`
*
* Increases the reference count of @formats.
*
* Returns: the passed-in object
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_ref (GdkDmabufFormats *formats)
{
formats->ref_count++;
return formats;
}
/**
* gdk_dmabuf_formats_unref:
* @formats: a `GdkDmabufFormats`
*
* Decreases the reference count of @formats.
*
* When the reference count reaches zero,
* the object is freed.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_unref (GdkDmabufFormats *formats)
{
formats->ref_count--;
if (formats->ref_count > 0)
return;
g_free (formats->formats);
g_free (formats);
}
/**
* gdk_dmabuf_formats_get_n_formats:
* @formats: a `GdkDmabufFormats`
*
* Returns the number of formats that the @formats object
* contains.
*
* Note that DMA buffers are a Linux concept, so on other
* platforms, [method@Gdk.DmabufFormats.get_n_formats] will
* always return zero.
*
* Returns: the number of formats
*
* Since: 4.14
*/
gsize
gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats)
{
return formats->n_formats;
}
/**
* gdk_dmabuf_formats_get_format:
* @formats: a `GdkDmabufFormats`
* @idx: the index of the format to return
* @fourcc: (out): return location for the format code
* @modifier: (out): return location for the format modifier
*
* Gets the fourcc code and modifier for a format
* that is contained in @formats.
*
* Since: 4.14
*/
void
gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier)
{
GdkDmabufFormat *format;
g_return_if_fail (idx < formats->n_formats);
g_return_if_fail (fourcc != NULL);
g_return_if_fail (modifier != NULL);
format = &formats->formats[idx];
*fourcc = format->fourcc;
*modifier = format->modifier;
}
/**
* gdk_dmabuf_format_contains:
* @formats: a `GdkDmabufFormats`
* @fourcc: a format code
* @modfier: a format modifier
*
* Returns whether a given format is contained in @formats.
*
* Returns: `TRUE` if the format specified by the arguments
* is part of @formats
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier)
{
for (gsize i = 0; i < formats->n_formats; i++)
{
GdkDmabufFormat *format = &formats->formats[i];
if (format->fourcc == fourcc && format->modifier == modifier)
return TRUE;
}
return FALSE;
}
/*< private >
* gdk_dmabuf_formats_new:
* @formats: the formats
* @n_formats: the length of @formats
*
* Creates a new `GdkDmabufFormats struct for
* the given formats.
*
* The @formats array is expected to be sorted
* by preference.
*
* Returns: (transfer full): the new `GdkDmabufFormats`
*
* Since: 4.14
*/
GdkDmabufFormats *
gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats)
{
GdkDmabufFormats *self;
self = g_new0 (GdkDmabufFormats, 1);
self->ref_count = 1;
self->n_formats = n_formats;
self->formats = g_new (GdkDmabufFormat, n_formats);
memcpy (self->formats, formats, n_formats * sizeof (GdkDmabufFormat));
return self;
}
const GdkDmabufFormat *
gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self)
{
return self->formats;
}
-54
View File
@@ -1,54 +0,0 @@
/* gdkdmabufformats.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 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/>.
*/
#pragma once
#if !defined (__GDK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gdk/gdk.h> can be included directly."
#endif
#include <gdk/gdktypes.h>
G_BEGIN_DECLS
#define GDK_TYPE_DMABUF_FORMATS (gdk_dmabuf_formats_get_type ())
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_formats_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GdkDmabufFormats * gdk_dmabuf_formats_ref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_unref (GdkDmabufFormats *formats);
GDK_AVAILABLE_IN_4_14
gsize gdk_dmabuf_formats_get_n_formats (GdkDmabufFormats *formats) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_formats_get_format (GdkDmabufFormats *formats,
gsize idx,
guint32 *fourcc,
guint64 *modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_formats_contains (GdkDmabufFormats *formats,
guint32 fourcc,
guint64 modifier) G_GNUC_PURE;
G_END_DECLS
-143
View File
@@ -1,143 +0,0 @@
/* gdkdmabufformats.c
*
* Copyright 2023 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "gdkdmabufformatsbuilderprivate.h"
#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
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
#define GDK_ARRAY_BY_VALUE 1
#define GDK_ARRAY_PREALLOC 1024
#define GDK_ARRAY_NO_MEMSET 1
#include "gdk/gdkarrayimpl.c"
/* NB: We keep duplicates in the list for ease of use. Only when creating the final
* GdkDmabufFormats do we actually remove duplicates.
*/
GdkDmabufFormatsBuilder *
gdk_dmabuf_formats_builder_new (void)
{
GdkDmabufFormatsBuilder *result = g_new (GdkDmabufFormatsBuilder, 1);
gdk_dmabuf_formats_builder_init (result);
return result;
}
static int
gdk_dmabuf_format_compare (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
if (a->fourcc == b->fourcc)
return (a->modifier - b->modifier) >> 8 * (sizeof (gint64) - sizeof (gint));
else
return a->fourcc - b->fourcc;
}
static gboolean
gdk_dmabuf_format_equal (gconstpointer data_a,
gconstpointer data_b)
{
const GdkDmabufFormat *a = data_a;
const GdkDmabufFormat *b = data_b;
return a->fourcc == b->fourcc &&
a->modifier == b->modifier;
}
static void
gdk_dmabuf_formats_builder_sort (GdkDmabufFormatsBuilder *self)
{
qsort (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self),
sizeof (GdkDmabufFormat),
gdk_dmabuf_format_compare);
}
/* list must be sorted */
static void
gdk_dmabuf_formats_builder_remove_duplicates (GdkDmabufFormatsBuilder *self)
{
gsize i, j;
for (i = 1, j = 0; i < gdk_dmabuf_formats_builder_get_size (self); i++)
{
if (gdk_dmabuf_format_equal (gdk_dmabuf_formats_builder_get (self, i),
gdk_dmabuf_formats_builder_get (self, j)))
continue;
j++;
if (i != j)
*gdk_dmabuf_formats_builder_index (self, j) = *gdk_dmabuf_formats_builder_index (self, i);
}
}
GdkDmabufFormats *
gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self)
{
GdkDmabufFormats *formats;
gdk_dmabuf_formats_builder_sort (self);
gdk_dmabuf_formats_builder_remove_duplicates (self);
formats = gdk_dmabuf_formats_new (gdk_dmabuf_formats_builder_get_data (self),
gdk_dmabuf_formats_builder_get_size (self));
gdk_dmabuf_formats_builder_clear (self);
g_free (self);
return formats;
}
void
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 });
}
void
gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats)
{
gdk_dmabuf_formats_builder_splice (self,
gdk_dmabuf_formats_builder_get_size (self),
0,
FALSE,
gdk_dmabuf_formats_peek_formats (formats),
gdk_dmabuf_formats_get_n_formats (formats));
}
-14
View File
@@ -1,14 +0,0 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct GdkDmabufFormatsBuilder GdkDmabufFormatsBuilder;
GdkDmabufFormatsBuilder * gdk_dmabuf_formats_builder_new (void);
GdkDmabufFormats * gdk_dmabuf_formats_builder_free_to_formats (GdkDmabufFormatsBuilder *self);
void gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc,
guint64 modifier);
void gdk_dmabuf_formats_builder_add_formats (GdkDmabufFormatsBuilder *self,
GdkDmabufFormats *formats);
-15
View File
@@ -1,15 +0,0 @@
#pragma once
#include "gdkdmabufformats.h"
typedef struct _GdkDmabufFormat GdkDmabufFormat;
struct _GdkDmabufFormat
{
guint32 fourcc;
guint64 modifier;
};
GdkDmabufFormats * gdk_dmabuf_formats_new (GdkDmabufFormat *formats,
gsize n_formats);
const GdkDmabufFormat * gdk_dmabuf_formats_peek_formats (GdkDmabufFormats *self);
-54
View File
@@ -1,54 +0,0 @@
#pragma once
#include "gdkdmabufformatsbuilderprivate.h"
#define GDK_DMABUF_MAX_PLANES 4
typedef struct _GdkDmabuf GdkDmabuf;
typedef struct _GdkDmabufDownloader GdkDmabufDownloader;
struct _GdkDmabuf
{
guint32 fourcc;
guint64 modifier;
unsigned int n_planes;
struct {
int fd;
unsigned int stride;
unsigned int offset;
} planes[GDK_DMABUF_MAX_PLANES];
};
struct _GdkDmabufDownloader
{
const char *name;
gboolean (* add_formats) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
GdkDmabufFormatsBuilder *builder);
gboolean (* supports) (const GdkDmabufDownloader *downloader,
GdkDisplay *display,
const GdkDmabuf *dmabuf,
gboolean premultiplied,
GdkMemoryFormat *out_format,
GError **error);
void (* download) (const GdkDmabufDownloader *downloader,
GdkTexture *texture,
GdkMemoryFormat format,
guchar *data,
gsize stride);
};
#ifdef HAVE_DMABUF
const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST;
const GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (void) G_GNUC_CONST;
gboolean gdk_dmabuf_sanitize (GdkDmabuf *dest,
gsize width,
gsize height,
const GdkDmabuf *src,
GError **error);
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
#endif
+261 -83
View File
@@ -20,21 +20,30 @@
#include "gdkdmabuftextureprivate.h"
#ifndef __linux__
GType
gdk_dmabuf_texture_get_type (void)
{
return G_TYPE_INVALID;
}
#else
#include "gdkdisplayprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufprivate.h"
#include "gdktextureprivate.h"
#include "gdkmemoryformatprivate.h"
#include "gdkmemorytextureprivate.h"
#include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdktexturedownloader.h>
#include <gsk/gsk.h>
#include <gsk/gl/gskglrenderer.h>
#ifdef HAVE_DMABUF
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/dma-buf.h>
#include <drm_fourcc.h>
#include <drm/drm_fourcc.h>
#include <epoxy/egl.h>
#endif
/**
* GdkDmabufTexture:
@@ -52,9 +61,16 @@ struct _GdkDmabufTexture
GdkTexture parent_instance;
GdkDisplay *display;
const GdkDmabufDownloader *downloader;
GdkDmabuf dmabuf;
unsigned int fourcc;
guint64 modifier;
unsigned int n_planes;
/* Per-plane properties */
int fds[4];
unsigned int strides[4];
unsigned int offsets[4];
GDestroyNotify destroy;
gpointer data;
@@ -65,15 +81,8 @@ struct _GdkDmabufTextureClass
GdkTextureClass parent_class;
};
G_DEFINE_QUARK (gdk-dmabuf-error-quark, gdk_dmabuf_error)
G_DEFINE_TYPE (GdkDmabufTexture, gdk_dmabuf_texture, GDK_TYPE_TEXTURE)
static void
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
{
}
static void
gdk_dmabuf_texture_dispose (GObject *object)
{
@@ -85,6 +94,130 @@ gdk_dmabuf_texture_dispose (GObject *object)
G_OBJECT_CLASS (gdk_dmabuf_texture_parent_class)->dispose (object);
}
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
struct _GdkDrmFormatInfo
{
unsigned int fourcc;
GdkMemoryFormat memory_format;
gboolean requires_gl;
};
static GdkDrmFormatInfo supported_formats[] = {
{ DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, FALSE },
{ DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, FALSE },
{ DRM_FORMAT_ARGB8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, FALSE },
{ DRM_FORMAT_RGBA8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, FALSE },
{ DRM_FORMAT_BGRA8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, FALSE },
{ DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, FALSE },
{ DRM_FORMAT_YUYV, GDK_MEMORY_DEFAULT, TRUE },
{ DRM_FORMAT_NV12, GDK_MEMORY_DEFAULT, TRUE },
{ DRM_FORMAT_P010, GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, TRUE },
{ DRM_FORMAT_YUV420, GDK_MEMORY_DEFAULT, TRUE },
};
static GdkDrmFormatInfo *
get_drm_format_info (unsigned int fourcc)
{
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (supported_formats[i].fourcc == fourcc)
return &supported_formats[i];
}
return NULL;
}
gboolean
gdk_dmabuf_texture_may_support (unsigned int fourcc)
{
return get_drm_format_info (fourcc) != NULL;
}
static void
do_indirect_download (GdkDmabufTexture *self,
GdkMemoryFormat format,
guchar *data,
gsize stride)
{
GskRenderer *renderer;
int width, height;
GskRenderNode *node;
GdkTexture *gl_texture;
GdkTextureDownloader *downloader;
GError *error = NULL;
GDK_DEBUG (MISC, "Using gsk_renderer_render_texture import for downloading a dmabuf");
g_assert (GDK_IS_DISPLAY (self->display));
g_assert (GDK_IS_GL_CONTEXT (gdk_display_get_gl_context (self->display)));
renderer = gsk_gl_renderer_new ();
if (!gsk_renderer_realize (renderer, NULL, &error))
{
g_warning ("Failed to realize GL renderer: %s", error->message);
g_error_free (error);
g_object_unref (renderer);
return;
}
width = gdk_texture_get_width (GDK_TEXTURE (self));
height = gdk_texture_get_height (GDK_TEXTURE (self));
node = gsk_texture_node_new (GDK_TEXTURE (self), &GRAPHENE_RECT_INIT (0, 0, width, height));
gl_texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_render_node_unref (node);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
downloader = gdk_texture_downloader_new (gl_texture);
gdk_texture_downloader_set_format (downloader, format);
gdk_texture_downloader_download_into (downloader, data, stride);
gdk_texture_downloader_free (downloader);
g_object_unref (gl_texture);
}
static void
do_direct_download (GdkDmabufTexture *self,
guchar *data,
gsize stride)
{
gsize size;
unsigned int height;
gsize src_stride;
guchar *src_data;
int bpp;
GDK_DEBUG (MISC, "Using mmap() and memcpy() for downloading a dmabuf");
height = gdk_texture_get_height (GDK_TEXTURE (self));
bpp = gdk_memory_format_bytes_per_pixel (gdk_texture_get_format (GDK_TEXTURE (self)));
src_stride = self->strides[0];
size = self->strides[0] * height;
if (ioctl (self->fds[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_START|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
src_data = mmap (NULL, size, PROT_READ, MAP_SHARED, self->fds[0], self->offsets[0]);
if (stride == src_stride)
memcpy (data, src_data, size);
else
{
for (unsigned int i = 0; i < height; i++)
memcpy (data + i * stride, src_data + i * src_stride, height * bpp);
}
if (ioctl (self->fds[0], DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
munmap (src_data, size);
}
static void
gdk_dmabuf_texture_download (GdkTexture *texture,
GdkMemoryFormat format,
@@ -92,12 +225,35 @@ gdk_dmabuf_texture_download (GdkTexture *texture,
gsize stride)
{
GdkDmabufTexture *self = GDK_DMABUF_TEXTURE (texture);
GdkMemoryFormat src_format = gdk_texture_get_format (texture);
GdkDrmFormatInfo *info;
self->downloader->download (self->downloader,
texture,
format,
data,
stride);
info = get_drm_format_info (self->fourcc);
if (info->requires_gl || self->n_planes > 1)
do_indirect_download (self, format, data, stride);
else if (format == src_format)
do_direct_download (self, data, stride);
else
{
unsigned int width, height;
guchar *src_data;
gsize src_stride;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
src_stride = self->strides[0];
src_data = g_new (guchar, src_stride * height);
do_direct_download (self, src_data, src_stride);
gdk_memory_convert (data, stride, format,
src_data, src_stride, src_format,
width, height);
g_free (src_data);
}
}
static void
@@ -111,86 +267,77 @@ gdk_dmabuf_texture_class_init (GdkDmabufTextureClass *klass)
gobject_class->dispose = gdk_dmabuf_texture_dispose;
}
GdkDisplay *
gdk_dmabuf_texture_get_display (GdkDmabufTexture *self)
static void
gdk_dmabuf_texture_init (GdkDmabufTexture *self)
{
return self->display;
self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1;
}
const GdkDmabuf *
gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self)
static gboolean
display_supports_format (GdkDisplay *display,
unsigned int fourcc,
guint64 modifier)
{
return &self->dmabuf;
const GdkDmabufFormat *formats;
gsize n_formats;
if (!display)
return FALSE;
formats = gdk_display_get_dmabuf_formats (display, &n_formats);
for (gsize i = 0; i < n_formats; i++)
{
if (formats[i].fourcc == fourcc &&
formats[i].modifier == modifier)
return TRUE;
}
return FALSE;
}
GdkTexture *
gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error)
gpointer data)
{
#ifdef HAVE_DMABUF
GdkDmabufTexture *self;
GdkTexture *update_texture;
GdkDisplay *display;
GdkDmabuf dmabuf;
GdkMemoryFormat format;
GError *local_error = NULL;
int width, height;
gsize i;
GdkDisplay *display = gdk_dmabuf_texture_builder_get_display (builder);
uint32_t fourcc = gdk_dmabuf_texture_builder_get_fourcc (builder);
uint64_t modifier = gdk_dmabuf_texture_builder_get_modifier (builder);
unsigned int n_planes = gdk_dmabuf_texture_builder_get_n_planes (builder);
GdkDrmFormatInfo *info;
display = gdk_dmabuf_texture_builder_get_display (builder);
width = gdk_dmabuf_texture_builder_get_width (builder);
height = gdk_dmabuf_texture_builder_get_height (builder);
info = get_drm_format_info (fourcc);
if (!gdk_dmabuf_sanitize (&dmabuf,
width,
height,
gdk_dmabuf_texture_builder_get_dmabuf (builder),
error))
return NULL;
gdk_display_init_dmabuf (display);
for (i = 0; display->dmabuf_downloaders[i] != NULL; i++)
if (!info ||
((info->requires_gl || n_planes > 1) && !display_supports_format (display, fourcc, modifier)))
{
if (local_error && g_error_matches (local_error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT))
g_clear_error (&local_error);
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
display,
&dmabuf,
gdk_dmabuf_texture_builder_get_premultiplied (builder),
&format,
local_error ? NULL : &local_error))
break;
}
if (display->dmabuf_downloaders[i] == NULL)
{
g_propagate_error (error, local_error);
g_warning ("Unsupported dmabuf format %c%c%c%c:%#lx",
fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier);
return NULL;
}
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,
format,
display->dmabuf_downloaders[i]->name);
GDK_DEBUG (MISC, "Dmabuf texture in format %c%c%c%c:%#lx",
fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier);
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", width,
"height", height,
"width", gdk_dmabuf_texture_builder_get_width (builder),
"height", gdk_dmabuf_texture_builder_get_height (builder),
NULL);
GDK_TEXTURE (self)->format = format;
GDK_TEXTURE (self)->format = info->memory_format;
g_set_object (&self->display, display);
self->downloader = display->dmabuf_downloaders[i];
self->dmabuf = dmabuf;
self->destroy = destroy;
self->data = data;
self->fourcc = fourcc;
self->modifier = modifier;
self->n_planes = n_planes;
memcpy (self->fds, gdk_dmabuf_texture_builder_get_fds (builder), sizeof (int) * 4);
memcpy (self->strides, gdk_dmabuf_texture_builder_get_strides (builder), sizeof (unsigned int) * 4);
memcpy (self->offsets, gdk_dmabuf_texture_builder_get_offsets (builder), sizeof (unsigned int) * 4);
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
if (update_texture)
@@ -209,11 +356,42 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
}
return GDK_TEXTURE (self);
#else /* !HAVE_DMABUF */
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled at compile-time.");
return NULL;
#endif
}
unsigned int
gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture)
{
return texture->fourcc;
}
guint64
gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture)
{
return texture->modifier;
}
unsigned int
gdk_dmabuf_texture_get_n_planes (GdkDmabufTexture *texture)
{
return texture->n_planes;
}
int *
gdk_dmabuf_texture_get_fds (GdkDmabufTexture *texture)
{
return texture->fds;
}
unsigned int *
gdk_dmabuf_texture_get_strides (GdkDmabufTexture *texture)
{
return texture->strides;
}
unsigned int *
gdk_dmabuf_texture_get_offsets (GdkDmabufTexture *texture)
{
return texture->offsets;
}
#endif /* __linux__ */
-5
View File
@@ -32,17 +32,12 @@ G_BEGIN_DECLS
#define GDK_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_DMABUF_TEXTURE, GdkDmabufTexture))
#define GDK_IS_DMABUF_TEXTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_DMABUF_TEXTURE))
#define GDK_DMABUF_ERROR (gdk_dmabuf_error_quark ())
typedef struct _GdkDmabufTexture GdkDmabufTexture;
typedef struct _GdkDmabufTextureClass GdkDmabufTextureClass;
GDK_AVAILABLE_IN_4_14
GType gdk_dmabuf_texture_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GQuark gdk_dmabuf_error_quark (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDmabufTexture, g_object_unref)
G_END_DECLS
+345 -202
View File
@@ -21,17 +21,11 @@
#include "gdkdmabuftexturebuilder.h"
#include "gdkdebugprivate.h"
#include "gdkdisplay.h"
#include "gdkenumtypes.h"
#include "gdkdmabuftextureprivate.h"
#include <cairo-gobject.h>
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#else
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
struct _GdkDmabufTextureBuilder
@@ -41,9 +35,15 @@ struct _GdkDmabufTextureBuilder
GdkDisplay *display;
unsigned int width;
unsigned int height;
gboolean premultiplied;
unsigned int fourcc;
guint64 modifier;
GdkDmabuf dmabuf;
unsigned int n_planes;
/* per-plane properties */
int fds[4];
unsigned int strides[4];
unsigned int offsets[4];
GdkTexture *update_texture;
cairo_region_t *update_region;
@@ -57,51 +57,19 @@ struct _GdkDmabufTextureBuilderClass
/**
* GdkDmabufTextureBuilder:
*
* `GdkDmabufTextureBuilder` is a builder used to construct [class@Gdk.Texture]
* objects from DMA buffers.
* `GdkDmabufTextureBuilder` is a buider used to construct [class@Gdk.Texture]
* objects from dma-buf buffers.
*
* DMA buffers are commonly called **_dma-bufs_**.
*
* DMA buffers a feature of the Linux kernel to enable efficient buffer and
* memory sharing between hardware such as codecs, GPUs, displays, cameras and the
* kernel drivers controlling them. For example, a decoder may want its output to
* be directly shared with the display server for rendering without a copy.
*
* Any device driver which participates in DMA buffer sharing, can do so as either
* the exporter or importer of buffers (or both).
*
* The memory that is shared via DMA buffers is usually stored in non-system memory
* (maybe in device's local memory or something else not directly accessible by the
* CPU), and accessing this memory from the CPU may have higher than usual overhead.
*
* In particular for graphics data, it is not uncommon that data consists of multiple
* separate blocks of memory, for example one block for each of the red, green and
* blue channels. These blocks are called **_planes_**. DMA buffers can have up to
* four planes. Even if the memory is a single block, the data can be organized in
* multiple planes, by specifying offsets from the beginning of the data.
*
* DMA buffers are exposed to user-space as file descriptors allowing to pass them
* between processes. If a DMA buffer has multiple planes, there is one file
* 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](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.
*
* The operation of `GdkDmabufTextureBuilder` is quite simple: Create a texture builder,
* set all the necessary properties, and then call [method@Gdk.DmabufTextureBuilder.build]
* to create the new texture.
* The operation is quite simple: Create a texture builder, set all the necessary
* properties, and then call [method@Gdk.DmabufTextureBuilder.build] to create the
* new texture.
*
* The required properties for a dma-buf texture are
*
* * The width and height in pixels
*
* * The `fourcc` code and `modifier` which identify the format and memory layout of the dma-buf
*
* * The file descriptor, offset and stride for each of the planes
* - The width and height in pixels
* - The `fourcc` code and `modifier` which together identify the
* format and memory layout of the dma-buf. See the `drm_fourcc.h`
* header for more information about these
* - The file descriptor referring to the buffer
*
* `GdkDmabufTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures.
@@ -117,8 +85,19 @@ enum
PROP_HEIGHT,
PROP_FOURCC,
PROP_MODIFIER,
PROP_PREMULTIPLIED,
PROP_N_PLANES,
PROP_FD0,
PROP_FD1,
PROP_FD2,
PROP_FD3,
PROP_STRIDE0,
PROP_STRIDE1,
PROP_STRIDE2,
PROP_STRIDE3,
PROP_OFFSET0,
PROP_OFFSET1,
PROP_OFFSET2,
PROP_OFFSET3,
PROP_UPDATE_REGION,
PROP_UPDATE_TEXTURE,
@@ -163,19 +142,63 @@ gdk_dmabuf_texture_builder_get_property (GObject *object,
break;
case PROP_FOURCC:
g_value_set_uint (value, self->dmabuf.fourcc);
g_value_set_uint (value, self->fourcc);
break;
case PROP_MODIFIER:
g_value_set_uint64 (value, self->dmabuf.modifier);
break;
case PROP_PREMULTIPLIED:
g_value_set_boolean (value, self->premultiplied);
g_value_set_uint64 (value, self->modifier);
break;
case PROP_N_PLANES:
g_value_set_uint (value, self->dmabuf.n_planes);
g_value_set_uint (value, self->n_planes);
break;
case PROP_FD0:
g_value_set_int (value, self->fds[0]);
break;
case PROP_FD1:
g_value_set_int (value, self->fds[1]);
break;
case PROP_FD2:
g_value_set_int (value, self->fds[2]);
break;
case PROP_FD3:
g_value_set_int (value, self->fds[3]);
break;
case PROP_STRIDE0:
g_value_set_uint (value, self->strides[0]);
break;
case PROP_STRIDE1:
g_value_set_uint (value, self->strides[1]);
break;
case PROP_STRIDE2:
g_value_set_uint (value, self->strides[2]);
break;
case PROP_STRIDE3:
g_value_set_uint (value, self->strides[3]);
break;
case PROP_OFFSET0:
g_value_set_uint (value, self->offsets[0]);
break;
case PROP_OFFSET1:
g_value_set_uint (value, self->offsets[1]);
break;
case PROP_OFFSET2:
g_value_set_uint (value, self->offsets[2]);
break;
case PROP_OFFSET3:
g_value_set_uint (value, self->offsets[3]);
break;
case PROP_UPDATE_REGION:
@@ -222,14 +245,58 @@ gdk_dmabuf_texture_builder_set_property (GObject *object,
gdk_dmabuf_texture_builder_set_modifier (self, g_value_get_uint64 (value));
break;
case PROP_PREMULTIPLIED:
gdk_dmabuf_texture_builder_set_premultiplied (self, g_value_get_boolean (value));
break;
case PROP_N_PLANES:
gdk_dmabuf_texture_builder_set_n_planes (self, g_value_get_uint (value));
break;
case PROP_FD0:
gdk_dmabuf_texture_builder_set_fd (self, 0, g_value_get_int (value));
break;
case PROP_FD1:
gdk_dmabuf_texture_builder_set_fd (self, 1, g_value_get_int (value));
break;
case PROP_FD2:
gdk_dmabuf_texture_builder_set_fd (self, 2, g_value_get_int (value));
break;
case PROP_FD3:
gdk_dmabuf_texture_builder_set_fd (self, 3, g_value_get_int (value));
break;
case PROP_STRIDE0:
gdk_dmabuf_texture_builder_set_stride (self, 0, g_value_get_uint (value));
break;
case PROP_STRIDE1:
gdk_dmabuf_texture_builder_set_stride (self, 1, g_value_get_uint (value));
break;
case PROP_STRIDE2:
gdk_dmabuf_texture_builder_set_stride (self, 2, g_value_get_uint (value));
break;
case PROP_STRIDE3:
gdk_dmabuf_texture_builder_set_stride (self, 3, g_value_get_uint (value));
break;
case PROP_OFFSET0:
gdk_dmabuf_texture_builder_set_offset (self, 0, g_value_get_uint (value));
break;
case PROP_OFFSET1:
gdk_dmabuf_texture_builder_set_offset (self, 1, g_value_get_uint (value));
break;
case PROP_OFFSET2:
gdk_dmabuf_texture_builder_set_offset (self, 2, g_value_get_uint (value));
break;
case PROP_OFFSET3:
gdk_dmabuf_texture_builder_set_offset (self, 3, g_value_get_uint (value));
break;
case PROP_UPDATE_REGION:
gdk_dmabuf_texture_builder_set_update_region (self, g_value_get_boxed (value));
break;
@@ -298,7 +365,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
*/
properties[PROP_FOURCC] =
g_param_spec_uint ("fourcc", NULL, NULL,
0, 0xffffffff, 0,
0, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
@@ -313,20 +380,6 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:premultiplied:
*
* Whether the alpha channel is premultiplied into the others.
*
* Only relevant if the format has alpha.
*
* Since: 4.14
*/
properties[PROP_PREMULTIPLIED] =
g_param_spec_boolean ("premultiplied", NULL, NULL,
TRUE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* 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)
*
@@ -339,7 +392,151 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
*/
properties[PROP_N_PLANES] =
g_param_spec_uint ("n-planes", NULL, NULL,
1, GDK_DMABUF_MAX_PLANES, 1,
0, 4, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fd0:
*
* The file descriptor for plane 0.
*
* Since: 4.14
*/
properties[PROP_FD0] =
g_param_spec_int ("fd0", NULL, NULL,
-1, G_MAXINT, -1,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fd1:
*
* The file descriptor for plane 1.
*
* Since: 4.14
*/
properties[PROP_FD1] =
g_param_spec_int ("fd1", NULL, NULL,
-1, G_MAXINT, -1,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fd2:
*
* The file descriptor for plane 2.
*
* Since: 4.14
*/
properties[PROP_FD2] =
g_param_spec_int ("fd2", NULL, NULL,
-1, G_MAXINT, -1,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:fd3:
*
* The file descriptor for plane 3.
*
* Since: 4.14
*/
properties[PROP_FD3] =
g_param_spec_int ("fd3", NULL, NULL,
-1, G_MAXINT, -1,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:stride0:
*
* The stride for plane 0.
*
* Since: 4.14
*/
properties[PROP_STRIDE0] =
g_param_spec_uint ("stride0", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:stride1:
*
* The stride for plane 1.
*
* Since: 4.14
*/
properties[PROP_STRIDE1] =
g_param_spec_uint ("stride1", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:stride2:
*
* The stride for plane 2.
*
* Since: 4.14
*/
properties[PROP_STRIDE2] =
g_param_spec_uint ("stride2", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:stride3:
*
* The stride for plane 3.
*
* Since: 4.14
*/
properties[PROP_STRIDE3] =
g_param_spec_uint ("stride3", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:offset0:
*
* The offset for plane 0.
*
* Since: 4.14
*/
properties[PROP_OFFSET0] =
g_param_spec_uint ("offset0", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:offset1:
*
* The offset for plane 1.
*
* Since: 4.14
*/
properties[PROP_OFFSET1] =
g_param_spec_uint ("offset1", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:offset2:
*
* The offset for plane 2.
*
* Since: 4.14
*/
properties[PROP_OFFSET2] =
g_param_spec_uint ("offset2", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
* GdkDmabufTextureBuilder:offset3:
*
* The offset for plane 3.
*
* Since: 4.14
*/
properties[PROP_OFFSET3] =
g_param_spec_uint ("offset3", NULL, NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/**
@@ -372,12 +569,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
static void
gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self)
{
self->premultiplied = TRUE;
self->display = gdk_display_get_default ();
self->dmabuf.n_planes = 1;
for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++)
self->dmabuf.planes[i].fd = -1;
self->fds[0] = self->fds[1] = self->fds[2] = self->fds[3] = -1;
}
/**
@@ -402,7 +594,7 @@ gdk_dmabuf_texture_builder_new (void)
* Returns the display that this texture builder is
* associated with.
*
* Returns: (transfer none): the display
* Returns: (transfer none) (nullable): the display
*
* Since: 4.14
*/
@@ -432,7 +624,6 @@ gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
GdkDisplay *display)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (GDK_IS_DISPLAY (display));
if (g_set_object (&self->display, display))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISPLAY]);
@@ -539,12 +730,12 @@ gdk_dmabuf_texture_builder_set_height (GdkDmabufTextureBuilder *self,
*
* Since: 4.14
*/
guint32
unsigned int
gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.fourcc;
return self->fourcc;
}
/**
@@ -562,14 +753,14 @@ gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self)
*/
void
gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
guint32 fourcc)
unsigned int fourcc)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->dmabuf.fourcc == fourcc)
if (self->fourcc == fourcc)
return;
self->dmabuf.fourcc = fourcc;
self->fourcc = fourcc;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOURCC]);
}
@@ -589,7 +780,7 @@ gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.modifier;
return self->modifier;
}
/**
@@ -606,18 +797,11 @@ 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)
if (self->modifier == modifier)
return;
self->dmabuf.modifier = modifier;
self->modifier = modifier;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODIFIER]);
}
@@ -637,51 +821,7 @@ gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
return self->dmabuf.n_planes;
}
/**
* gdk_dmabuf_texture_builder_get_premultiplied:
* @self: a `GdkDmabufTextureBuilder`
*
* Whether the data is premultiplied.
*
* Returns: whether the data is premultiplied
*
* Since: 4.14
*/
gboolean
gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), TRUE);
return self->premultiplied;
}
/**
* gdk_dmabuf_texture_builder_set_premultiplied:
* @self: a `GdkDmabufTextureBuilder`
* @premultiplied: whether the data is premultiplied
*
* Sets whether the data is premultiplied.
*
* Unless otherwise specified, all formats including alpha channels are assumed
* to be premultiplied.
*
* Since: 4.14
*/
void
gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
gboolean premultiplied)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
if (self->premultiplied == premultiplied)
return;
self->premultiplied = premultiplied;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PREMULTIPLIED]);
return self->n_planes;
}
/**
@@ -698,12 +838,11 @@ gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (n_planes > 0 && n_planes <= GDK_DMABUF_MAX_PLANES);
if (self->dmabuf.n_planes == n_planes)
if (self->n_planes == n_planes)
return;
self->dmabuf.n_planes = n_planes;
self->n_planes = n_planes;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_PLANES]);
}
@@ -721,12 +860,12 @@ gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
*/
int
gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
unsigned int plane)
int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->dmabuf.planes[plane].fd;
return self->fds[plane];
}
/**
@@ -741,16 +880,18 @@ gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
*/
void
gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
int fd)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
g_return_if_fail (0 <= plane && plane < 4);
if (self->dmabuf.planes[plane].fd == fd)
if (self->fds[plane] == fd)
return;
self->dmabuf.planes[plane].fd = fd;
self->fds[plane] = fd;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FD0 + plane]);
}
/**
@@ -766,12 +907,12 @@ gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
*/
unsigned int
gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
unsigned int plane)
int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->dmabuf.planes[plane].stride;
return self->strides[plane];
}
/**
@@ -788,16 +929,18 @@ gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
*/
void
gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
unsigned int stride)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
g_return_if_fail (0 <= plane && plane < 4);
if (self->dmabuf.planes[plane].stride == stride)
if (self->strides[plane] == stride)
return;
self->dmabuf.planes[plane].stride = stride;
self->strides[plane] = stride;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_STRIDE0 + plane]);
}
/**
@@ -813,12 +956,12 @@ gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
*/
unsigned int
gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
unsigned int plane)
int plane)
{
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), 0);
g_return_val_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES, 0);
g_return_val_if_fail (0 <= plane && plane < 4, 0);
return self->dmabuf.planes[plane].offset;
return self->offsets[plane];
}
/**
@@ -833,16 +976,18 @@ gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
*/
void
gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
unsigned int offset)
{
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
g_return_if_fail (0 <= plane && plane < GDK_DMABUF_MAX_PLANES);
g_return_if_fail (0 <= plane && plane < 4);
if (self->dmabuf.planes[plane].offset == offset)
if (self->offsets[plane] == offset)
return;
self->dmabuf.planes[plane].offset = offset;
self->offsets[plane] = offset;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OFFSET0 + plane]);
}
/**
@@ -947,26 +1092,18 @@ gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
* @destroy: (nullable): destroy function to be called when the texture is
* released
* @data: user data to pass to the destroy function
* @error: Return location for an error
*
* Builds a new `GdkTexture` with the values set up in the builder.
*
* It is a programming error to call this function if any mandatory
* property has not been set.
*
* If the dmabuf is not supported by GTK, %NULL will be returned and @error will be set.
*
* The `destroy` function gets called when the returned texture gets released.
*
* Note that it is a programming error to call this function if any mandatory
* property has not been set.
*
* It is possible to call this function multiple times to create multiple textures,
* possibly with changing properties in between.
*
* It is the responsibility of the caller to keep the file descriptors for the planes
* open until the created texture is no longer used, and close them afterwards (possibly
* using the @destroy notify).
*
* Not all formats defined in the `drm_fourcc.h` header are supported. You can use
* [method@Gdk.Display.get_dmabuf_formats] to get a list of supported formats.
* Not all formats defined in the `drm_fourcc.h` header are supported.
*
* Returns: (transfer full) (nullable): a newly built `GdkTexture` or `NULL`
* if the format is not supported
@@ -975,34 +1112,40 @@ gdk_dmabuf_texture_builder_set_update_region (GdkDmabufTextureBuilder *self,
*/
GdkTexture *
gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
GDestroyNotify destroy,
gpointer data,
GError **error)
GDestroyNotify destroy,
gpointer data)
{
unsigned i;
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL);
g_return_val_if_fail (destroy == NULL || data != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
g_return_val_if_fail (self->width > 0, NULL);
g_return_val_if_fail (self->height > 0, NULL);
g_return_val_if_fail (self->dmabuf.fourcc != 0, NULL);
g_return_val_if_fail (self->fourcc != 0, NULL);
g_return_val_if_fail (self->n_planes > 0, NULL);
for (i = 0; i < self->dmabuf.n_planes; i++)
g_return_val_if_fail (self->dmabuf.planes[i].fd != -1, NULL);
for (int i = 0; i < self->n_planes; i++)
g_return_val_if_fail (self->fds[i] != -1 || self->offsets[i] != 0, NULL);
if (GDK_DEBUG_CHECK (DMABUF_DISABLE))
{
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled via GDK_DEBUG environment variable");
return NULL;
}
return gdk_dmabuf_texture_new_from_builder (self, destroy, data, error);
#ifdef __linux__
return gdk_dmabuf_texture_new_from_builder (self, destroy, data);
#else
return NULL;
#endif
}
const GdkDmabuf *
gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *self)
int *
gdk_dmabuf_texture_builder_get_fds (GdkDmabufTextureBuilder *self)
{
return &self->dmabuf;
return self->fds;
}
unsigned int *
gdk_dmabuf_texture_builder_get_strides (GdkDmabufTextureBuilder *self)
{
return self->strides;
}
unsigned int *
gdk_dmabuf_texture_builder_get_offsets (GdkDmabufTextureBuilder *self)
{
return self->offsets;
}
+9 -16
View File
@@ -53,10 +53,10 @@ void gdk_dmabuf_texture_builder_set_height (GdkDmabufT
unsigned int height);
GDK_AVAILABLE_IN_4_14
guint32 gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
unsigned int gdk_dmabuf_texture_builder_get_fourcc (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fourcc (GdkDmabufTextureBuilder *self,
guint32 fourcc);
unsigned int fourcc);
GDK_AVAILABLE_IN_4_14
guint64 gdk_dmabuf_texture_builder_get_modifier (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
@@ -64,12 +64,6 @@ GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier);
GDK_AVAILABLE_IN_4_14
gboolean gdk_dmabuf_texture_builder_get_premultiplied (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_premultiplied (GdkDmabufTextureBuilder *self,
gboolean premultiplied);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_n_planes (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
@@ -78,26 +72,26 @@ void gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufT
GDK_AVAILABLE_IN_4_14
int gdk_dmabuf_texture_builder_get_fd (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_fd (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
int fd);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_stride (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_stride (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
unsigned int stride);
GDK_AVAILABLE_IN_4_14
unsigned int gdk_dmabuf_texture_builder_get_offset (GdkDmabufTextureBuilder *self,
unsigned int plane) G_GNUC_PURE;
int plane) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
void gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
unsigned int plane,
int plane,
unsigned int offset);
GDK_AVAILABLE_IN_4_14
@@ -115,8 +109,7 @@ void gdk_dmabuf_texture_builder_set_update_region (GdkDmabuf
GDK_AVAILABLE_IN_4_14
GdkTexture * gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
GDestroyNotify destroy,
gpointer data,
GError **error);
gpointer data);
G_END_DECLS
+14 -6
View File
@@ -3,19 +3,27 @@
#include "gdkdmabuftexture.h"
#include "gdkdmabuftexturebuilder.h"
#include "gdkdmabufprivate.h"
#include "gdktextureprivate.h"
G_BEGIN_DECLS
const GdkDmabuf * gdk_dmabuf_texture_builder_get_dmabuf (GdkDmabufTextureBuilder *builder);
int * gdk_dmabuf_texture_builder_get_fds (GdkDmabufTextureBuilder *builder);
unsigned int * gdk_dmabuf_texture_builder_get_offsets (GdkDmabufTextureBuilder *builder);
unsigned int * gdk_dmabuf_texture_builder_get_strides (GdkDmabufTextureBuilder *builder);
GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GDestroyNotify destroy,
gpointer data,
GError **error);
gpointer data);
unsigned int gdk_dmabuf_texture_get_fourcc (GdkDmabufTexture *texture);
guint64 gdk_dmabuf_texture_get_modifier (GdkDmabufTexture *texture);
unsigned int gdk_dmabuf_texture_get_n_planes (GdkDmabufTexture *texture);
int * gdk_dmabuf_texture_get_fds (GdkDmabufTexture *texture);
unsigned int * gdk_dmabuf_texture_get_offsets (GdkDmabufTexture *texture);
unsigned int * gdk_dmabuf_texture_get_strides (GdkDmabufTexture *texture);
gboolean gdk_dmabuf_texture_may_support (unsigned int fourcc);
GdkDisplay * gdk_dmabuf_texture_get_display (GdkDmabufTexture *self);
const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self);
G_END_DECLS
+1 -1
View File
@@ -684,7 +684,7 @@ gdk_drop_read_async (GdkDrop *self,
* gdk_drop_read_finish:
* @self: a `GdkDrop`
* @result: a `GAsyncResult`
* @out_mime_type: (out) (type utf8) (transfer none): return location for the used mime type
* @out_mime_type: (out) (type utf8): return location for the used mime type
* @error: (nullable): location to store error information on failure
*
* Finishes an async drop read operation.
-27
View File
@@ -142,22 +142,6 @@ typedef enum
GDK_BUTTON4_MASK|GDK_BUTTON5_MASK)
/**
* GdkDmabufError:
* @GDK_DMABUF_ERROR_NOT_AVAILABLE: Dmabuf support is not available, because the OS
* is not Linux, or it was explicitly disabled at compile- or runtime
* @GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT: The requested format is not supported
* @GDK_DMABUF_ERROR_CREATION_FAILED: GTK failed to create the resource for other
* reasons
*
* Error enumeration for `GdkDmabufTexture`.
*/
typedef enum {
GDK_DMABUF_ERROR_NOT_AVAILABLE,
GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
GDK_DMABUF_ERROR_CREATION_FAILED,
} GdkDmabufError;
/**
* GdkGLError:
* @GDK_GL_ERROR_NOT_AVAILABLE: OpenGL support is not available
@@ -298,16 +282,10 @@ typedef enum
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
* The color values are premultiplied with the alpha value.
* @GDK_MEMORY_A8B8G8R8_PREMULTIPLIED: 4 bytes; for alpha, blue, green, red,
* The color values are premultiplied with the alpha value. Since 4.14
* @GDK_MEMORY_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red.
* @GDK_MEMORY_B8G8R8X8: 4 bytes; for blue, green, red, unused. Since 4.14
* @GDK_MEMORY_X8R8G8B8: 4 bytes; for unused, red, green, blue. Since 4.14
* @GDK_MEMORY_R8G8B8X8: 4 bytes; for red, green, blue, unused. Since 4.14
* @GDK_MEMORY_X8B8G8R8: 4 bytes; for unused, blue, green, red. Since 4.14
* @GDK_MEMORY_R8G8B8: 3 bytes; for red, green, blue. The data is opaque.
* @GDK_MEMORY_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6
@@ -388,11 +366,6 @@ typedef enum {
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A16_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A32_FLOAT GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A8B8G8R8_PREMULTIPLIED GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_B8G8R8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_X8R8G8B8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_R8G8B8X8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_X8B8G8R8 GDK_AVAILABLE_ENUMERATOR_IN_4_14,
GDK_MEMORY_N_FORMATS
} GdkMemoryFormat;
-251
View File
@@ -83,7 +83,6 @@
#include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h"
#include "gdkglversionprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkprivate.h"
@@ -96,10 +95,6 @@
#include <epoxy/egl.h>
#endif
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#include <math.h>
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
@@ -114,8 +109,6 @@ typedef struct {
guint has_sync : 1;
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;
@@ -1538,13 +1531,11 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
priv->has_unpack_subimage = gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 0)) ||
epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
priv->has_bgra = epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888");
}
else
{
priv->has_unpack_subimage = TRUE;
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
priv->has_bgra = TRUE;
/* We asked for a core profile, but we didn't get one, so we're in legacy mode */
if (!gdk_gl_version_greater_equal (&priv->gl_version, &GDK_GL_VERSION_INIT (3, 2)))
@@ -1564,8 +1555,6 @@ 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;
@@ -1577,8 +1566,6 @@ 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",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
@@ -1588,8 +1575,6 @@ 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");
}
@@ -1877,44 +1862,6 @@ gdk_gl_context_has_sync (GdkGLContext *self)
return priv->has_sync;
}
/* Return if GL_BGRA works with glTexImage2D */
gboolean
gdk_gl_context_has_bgra (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
return priv->has_bgra;
}
/* Return if glGenVertexArrays, glBindVertexArray and glDeleteVertexArrays
* can be used
*/
gboolean
gdk_gl_context_has_vertex_arrays (GdkGLContext *self)
{
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
switch (priv->api)
{
case GDK_GL_API_GL:
return TRUE;
case GDK_GL_API_GLES:
return gdk_gl_version_get_major (&priv->gl_version) >= 3;
default:
g_return_val_if_reached (FALSE);
}
}
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
@@ -1995,201 +1942,3 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
g_assert (the_gl_backend_type == backend_type);
}
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);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLint attribs[64];
int i;
EGLImage image;
guint texture_id;
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), 0);
g_return_val_if_fail (width > 0, 0);
g_return_val_if_fail (height > 0, 0);
g_return_val_if_fail (1 <= dmabuf->n_planes && dmabuf->n_planes <= 4, 0);
g_return_val_if_fail (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES, 0);
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_import)
return 0;
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;
attribs[i++] = EGL_TRUE;
attribs[i++] = EGL_WIDTH;
attribs[i++] = width;
attribs[i++] = EGL_HEIGHT;
attribs[i++] = height;
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[i++] = dmabuf->fourcc;
#define ADD_PLANE(plane) \
{ \
if (dmabuf->modifier != DRM_FORMAT_MOD_INVALID) \
{ \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \
attribs[i++] = dmabuf->modifier & 0xFFFFFFFF; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \
attribs[i++] = dmabuf->modifier >> 32; \
} \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \
attribs[i++] = dmabuf->planes[plane].fd; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \
attribs[i++] = dmabuf->planes[plane].stride; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \
attribs[i++] = dmabuf->planes[plane].offset; \
}
ADD_PLANE (0);
if (dmabuf->n_planes > 1) ADD_PLANE (1);
if (dmabuf->n_planes > 2) ADD_PLANE (2);
if (dmabuf->n_planes > 3) ADD_PLANE (3);
attribs[i++] = EGL_NONE;
image = eglCreateImageKHR (egl_display,
EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT,
(EGLClientBuffer)NULL,
attribs);
if (image == EGL_NO_IMAGE)
{
GDK_DEBUG (DMABUF, "Creating EGLImage for dmabuf failed: %#x", eglGetError ());
return 0;
}
glGenTextures (1, &texture_id);
glBindTexture (target, texture_id);
glEGLImageTargetTexture2DOES (target, image);
glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
eglDestroyImageKHR (egl_display, image);
return texture_id;
#else
return 0;
#endif
}
gboolean
gdk_gl_context_export_dmabuf (GdkGLContext *self,
unsigned int texture_id,
GdkDmabuf *dmabuf)
{
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
GdkDisplay *display = gdk_gl_context_get_display (self);
EGLDisplay egl_display = gdk_display_get_egl_display (display);
EGLContext egl_context = priv->egl_context;
EGLint attribs[10];
EGLImage image;
gboolean result = FALSE;
int i;
int fourcc;
int n_planes;
guint64 modifier;
int fds[GDK_DMABUF_MAX_PLANES];
int strides[GDK_DMABUF_MAX_PLANES];
int offsets[GDK_DMABUF_MAX_PLANES];
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
g_return_val_if_fail (texture_id > 0, FALSE);
g_return_val_if_fail (dmabuf != NULL, FALSE);
if (egl_display == EGL_NO_DISPLAY || !display->have_egl_dma_buf_export)
return 0;
GDK_DEBUG (DMABUF, "Exporting GL texture to dmabuf");
i = 0;
attribs[i++] = EGL_IMAGE_PRESERVED_KHR;
attribs[i++] = EGL_TRUE;
attribs[i++] = EGL_NONE;
image = eglCreateImageKHR (egl_display,
egl_context,
EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer)GUINT_TO_POINTER (texture_id),
attribs);
if (image == EGL_NO_IMAGE)
{
GDK_DEBUG (DMABUF, "Creating EGLImage for dmabuf failed: %#x", eglGetError ());
return FALSE;
}
if (!eglExportDMABUFImageQueryMESA (egl_display,
image,
&fourcc,
&n_planes,
&modifier))
{
GDK_DEBUG (DMABUF, "eglExportDMABUFImageQueryMESA failed: %#x", eglGetError ());
goto out;
}
if (n_planes < 1 || n_planes > GDK_DMABUF_MAX_PLANES)
{
GDK_DEBUG (DMABUF, "dmabufs with %d planes are not supported", n_planes);
goto out;
}
if (!eglExportDMABUFImageMESA (egl_display,
image,
fds,
strides,
offsets))
{
g_warning ("eglExportDMABUFImage failed: %#x", eglGetError ());
goto out;
}
for (i = 0; i < n_planes; i++)
{
if (fds[i] == -1)
{
g_warning ("dmabuf plane %d has no file descriptor", i);
goto out;
}
}
dmabuf->fourcc = (guint32)fourcc;
dmabuf->modifier = modifier;
dmabuf->n_planes = n_planes;
for (i = 0; i < n_planes; i++)
{
dmabuf->planes[i].fd = fds[i];
dmabuf->planes[i].stride = (int) strides[i];
dmabuf->planes[i].offset = (int) offsets[i];
}
GDK_DEBUG (DMABUF,
"Exported GL texture to dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %d)",
(char *)&fourcc, modifier, n_planes);
result = TRUE;
out:
eglDestroyImageKHR (egl_display, image);
return result;
#else
return FALSE;
#endif
}
+1 -17
View File
@@ -23,7 +23,6 @@
#include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h"
#include "gdkglversionprivate.h"
#include "gdkdmabufprivate.h"
G_BEGIN_DECLS
@@ -158,22 +157,7 @@ gboolean gdk_gl_context_has_vertex_half_float (GdkGLContext
gboolean gdk_gl_context_has_sync (GdkGLContext *self) G_GNUC_PURE;
gboolean gdk_gl_context_has_bgra (GdkGLContext *self) G_GNUC_PURE;
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,
int target);
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
unsigned int texture_id,
GdkDmabuf *dmabuf);
G_END_DECLS
+9 -4
View File
@@ -141,7 +141,9 @@ struct _Download
};
static gboolean
gdk_gl_texture_find_format (GdkGLContext *context,
gdk_gl_texture_find_format (gboolean use_es,
guint gl_major,
guint gl_minor,
GdkMemoryAlpha alpha,
GLint gl_format,
GLint gl_type,
@@ -157,7 +159,7 @@ gdk_gl_texture_find_format (GdkGLContext *context,
if (gdk_memory_format_alpha (format) != alpha)
continue;
if (!gdk_memory_format_gl_format (format, context, &q_internal_format, &q_format, &q_type, q_swizzle))
if (!gdk_memory_format_gl_format (format, use_es, gl_major, gl_minor, &q_internal_format, &q_format, &q_type, q_swizzle))
continue;
if (q_format != gl_format || q_type != gl_type)
@@ -181,13 +183,16 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type;
GLint gl_swizzle[4];
int major, minor;
format = gdk_texture_get_format (texture),
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format);
gdk_gl_context_get_version (context, &major, &minor);
if (!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (format,
context,
FALSE,
major, minor,
&gl_internal_format,
&gl_format, &gl_type, gl_swizzle))
{
@@ -238,7 +243,7 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
{
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type);
if (!gdk_gl_texture_find_format (context, gdk_memory_format_alpha (format), gl_read_format, gl_read_type, &actual_format))
if (!gdk_gl_texture_find_format (TRUE, major, minor, gdk_memory_format_alpha (format), gl_read_format, gl_read_type, &actual_format))
{
gl_read_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE;
+6 -72
View File
@@ -20,7 +20,6 @@
#include "config.h"
#include "gdkmemoryformatprivate.h"
#include "gdkglcontextprivate.h"
#include "gsk/gl/fp16private.h"
@@ -94,17 +93,10 @@ name ## _from_float (guchar *dest_data, \
TYPED_FUNCS (b8g8r8a8_premultiplied, guchar, 2, 1, 0, 3, 4, 255)
TYPED_FUNCS (a8r8g8b8_premultiplied, guchar, 1, 2, 3, 0, 4, 255)
TYPED_FUNCS (r8g8b8a8_premultiplied, guchar, 0, 1, 2, 3, 4, 255)
TYPED_FUNCS (a8b8g8r8_premultiplied, guchar, 3, 2, 1, 0, 4, 255)
TYPED_FUNCS (b8g8r8a8, guchar, 2, 1, 0, 3, 4, 255)
TYPED_FUNCS (a8r8g8b8, guchar, 1, 2, 3, 0, 4, 255)
TYPED_FUNCS (r8g8b8a8, guchar, 0, 1, 2, 3, 4, 255)
TYPED_FUNCS (a8b8g8r8, guchar, 3, 2, 1, 0, 4, 255)
TYPED_FUNCS (r8g8b8x8, guchar, 0, 1, 2, -1, 4, 255)
TYPED_FUNCS (x8r8g8b8, guchar, 1, 2, 3, -1, 4, 255)
TYPED_FUNCS (b8g8r8x8, guchar, 2, 1, 0, -1, 4, 255)
TYPED_FUNCS (x8b8g8r8, guchar, 3, 2, 1, -1, 4, 255)
TYPED_FUNCS (r8g8b8, guchar, 0, 1, 2, -1, 3, 255)
TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255)
TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535)
@@ -360,7 +352,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 0, 0 },
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_premultiplied_to_float,
b8g8r8a8_premultiplied_from_float,
@@ -385,22 +377,12 @@ static const GdkMemoryFormatDescription memory_formats[] = {
r8g8b8a8_premultiplied_to_float,
r8g8b8a8_premultiplied_from_float,
},
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
a8b8g8r8_premultiplied_to_float,
a8b8g8r8_premultiplied_from_float,
},
[GDK_MEMORY_B8G8R8A8] = {
GDK_MEMORY_ALPHA_STRAIGHT,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, 0, 0 },
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_to_float,
b8g8r8a8_from_float,
@@ -435,46 +417,6 @@ static const GdkMemoryFormatDescription memory_formats[] = {
a8b8g8r8_to_float,
a8b8g8r8_from_float,
},
[GDK_MEMORY_B8G8R8X8] = {
GDK_MEMORY_ALPHA_OPAQUE,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
b8g8r8x8_to_float,
b8g8r8x8_from_float,
},
[GDK_MEMORY_X8R8G8B8] = {
GDK_MEMORY_ALPHA_OPAQUE,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_BGRA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
x8r8g8b8_to_float,
x8r8g8b8_from_float,
},
[GDK_MEMORY_R8G8B8X8] = {
GDK_MEMORY_ALPHA_OPAQUE,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ 0, 0, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
r8g8b8x8_to_float,
r8g8b8x8_from_float,
},
[GDK_MEMORY_X8B8G8R8] = {
GDK_MEMORY_ALPHA_OPAQUE,
4,
G_ALIGNOF (guchar),
GDK_MEMORY_U8,
{ G_MAXUINT, G_MAXUINT, G_MAXUINT, G_MAXUINT },
{ GL_RGBA8, GL_RGBA, GDK_GL_UNSIGNED_BYTE_FLIPPED, { GL_RED, GL_GREEN, GL_BLUE, GL_ONE } },
x8b8g8r8_to_float,
x8b8g8r8_from_float,
},
[GDK_MEMORY_R8G8B8] = {
GDK_MEMORY_ALPHA_OPAQUE,
3,
@@ -569,7 +511,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED,
16,
G_ALIGNOF (float),
GDK_MEMORY_FLOAT32,
TRUE,
{ 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r32g32b32a32_float_to_float,
@@ -791,19 +733,14 @@ gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
gboolean
gdk_memory_format_gl_format (GdkMemoryFormat format,
GdkGLContext *context,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type,
GLint out_swizzle[4])
{
int gl_major;
int gl_minor;
gboolean gles;
gdk_gl_context_get_version (context, &gl_major, &gl_minor);
gles = gdk_gl_context_get_use_es (context);
*out_internal_format = memory_formats[format].gl.internal_format;
*out_format = memory_formats[format].gl.format;
*out_type = memory_formats[format].gl.type;
@@ -815,9 +752,6 @@ gdk_memory_format_gl_format (GdkMemoryFormat format,
(memory_formats[format].min_gl_version.gles_major == gl_major &&
memory_formats[format].min_gl_version.gles_minor > gl_minor))
return FALSE;
if (*out_format == GL_BGRA && !gdk_gl_context_has_bgra (context))
return FALSE;
}
else
{
+3 -2
View File
@@ -20,7 +20,6 @@
#pragma once
#include "gdkenums.h"
#include "gdktypes.h"
#include <epoxy/gl.h>
@@ -47,7 +46,9 @@ GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth
GdkMemoryDepth depth2) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
GdkGLContext *context,
gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format,
guint *out_format,
guint *out_type,
+1 -1
View File
@@ -40,7 +40,7 @@ struct _GdkIOPipe
GCond cond;
guchar *buffer;
gsize size;
guint state : 2; /* GdkIOPipeState */
GdkIOPipeState state : 2;
guint input_closed : 1;
guint output_closed : 1;
};
-44
View File
@@ -493,12 +493,6 @@ gdk_surface_real_get_scale (GdkSurface *surface)
return 1.0;
}
static GdkSubsurface *
gdk_surface_real_create_subsurface (GdkSurface *surface)
{
return NULL;
}
static void
gdk_surface_constructed (GObject *object)
{
@@ -521,7 +515,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
klass->beep = gdk_surface_real_beep;
klass->get_scale = gdk_surface_real_get_scale;
klass->create_subsurface = gdk_surface_real_create_subsurface;
/**
* GdkSurface:cursor: (attributes org.gtk.Property.get=gdk_surface_get_cursor org.gtk.Property.set=gdk_surface_set_cursor)
@@ -3061,40 +3054,3 @@ gdk_surface_leave_monitor (GdkSurface *surface,
{
g_signal_emit (surface, signals[LEAVE_MONITOR], 0, monitor);
}
GdkSubsurface *
gdk_surface_create_subsurface (GdkSurface *surface)
{
return GDK_SURFACE_GET_CLASS (surface)->create_subsurface (surface);
}
void
gdk_subsurface_destroy (GdkSubsurface *subsurface)
{
subsurface->class->destroy (subsurface);
}
void
gdk_subsurface_attach (GdkSubsurface *subsurface,
GdkTexture *texture,
const graphene_rect_t *bounds)
{
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);
}
-35
View File
@@ -23,14 +23,9 @@
#include "gdkenumtypes.h"
#include "gdksurface.h"
#include "gdktoplevel.h"
#include <graphene.h>
G_BEGIN_DECLS
typedef struct _GdkSubsurface GdkSubsurface;
typedef struct _GskRenderNode GskRenderNode;
struct _GdkSurface
{
GObject parent_instance;
@@ -151,9 +146,6 @@ struct _GdkSurfaceClass
cairo_region_t *region);
void (* request_layout) (GdkSurface *surface);
gboolean (* compute_size) (GdkSurface *surface);
GdkSubsurface *
(* create_subsurface) (GdkSurface *surface);
};
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
@@ -342,34 +334,7 @@ void gdk_surface_request_motion (GdkSurface *surface);
gboolean gdk_surface_supports_edge_constraints (GdkSurface *surface);
GdkSubsurface * gdk_surface_create_subsurface (GdkSurface *surface);
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
@@ -96,8 +96,6 @@ typedef struct _GdkCairoContext GdkCairoContext;
typedef struct _GdkGLContext GdkGLContext;
typedef struct _GdkVulkanContext GdkVulkanContext;
typedef struct _GdkDmabufFormats GdkDmabufFormats;
/*
* GDK_DECLARE_INTERNAL_TYPE:
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
-7
View File
@@ -1475,13 +1475,6 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
gboolean validate = FALSE, have_debug_report = FALSE;
VkResult res;
if (gdk_display_get_debug_flags (display) & GDK_DEBUG_VULKAN_DISABLE)
{
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
_("Vulkan support disabled via GDK_DEBUG"));
return FALSE;
}
if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)
{
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
-5
View File
@@ -329,7 +329,6 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
@@ -341,10 +340,6 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8B8G8R8:
format = GDK_MEMORY_R8G8B8;
png_format = PNG_COLOR_TYPE_RGB;
depth = 8;
-5
View File
@@ -236,17 +236,12 @@ static const FormatData format_data[] = {
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = { GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8R8G8B8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8A8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_A8B8G8R8] = { GDK_MEMORY_R8G8B8A8, 8, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R8G8B8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_X8R8G8B8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_B8G8R8X8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_X8B8G8R8] = { GDK_MEMORY_R8G8B8, 8, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16] = { GDK_MEMORY_R16G16B16, 16, 3, SAMPLEFORMAT_UINT, 0, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = { GDK_MEMORY_R16G16B16A16_PREMULTIPLIED, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_ASSOCALPHA, PHOTOMETRIC_RGB },
[GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },
-6
View File
@@ -17,10 +17,6 @@ gdk_public_sources = files([
'gdkdevicetool.c',
'gdkdisplay.c',
'gdkdisplaymanager.c',
'gdkdmabuf.c',
'gdkdmabufegl.c',
'gdkdmabufformats.c',
'gdkdmabufformatsbuilder.c',
'gdkdmabuftexture.c',
'gdkdmabuftexturebuilder.c',
'gdkdrag.c',
@@ -85,7 +81,6 @@ gdk_public_headers = files([
'gdkdisplay.h',
'gdkdisplaymanager.h',
'gdkdrag.h',
'gdkdmabufformats.h',
'gdkdmabuftexture.h',
'gdkdmabuftexturebuilder.h',
'gdkdragsurfacesize.h',
@@ -217,7 +212,6 @@ gdk_deps = [
platform_gio_dep,
pangocairo_dep,
vulkan_dep,
dmabuf_dep,
png_dep,
tiff_dep,
jpeg_dep,
+29 -2
View File
@@ -269,12 +269,39 @@ postpone_on_globals_closure (GdkWaylandDisplay *display_wayland,
g_list_append (display_wayland->on_has_globals_closures, closure);
}
#ifdef G_ENABLE_DEBUG
static const char *
get_format_name (uint32_t format,
char name[10])
{
if (format == 0)
g_strlcpy (name, "ARGB8888", 10);
else if (format == 1)
g_strlcpy (name, "XRGB8888", 10);
else
g_snprintf (name, 10, "4cc %c%c%c%c",
(char) (format & 0xff),
(char) ((format >> 8) & 0xff),
(char) ((format >> 16) & 0xff),
(char) ((format >> 24) & 0xff));
return name;
}
#endif
static void
wl_shm_format (void *data,
struct wl_shm *wl_shm,
uint32_t format)
{
GDK_DEBUG (MISC, "supported shm pixel format %.4s (0x%X)", (char *) &format, format);
#ifdef G_ENABLE_DEBUG
char buf[10];
#endif
GDK_DEBUG (MISC, "supported shm pixel format %s (0x%X)",
get_format_name (format, buf), (guint) format);
}
static const struct wl_shm_listener wl_shm_listener = {
@@ -344,7 +371,7 @@ linux_dmabuf_tranche_formats (void *data,
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);
GDK_DEBUG (MISC, " %c%c%c%c:%#lx", f & 0xff, (f >> 8) & 0xff, (f >> 16) & 0xff, (f >> 24) & 0xff, m);
}
}
+1 -1
View File
@@ -75,7 +75,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface, dx, dy);
/* We should do this when setting up the EGLSurface, but we don't make_current then */
/* We should do ths when setting up the EGLSurface, but we don't make_current then */
eglSwapInterval (gdk_display_get_egl_display (gdk_draw_context_get_display (draw_context)), 0);
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
+1 -1
View File
@@ -35,7 +35,6 @@
#include <gdk/wayland/gdkdisplay-wayland.h>
#include <gdk/wayland/gdkseat-wayland.h>
#include <gsk/gsk.h>
#include <xkbcommon/xkbcommon.h>
@@ -223,3 +222,4 @@ void gdk_wayland_surface_update_scale (GdkSurface *surface);
GdkModifierType gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap,
guint32 mods);
-2
View File
@@ -86,8 +86,6 @@ struct _GdkWaylandSurface
uint32_t last_configure_serial;
int state_freeze_count;
GPtrArray *subsurfaces;
};
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
+1 -256
View File
@@ -33,11 +33,9 @@
#include "gdksurfaceprivate.h"
#include "gdktoplevelprivate.h"
#include "gdkdevice-wayland-private.h"
#include "gdkdmabuftextureprivate.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>
@@ -50,7 +48,6 @@
#include "gdksurface-wayland-private.h"
#include "gdktoplevel-wayland-private.h"
/**
* GdkWaylandSurface:
*
@@ -155,17 +152,13 @@ wl_region_from_cairo_region (GdkWaylandDisplay *display,
}
/* }}} */
/* {{{ Surface implementation */
static void gdk_wayland_subsurface_destroy (GdkSubsurface *sub);
/* {{{ Surface implementation */
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
@@ -559,7 +552,6 @@ 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);
}
@@ -1143,17 +1135,6 @@ 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)
@@ -1170,7 +1151,6 @@ 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);
@@ -1227,8 +1207,6 @@ gdk_wayland_surface_default_hide_surface (GdkWaylandSurface *surface)
{
}
static GdkSubsurface *gdk_wayland_surface_create_subsurface (GdkSurface *surface);
static void
gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
{
@@ -1252,7 +1230,6 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
surface_class->get_scale = gdk_wayland_surface_get_scale;
surface_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
surface_class->request_layout = gdk_wayland_surface_request_layout;
surface_class->create_subsurface = gdk_wayland_surface_create_subsurface;
klass->handle_configure = gdk_wayland_surface_default_handle_configure;
klass->handle_frame = gdk_wayland_surface_default_handle_frame;
@@ -1328,236 +1305,4 @@ 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);
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
GdkWaylandSubsurface *sub;
struct wl_region *wl_region;
if (display->viewporter == NULL)
{
GDK_DEBUG (DMABUF, "Can't use subsurfaces without viewporter");
return NULL;
}
sub = g_new0 (GdkWaylandSubsurface, 1);
sub->subsurface.class = &subsurface_class;
sub->parent = impl;
g_ptr_array_add (sub->parent->subsurfaces, sub);
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);
GDK_DEBUG (DMABUF, "Subsurface created");
return (GdkSubsurface *) sub;
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */
-4
View File
@@ -4442,10 +4442,6 @@ _gdk_win32_surface_request_layout (GdkSurface *surface)
{
_gdk_win32_get_window_rect (surface, &rect);
/* Keep current position if rect is invalid (i.e. queried in bad context) */
if (rect.right == rect.left || rect.bottom == rect.top)
return;
impl->next_layout.configured_width = (rect.right - rect.left + scale - 1) / scale;
impl->next_layout.configured_height = (rect.bottom - rect.top + scale - 1) / scale;
+1 -2
View File
@@ -76,8 +76,7 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
g_assert (self != NULL);
g_assert (target == GL_TEXTURE_1D ||
target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D ||
target == GL_TEXTURE_EXTERNAL_OES);
target == GL_TEXTURE_3D);
g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16);
g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures));
-3
View File
@@ -29,9 +29,6 @@ typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
typedef struct _GskGLBindTexture GskGLBindTexture;
#define GSK_GL_N_FILTERS 3
#define SAMPLER_EXTERNAL 9
G_STATIC_ASSERT (SAMPLER_EXTERNAL >= GSK_GL_N_FILTERS * GSK_GL_N_FILTERS);
static inline guint
filter_index (GLint filter)
+44 -43
View File
@@ -282,10 +282,7 @@ snapshot_attachments (const GskGLAttachmentState *state,
{
bind[count].id = state->textures[i].id;
bind[count].texture = state->textures[i].texture;
if (state->textures[i].target == GL_TEXTURE_EXTERNAL_OES)
bind[count].sampler = SAMPLER_EXTERNAL;
else
bind[count].sampler = state->textures[i].sampler;
bind[count].sampler = state->textures[i].sampler;
count++;
}
}
@@ -1073,7 +1070,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation (GL_FUNC_ADD);
if (gdk_gl_context_has_vertex_arrays (self->context))
if (!gdk_gl_context_get_use_es (self->context))
{
glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id);
@@ -1193,23 +1190,12 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
s->sync = NULL;
}
if (bind->sampler == SAMPLER_EXTERNAL)
glBindTexture (GL_TEXTURE_EXTERNAL_OES, bind->id);
else
glBindTexture (GL_TEXTURE_2D, bind->id);
glBindTexture (GL_TEXTURE_2D, bind->id);
textures[bind->texture] = bind->id;
if (!self->has_samplers)
{
if (bind->sampler == SAMPLER_EXTERNAL)
{
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
}
}
@@ -1219,16 +1205,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBindSampler (bind->texture, self->samplers[bind->sampler]);
else
{
if (bind->sampler == SAMPLER_EXTERNAL)
{
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_from_index (bind->sampler / GSK_GL_N_FILTERS));
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_from_index (bind->sampler % GSK_GL_N_FILTERS));
}
samplers[bind->texture] = bind->sampler;
}
@@ -1279,7 +1257,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
}
glDeleteBuffers (1, &vbo_id);
if (gdk_gl_context_has_vertex_arrays (self->context))
if (!gdk_gl_context_get_use_es (self->context))
glDeleteVertexArrays (1, &vao_id);
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds);
@@ -1346,7 +1324,7 @@ gsk_gl_command_queue_end_frame (GskGLCommandQueue *self)
if (self->attachments->textures[i].id != 0)
{
glActiveTexture (GL_TEXTURE0 + i);
glBindTexture (self->attachments->textures[i].target, 0);
glBindTexture (GL_TEXTURE_2D, 0);
self->attachments->textures[i].id = 0;
self->attachments->textures[i].changed = FALSE;
@@ -1423,7 +1401,7 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_id);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@@ -1451,9 +1429,8 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
}
/* Restore the previous texture if it was set */
if (self->attachments->textures[0].id != 0 &&
self->attachments->textures[0].target == GL_TEXTURE_2D)
glBindTexture (self->attachments->textures[0].target, self->attachments->textures[0].id);
if (self->attachments->textures[0].id != 0)
glBindTexture (GL_TEXTURE_2D, self->attachments->textures[0].id);
return (int)texture_id;
}
@@ -1473,7 +1450,9 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
static GdkMemoryFormat
memory_format_gl_format (GdkMemoryFormat data_format,
GdkGLContext *context,
gboolean use_es,
guint major,
guint minor,
guint *gl_internalformat,
guint *gl_format,
guint *gl_type,
@@ -1483,7 +1462,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
/* First, try the format itself */
if (gdk_memory_format_gl_format (data_format,
context,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
@@ -1499,7 +1480,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
case GDK_MEMORY_FLOAT16:
data_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
context,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
@@ -1510,7 +1493,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
case GDK_MEMORY_U16:
data_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
context,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
@@ -1532,7 +1517,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
{
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format,
context,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
@@ -1543,7 +1530,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
/* If all else fails, pick the one format that's always supported */
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
context,
use_es,
major,
minor,
gl_internalformat,
gl_format,
gl_type,
@@ -1572,13 +1561,19 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
GLenum gl_type;
GLint gl_swizzle[4];
gsize bpp;
gboolean use_es;
int major, minor;
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
data_format = gdk_texture_get_format (texture);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
data_format = memory_format_gl_format (data_format,
self->context,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type,
@@ -1643,7 +1638,9 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
GLenum gl_format;
GLenum gl_type;
GLint gl_swizzle[4];
gboolean use_es;
int texture_id;
int major, minor;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self));
@@ -1676,9 +1673,13 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
glBindTexture (GL_TEXTURE_2D, texture_id);
/* Initialize the texture */
use_es = gdk_gl_context_get_use_es (self->context);
gdk_gl_context_get_version (self->context, &major, &minor);
data_format = gdk_texture_get_format (chunks[0].texture);
data_format = memory_format_gl_format (data_format,
self->context,
use_es,
major,
minor,
&gl_internalformat,
&gl_format,
&gl_type,
-6
View File
@@ -54,7 +54,6 @@ typedef struct _GskGLCommandBind
*/
guint texture : 4;
/* the sampler to use. We set sampler to 15 to indicate external textures */
guint sampler : 4;
/* The identifier for the texture created with glGenTextures(). */
@@ -235,13 +234,8 @@ struct _GskGLCommandQueue
/* Array of samplers that we use for mag/min filter handling. It is indexed
* by the sampler_index() function.
*
* Note that when samplers are not supported (hello GLES), we fall back to
* setting the texture filter, but that needs to be done for every texture.
*
* Also note that we don't use all of these samplers since some combinations
* are invalid. An index of SAMPLER_EXTERNAL is used to indicate an external
* texture, which needs special sampler treatment.
*/
GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];
+7 -15
View File
@@ -54,7 +54,6 @@ struct _GskGLCompiler
guint gl3 : 1;
guint gles : 1;
guint gles3 : 1;
guint legacy : 1;
guint debug_shaders : 1;
};
@@ -135,10 +134,7 @@ gsk_gl_compiler_new (GskGLDriver *driver,
gdk_gl_context_get_version (context, &maj, &min);
if (maj >= 3)
{
self->glsl_version = SHADER_VERSION_GLES3;
self->gles3 = TRUE;
}
self->glsl_version = SHADER_VERSION_GLES3;
else
{
self->glsl_version = SHADER_VERSION_GLES;
@@ -547,7 +543,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
const char *legacy = "";
const char *gl3 = "";
const char *gles = "";
const char *gles3 = "";
int program_id;
int vertex_id;
int fragment_id;
@@ -574,17 +569,15 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
if (self->gles)
gles = "#define GSK_GLES 1\n";
if (self->gles3)
gles3 = "#define GSK_GLES3 1\n";
if (self->gl3)
gl3 = "#define GSK_GL3 1\n";
vertex_id = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vertex_id,
11,
10,
(const char *[]) {
version, debug, legacy, gl3, gles, gles3, clip,
version, debug, legacy, gl3, gles,
clip,
get_shader_string (self->all_preamble),
get_shader_string (self->vertex_preamble),
get_shader_string (self->vertex_source),
@@ -596,7 +589,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
strlen (legacy),
strlen (gl3),
strlen (gles),
strlen (gles3),
strlen (clip),
g_bytes_get_size (self->all_preamble),
g_bytes_get_size (self->vertex_preamble),
@@ -615,9 +607,10 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fragment_id,
11,
10,
(const char *[]) {
version, debug, legacy, gl3, gles, gles3, clip,
version, debug, legacy, gl3, gles,
clip,
get_shader_string (self->all_preamble),
get_shader_string (self->fragment_preamble),
get_shader_string (self->fragment_source),
@@ -629,7 +622,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
strlen (legacy),
strlen (gl3),
strlen (gles),
strlen (gles3),
strlen (clip),
g_bytes_get_size (self->all_preamble),
g_bytes_get_size (self->fragment_preamble),
+194 -70
View File
@@ -42,10 +42,11 @@
#include <gdk/gdkmemorytextureprivate.h>
#include <gdk/gdkprofilerprivate.h>
#include <gdk/gdktextureprivate.h>
#include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkdmabuftextureprivate.h>
#include <gdk/gdkmemoryformatprivate.h>
#include <epoxy/egl.h>
#include <drm/drm_fourcc.h>
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
@@ -713,7 +714,96 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
}
}
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
static int
import_dmabuf_planes (GskGLDriver *self,
int width,
int height,
unsigned int fourcc,
guint64 modifier,
unsigned int n_planes,
int *fds,
unsigned int *strides,
unsigned int *offsets)
{
GdkGLContext *context = self->command_queue->context;
GdkDisplay *display = gdk_gl_context_get_display (context);
EGLDisplay egl_display;
EGLint attribs[64];
EGLImage image;
guint texture_id;
int i;
g_assert (1 <= n_planes && n_planes <= 4);
GSK_DEBUG (OPENGL,
"Importing dma-buf into GL via EGLImage. Format %c%c%c%c:%#lx",
fourcc & 0xff, (fourcc >> 8) & 0xff, (fourcc >> 16) & 0xff, (fourcc >> 24) & 0xff, modifier);
egl_display = gdk_display_get_egl_display (display);
if (egl_display == NULL)
{
g_warning ("Can't import dmabufs when not using EGL");
return 0;
}
i = 0;
attribs[i++] = EGL_WIDTH;
attribs[i++] = width;
attribs[i++] = EGL_HEIGHT;
attribs[i++] = height;
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
attribs[i++] = fourcc;
#define ADD_PLANE(plane) \
{ \
if (modifier != DRM_FORMAT_MOD_INVALID) \
{ \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_MODIFIER_LO_EXT; \
attribs[i++] = modifier & 0xFFFFFFFF; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ## _MODIFIER_HI_EXT; \
attribs[i++] = modifier >> 32; \
} \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_FD_EXT; \
attribs[i++] = fds[plane]; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_PITCH_EXT; \
attribs[i++] = strides[plane]; \
attribs[i++] = EGL_DMA_BUF_PLANE## plane ##_OFFSET_EXT; \
attribs[i++] = offsets[plane]; \
}
ADD_PLANE (0);
if (n_planes > 1) ADD_PLANE (1);
if (n_planes > 2) ADD_PLANE (2);
if (n_planes > 3) ADD_PLANE (3);
attribs[i++] = EGL_NONE;
image = eglCreateImageKHR (egl_display,
EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT,
(EGLClientBuffer)NULL,
attribs);
if (image == EGL_NO_IMAGE)
{
g_warning ("Failed to create EGL image: %#x\n", eglGetError ());
return 0;
}
gdk_gl_context_make_current (context);
glGenTextures (1, &texture_id);
glBindTexture (GL_TEXTURE_2D, texture_id);
glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, image);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
eglDestroyImageKHR (egl_display, image);
return texture_id;
}
static void
set_viewport_for_size (GskGLDriver *self,
GskGLProgram *program,
@@ -788,105 +878,142 @@ draw_rect (GskGLCommandQueue *command_queue,
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
}
typedef struct _TextureFormatInfo TextureFormatInfo;
struct _TextureFormatInfo
{
int n_planes;
unsigned int subformats[3];
int plane_indices[3];
int hsub[3];
int vsub[3];
int uniforms[3];
};
static TextureFormatInfo texture_format_info[] = {
{ .n_planes = 2,
.subformats = { DRM_FORMAT_GR88, DRM_FORMAT_ARGB8888 },
.plane_indices = { 0, 0 },
.hsub = { 1, 2 },
.vsub = { 1, 1 },
.uniforms = { UNIFORM_SHARED_SOURCE, UNIFORM_YUYV_SOURCE2 },
},
{ .n_planes = 2,
.subformats = { DRM_FORMAT_R8, DRM_FORMAT_GR88 },
.plane_indices = { 0, 1 },
.hsub = { 1, 2 },
.vsub = { 1, 2 },
.uniforms = { UNIFORM_SHARED_SOURCE, UNIFORM_NV12_SOURCE2 },
},
{ .n_planes = 2,
.subformats = { DRM_FORMAT_R16, DRM_FORMAT_GR1616 },
.plane_indices = { 0, 1 },
.hsub = { 1, 2 },
.vsub = { 1, 2 },
.uniforms = { UNIFORM_SHARED_SOURCE, UNIFORM_NV12_SOURCE2 },
},
{ .n_planes = 3,
.subformats = { DRM_FORMAT_R8, DRM_FORMAT_R8, DRM_FORMAT_R8 },
.plane_indices = { 0, 1, 2 },
.hsub = { 1, 2, 2 },
.vsub = { 1, 2, 2 },
.uniforms = { UNIFORM_SHARED_SOURCE, UNIFORM_YUV420_SOURCE2, UNIFORM_YUV420_SOURCE3 },
},
};
static unsigned int release_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target,
gboolean release_texture,
gboolean cache_texture);
static guint
static unsigned int
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;
int width, height;
guint64 modifier;
TextureFormatInfo *info;
GskGLProgram *program;
GskGLRenderTarget *render_target;
guint prev_fbo;
gdk_gl_context_make_current (context);
width = gdk_texture_get_width (GDK_TEXTURE (texture));
height = gdk_texture_get_height (GDK_TEXTURE (texture));
modifier = gdk_dmabuf_texture_get_modifier (texture);
if (width > max_texture_size || height > max_texture_size)
if (gdk_dmabuf_texture_get_fourcc (texture) == DRM_FORMAT_YUYV)
{
GDK_DEBUG (DMABUF, "Can't import dmabuf bigger than MAX_TEXTURE_SIZE (%d)", max_texture_size);
return 0;
info = &texture_format_info[0];
program = self->yuyv;
}
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
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))
else if (gdk_dmabuf_texture_get_fourcc (texture) == DRM_FORMAT_NV12)
{
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_2D texture");
return gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
GL_TEXTURE_2D);
info = &texture_format_info[1];
program = self->nv12;
}
if (!gdk_gl_context_get_use_es (context))
else if (gdk_dmabuf_texture_get_fourcc (texture) == DRM_FORMAT_P010)
{
GDK_DEBUG (DMABUF, "Can't import external_only dmabuf outside of GLES");
return 0;
info = &texture_format_info[2];
program = self->nv12;
}
else if (gdk_dmabuf_texture_get_fourcc (texture) == DRM_FORMAT_YUV420)
{
info = &texture_format_info[3];
program = self->yuv420;
}
else
{
return import_dmabuf_planes (self,
gdk_texture_get_width (GDK_TEXTURE (texture)),
gdk_texture_get_height (GDK_TEXTURE (texture)),
gdk_dmabuf_texture_get_fourcc (texture),
gdk_dmabuf_texture_get_modifier (texture),
gdk_dmabuf_texture_get_n_planes (texture),
gdk_dmabuf_texture_get_fds (texture),
gdk_dmabuf_texture_get_strides (texture),
gdk_dmabuf_texture_get_offsets (texture));
}
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_EXTERNAL_OES texture");
texture_id = gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
GL_TEXTURE_EXTERNAL_OES);
if (texture_id == 0)
return 0;
gsk_gl_driver_autorelease_texture (self, texture_id);
program = self->external;
gsk_gl_driver_create_render_target (self, width, height, GL_RGBA8, &render_target);
prev_fbo = gsk_gl_command_queue_bind_framebuffer (self->command_queue, render_target->framebuffer_id);
gsk_gl_command_queue_clear (self->command_queue, 0, &GRAPHENE_RECT_INIT (0, 0, width, height));
if (gsk_gl_command_queue_begin_draw (self->command_queue, program->program_info, width, height))
gsk_gl_command_queue_begin_draw (self->command_queue, program->program_info, width, height);
set_projection_for_size (self, program, width, height);
set_viewport_for_size (self, program, width, height);
reset_modelview (self, program);
for (int i = 0; i < info->n_planes; i++)
{
set_projection_for_size (self, program, width, height);
set_viewport_for_size (self, program, width, height);
reset_modelview (self, program);
int plane = info->plane_indices[i];
int texture_id = import_dmabuf_planes (self,
width / info->hsub[i],
height / info->vsub[i],
info->subformats[i],
modifier,
1,
gdk_dmabuf_texture_get_fds (texture) + plane,
gdk_dmabuf_texture_get_strides (texture) + plane,
gdk_dmabuf_texture_get_offsets (texture) + plane);
gsk_gl_program_set_uniform_texture (program,
UNIFORM_EXTERNAL_SOURCE, 0,
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
info->uniforms[i], 0,
GL_TEXTURE_2D, GL_TEXTURE0 + i, texture_id);
draw_rect (self->command_queue, 0, 0, width, height);
gsk_gl_command_queue_end_draw (self->command_queue);
gsk_gl_driver_autorelease_texture (self, texture_id);
}
draw_rect (self->command_queue, 0, 0, width, height);
gsk_gl_command_queue_end_draw (self->command_queue);
gsk_gl_command_queue_bind_framebuffer (self->command_queue, prev_fbo);
return release_render_target (self, render_target, FALSE, FALSE);
}
#else
static guint
gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
GdkDmabufTexture *texture)
{
return 0;
}
#endif /* HAVE_DMABUF && HAVE_EGL */
/**
* gsk_gl_driver_load_texture:
* @self: a `GdkTexture`
@@ -976,9 +1103,8 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
t = gsk_gl_texture_new (texture_id,
width, height,
self->current_frame_id);
t = gsk_gl_texture_new (texture_id, width, height, self->current_frame_id);
if (ensure_mipmap)
{
glBindTexture (GL_TEXTURE_2D, t->texture_id);
@@ -1801,9 +1927,8 @@ create_texture_from_texture_destroy (gpointer data)
}
GdkTexture *
gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id,
GdkMemoryFormat format)
gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id)
{
GskGLTextureState *state;
GdkGLTextureBuilder *builder;
@@ -1831,7 +1956,6 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, self->command_queue->context);
gdk_gl_texture_builder_set_id (builder, texture_id);
gdk_gl_texture_builder_set_format (builder, format);
gdk_gl_texture_builder_set_width (builder, texture->width);
gdk_gl_texture_builder_set_height (builder, texture->height);
gdk_gl_texture_builder_set_sync (builder, state->sync);
+1 -2
View File
@@ -154,8 +154,7 @@ void gsk_gl_driver_begin_frame (GskGLDriver *s
void gsk_gl_driver_end_frame (GskGLDriver *self);
void gsk_gl_driver_after_frame (GskGLDriver *self);
GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id,
GdkMemoryFormat format);
guint texture_id);
void gsk_gl_driver_cache_texture (GskGLDriver *self,
const GskTextureKey *key,
guint texture_id);
+5 -8
View File
@@ -119,11 +119,7 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
memset (pixel_data, 255, sizeof pixel_data);
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())
#if G_BYTE_ORDER == G_BIG_ENDIAN
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
#endif
)
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
{
gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE;
@@ -131,8 +127,9 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
else
{
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_BYTE;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0,
@@ -280,7 +277,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
g_assert (texture_id > 0);
if (G_UNLIKELY (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())))
if G_UNLIKELY (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
{
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4,
@@ -297,7 +294,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
{
pixel_data = cairo_image_surface_get_data (surface);
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_BYTE;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);
+2 -6
View File
@@ -111,11 +111,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
"Uploading texture");
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ())
#if G_BYTE_ORDER == G_BIG_ENDIAN
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
#endif
)
if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
{
pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4,
@@ -129,7 +125,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
{
pixel_data = surface_data;
gl_format = GL_BGRA;
gl_type = GL_UNSIGNED_BYTE;
gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
+12 -3
View File
@@ -94,6 +94,15 @@ GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
* to the list of supported formats in gdk/gdkdmabuftexture.c.
*/
GSK_GL_DEFINE_PROGRAM_NO_CLIP (external,
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("external.glsl")),
GSK_GL_ADD_UNIFORM (1, EXTERNAL_SOURCE, u_external_source))
GSK_GL_DEFINE_PROGRAM_NO_CLIP (yuyv,
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("yuyv.glsl")),
GSK_GL_ADD_UNIFORM (1, YUYV_SOURCE2, u_source2))
GSK_GL_DEFINE_PROGRAM_NO_CLIP (nv12,
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("nv12.glsl")),
GSK_GL_ADD_UNIFORM (1, NV12_SOURCE2, u_source2))
GSK_GL_DEFINE_PROGRAM_NO_CLIP (yuv420,
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("yuv420.glsl")),
GSK_GL_ADD_UNIFORM (1, YUV420_SOURCE2, u_source2)
GSK_GL_ADD_UNIFORM (2, YUV420_SOURCE3, u_source2))
+3 -10
View File
@@ -332,7 +332,6 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
GskGLRenderJob *job;
GdkTexture *texture;
guint texture_id;
GdkMemoryFormat gdk_format;
int width, height, max_size;
int format;
@@ -376,15 +375,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
if (gsk_render_node_get_preferred_depth (root) != GDK_MEMORY_U8 &&
gdk_gl_context_check_version (self->context, "3.0", "3.0"))
{
gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
format = GL_RGBA32F;
}
format = GL_RGBA32F;
else
{
format = GL_RGBA8;
gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
format = GL_RGBA8;
gdk_gl_context_make_current (self->context);
@@ -401,7 +394,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
#endif
gsk_gl_render_job_render_flipped (job, root);
texture_id = gsk_gl_driver_release_render_target (self->driver, render_target, FALSE);
texture = gsk_gl_driver_create_gdk_texture (self->driver, texture_id, gdk_format);
texture = gsk_gl_driver_create_gdk_texture (self->driver, texture_id);
gsk_gl_driver_end_frame (self->driver);
gsk_gl_render_job_free (job);
+12 -64
View File
@@ -30,7 +30,8 @@
#include <gsk/gskglshaderprivate.h>
#include <gdk/gdktextureprivate.h>
#include <gdk/gdkmemorytextureprivate.h>
#include <gdk/gdkdmabuftexture.h>
#include <gdk/gdkdmabuftextureprivate.h>
#include <gdk/gdkdisplayprivate.h>
#include <gsk/gsktransformprivate.h>
#include <gsk/gskroundedrectprivate.h>
#include <gsk/gskrectprivate.h>
@@ -44,10 +45,14 @@
#include "gskglprogramprivate.h"
#include "gskglrenderjobprivate.h"
#include "gskglshadowlibraryprivate.h"
#include "gskdebugprivate.h"
#include "ninesliceprivate.h"
#include "fp16private.h"
#include <epoxy/egl.h>
#include <drm/drm_fourcc.h>
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
@@ -210,10 +215,6 @@ static void gsk_gl_render_job_visit_node (GskGLRenderJob
static gboolean gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
const GskRenderNode *node,
GskGLRenderOffscreen *offscreen);
static void gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
GdkTexture *texture,
gboolean ensure_mipmap,
GskGLRenderOffscreen *offscreen);
static inline GskGLRenderClip *
clips_grow_one (Clips *clips)
@@ -3334,53 +3335,6 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
}
}
static gboolean
gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
const GskRenderNode *mask,
const GskRenderNode *color,
const graphene_rect_t *bounds)
{
int max_texture_size = job->command_queue->max_texture_size;
GdkTexture *texture = gsk_texture_node_get_texture (mask);
const GdkRGBA *rgba;
rgba = gsk_color_node_get_color (color);
if (RGBA_IS_CLEAR (rgba))
return TRUE;
if G_LIKELY (texture->width <= max_texture_size &&
texture->height <= max_texture_size &&
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, coloring)))
{
GskGLRenderOffscreen offscreen = {0};
float scale_x = mask->bounds.size.width / texture->width;
float scale_y = mask->bounds.size.height / texture->height;
gboolean use_mipmap;
guint16 cc[4];
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
(scale_y * fabs (job->scale_y)) < 0.5;
rgba_to_half (rgba, cc);
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
gsk_gl_program_set_uniform_texture_with_sync (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
GL_TEXTURE_2D,
GL_TEXTURE0,
offscreen.texture_id,
offscreen.has_mipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR,
GL_LINEAR,
offscreen.sync);
job->source_is_glyph_atlas = FALSE;
gsk_gl_render_job_draw_offscreen_with_color (job, bounds, &offscreen, cc);
gsk_gl_render_job_end_draw (job);
return TRUE;
}
return FALSE;
}
static inline void
gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
const GskRenderNode *node)
@@ -3390,17 +3344,6 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
GskGLRenderOffscreen source_offscreen = {0};
GskGLRenderOffscreen mask_offscreen = {0};
/* If the mask is a texture and the source is a color node
* then we can take a shortcut and avoid offscreens.
*/
if (GSK_RENDER_NODE_TYPE (mask) == GSK_TEXTURE_NODE &&
GSK_RENDER_NODE_TYPE (source) == GSK_COLOR_NODE &&
gsk_mask_node_get_mask_mode (node) == GSK_MASK_MODE_ALPHA)
{
if (gsk_gl_render_job_texture_mask_for_color (job, mask, source, &node->bounds))
return;
}
source_offscreen.bounds = &node->bounds;
source_offscreen.force_offscreen = TRUE;
source_offscreen.reset_clip = TRUE;
@@ -3632,7 +3575,6 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
gboolean ensure_mipmap,
GskGLRenderOffscreen *offscreen)
{
/* Don't put GL or dmabuf textures into icon caches, they are already on the GPU side */
if (!ensure_mipmap &&
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
texture->width,
@@ -3784,6 +3726,12 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
GskTextureKey key;
guint texture_id;
if (filter == GSK_SCALING_FILTER_LINEAR)
{
gsk_gl_render_job_visit_texture (job, texture, bounds);
return;
}
gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))
-28
View File
@@ -1,28 +0,0 @@
// VERTEX_SHADER:
// external.glsl
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
// external.glsl
#if defined(GSK_GLES) || defined(GSK_GLES3)
uniform samplerExternalOES u_external_source;
#else
/* Just to make this compile, we won't use it without GLES */
uniform sampler2D u_external_source;
#endif
void main() {
/* Open-code this here, since GskTexture() expects a sampler2D */
#if defined(GSK_GLES) || defined(GSK_LEGACY)
vec4 color = texture2D(u_external_source, vUv);
#else
vec4 color = texture(u_external_source, vUv);
#endif
gskSetOutputColor(color);
}
+49
View File
@@ -0,0 +1,49 @@
// VERTEX_SHADER:
// nv12.glsl
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
// nv12.glsl
uniform sampler2D u_source2;
vec4 yuv_to_rgb(vec4 yuv)
{
vec4 res;
float Y = 1.16438356 * (yuv.x - 0.0625);
float su = yuv.y - 0.5;
float sv = yuv.z - 0.5;
res.r = Y + 1.59602678 * sv;
res.g = Y - 0.39176229 * su - 0.81296764 * sv;
res.b = Y + 2.01723214 * su;
res.rgb *= yuv.w;
res.a = yuv.w;
return res;
}
/* This shader converts 2-plane yuv (DRM_FORMAT_NV12 or DRM_FORMAT_P010)
* into rgb. It assumes that the two planes have been imported separately,
* the first one as R texture, the second one as RG.
*/
void main() {
vec4 y = GskTexture(u_source, vUv);
vec4 uv = GskTexture(u_source2, vUv);
vec4 yuv;
yuv.x = y.x;
yuv.yz = uv.xy;
yuv.w = 1.0;
gskSetOutputColor(yuv_to_rgb(yuv));
}
-6
View File
@@ -1,9 +1,3 @@
#if defined(GSK_GLES3)
#extension GL_OES_EGL_image_external_essl3 : require
#elif defined (GSK_GLES)
#extension GL_OES_EGL_image_external : require
#endif
#ifndef GSK_LEGACY
precision highp float;
#endif
+51
View File
@@ -0,0 +1,51 @@
// VERTEX_SHADER:
// y_uv_to_rgba.glsl
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
// y_uv_to_rgba.glsl
uniform sampler2D u_source2;
uniform sampler2D u_source3;
vec4 yuv_to_rgb(vec4 yuv)
{
vec4 res;
float Y = 1.16438356 * (yuv.x - 0.0625);
float su = yuv.y - 0.5;
float sv = yuv.z - 0.5;
res.r = Y + 1.59602678 * sv;
res.g = Y - 0.39176229 * su - 0.81296764 * sv;
res.b = Y + 2.01723214 * su;
res.rgb *= yuv.w;
res.a = yuv.w;
return res;
}
/* This shader converts 3-plane yuv (DRM_FORMAT_YUY420) into rgb.
*/
void main() {
vec4 y = GskTexture(u_source, vUv);
vec4 u = GskTexture(u_source2, vUv);
vec4 v = GskTexture(u_source3, vUv);
vec4 yuv;
yuv.x = y.x;
yuv.y = u.x;
yuv.z = v.x;
yuv.w = 1.0;
gskSetOutputColor(yuv_to_rgb(yuv));
}
+49
View File
@@ -0,0 +1,49 @@
// VERTEX_SHADER:
// y_xuxv_to_rgba.glsl
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
vUv = vec2(aUv.x, aUv.y);
}
// FRAGMENT_SHADER:
// y_xuxv_to_rgba.glsl
uniform sampler2D u_source2;
vec4 yuv_to_rgb(vec4 yuv)
{
vec4 res;
float Y = 1.16438356 * (yuv.x - 0.0625);
float su = yuv.y - 0.5;
float sv = yuv.z - 0.5;
res.r = Y + 1.59602678 * sv;
res.g = Y - 0.39176229 * su - 0.81296764 * sv;
res.b = Y + 2.01723214 * su;
res.rgb *= yuv.w;
res.a = yuv.w;
return res;
}
/* This shader converts single-plane yuv (DRM_FORMAT_YUYV) into rgb.
* It assumes that the buffer has been imported twice - once as RG
* texture with full size, and once as RGBA textures with half the
* width (to account for the subsampling).
*/
void main() {
vec4 y = GskTexture(u_source, vUv);
vec4 uv = GskTexture(u_source2, vUv);
vec4 yuv;
yuv.x = y.x;
yuv.yz = uv.yw;
yuv.w = 1.0;
gskSetOutputColor(yuv_to_rgb(yuv));
}
+16 -12
View File
@@ -19,10 +19,8 @@
#ifdef _MSC_VER
#define STBRP__NOTUSED(v) (void)(v)
#define STBRP__CDECL __cdecl
#else
#define STBRP__NOTUSED(v) (void)sizeof(v)
#define STBRP__CDECL
#endif
enum
@@ -65,6 +63,9 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
#ifndef STBRP_LARGE_RECTS
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
#endif
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
@@ -83,7 +84,11 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
#ifdef STBRP_LARGE_RECTS
context->extra[1].y = (1<<30);
#else
context->extra[1].y = 65535;
#endif
context->extra[1].next = NULL;
}
@@ -155,13 +160,6 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
width -= width % c->align;
STBRP_ASSERT(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
@@ -225,7 +223,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt
}
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
if (y + height < c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
@@ -325,7 +323,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
return res;
}
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
static int rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
@@ -336,13 +334,19 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
return (p->w > q->w) ? -1 : (p->w < q->w);
}
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
static int rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
#ifdef STBRP_LARGE_RECTS
#define STBRP__MAXVAL 0xffffffff
#else
#define STBRP__MAXVAL 0xffff
#endif
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
int i, all_rects_packed = 1;
+5 -13
View File
@@ -1,15 +1,9 @@
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// stb_rect_pack.h - v0.99 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// Before #including,
//
// #define STB_RECT_PACK_IMPLEMENTATION
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
@@ -37,12 +31,9 @@
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
@@ -81,10 +72,11 @@ typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
#ifdef STBRP_LARGE_RECTS
typedef int stbrp_coord;
#define STBRP__MAXVAL 0x7fffffff
// Mostly for internal use, but this is the maximum supported coordinate value.
#else
typedef unsigned short stbrp_coord;
#endif
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
-19
View File
@@ -684,22 +684,3 @@ gsk_renderer_set_debug_flags (GskRenderer *renderer,
priv->debug_flags = flags;
}
/* Feed a texture through a renderer and return the resulting 'native' texture. */
GdkTexture *
gsk_renderer_convert_texture (GskRenderer *self,
GdkTexture *texture)
{
int width, height;
GskRenderNode *node;
GdkTexture *result;
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
node = gsk_texture_node_new (texture, &GRAPHENE_RECT_INIT (0, 0, width, height));
result = gsk_renderer_render_texture (self, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_render_node_unref (node);
return result;
}
-3
View File
@@ -56,8 +56,5 @@ GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer
void gsk_renderer_set_debug_flags (GskRenderer *renderer,
GskDebugFlags flags);
GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
GdkTexture *texture);
G_END_DECLS
+30 -6
View File
@@ -33,7 +33,6 @@
#include "gdk/gdkrgbaprivate.h"
#include "gdk/gdktextureprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
#include <gtk/css/gtkcss.h>
#include "gtk/css/gtkcssdataurlprivate.h"
#include "gtk/css/gtkcssparserprivate.h"
@@ -3170,20 +3169,45 @@ append_texture_param (Printer *p,
g_hash_table_insert (p->named_textures, texture, new_name);
}
switch (gdk_memory_format_get_depth (gdk_texture_get_format (texture)))
switch (gdk_texture_get_format (texture))
{
case GDK_MEMORY_U8:
case GDK_MEMORY_U16:
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_G8:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_G16:
case GDK_MEMORY_A8:
case GDK_MEMORY_A16:
bytes = gdk_texture_save_to_png_bytes (texture);
g_string_append (p->str, "url(\"data:image/png;base64,");
break;
case GDK_MEMORY_FLOAT16:
case GDK_MEMORY_FLOAT32:
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_A16_FLOAT:
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT:
case GDK_MEMORY_A32_FLOAT:
bytes = gdk_texture_save_to_tiff_bytes (texture);
g_string_append (p->str, "url(\"data:image/tiff;base64,");
break;
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();
}
+3 -1
View File
@@ -20,7 +20,9 @@ gsk_private_gl_shaders = [
'gl/resources/custom.glsl',
'gl/resources/filled_border.glsl',
'gl/resources/mask.glsl',
'gl/resources/external.glsl',
'gl/resources/yuyv.glsl',
'gl/resources/nv12.glsl',
'gl/resources/yuv420.glsl',
]
gsk_public_sources = files([
-25
View File
@@ -80,15 +80,6 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
return info;
}
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_R8G8B8A8_UNORM, SWIZZLE(A, B, G, R), 0 },
{ VK_FORMAT_UNDEFINED }
};
return info;
}
case GDK_MEMORY_B8G8R8A8:
{
static const GskMemoryFormatInfo info[] = {
@@ -126,17 +117,6 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
return info;
}
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
{
static const GskMemoryFormatInfo info[] = {
{ VK_FORMAT_UNDEFINED }
};
return info;
}
case GDK_MEMORY_R8G8B8:
{
static const GskMemoryFormatInfo info[] = {
@@ -344,7 +324,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
@@ -352,10 +331,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
case GDK_MEMORY_R8G8B8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
case GDK_MEMORY_B8G8R8:
return GDK_MEMORY_R8G8B8;
+1 -3
View File
@@ -714,9 +714,7 @@ emit_text_changed (GtkAtSpiContext *self,
"org.a11y.atspi.Event.Object",
"TextChanged",
g_variant_new ("(siiva{sv})",
kind, start, end,
g_variant_new_string (text),
NULL),
kind, start, end, g_variant_new_string (text), NULL),
NULL);
}
+3 -12
View File
@@ -1614,10 +1614,7 @@ insert_text_cb (GtkEditable *editable,
return;
length = g_utf8_strlen (new_text, new_text_length);
char *inserted_text = g_utf8_substring (new_text, 0, length);
changed->text_changed (changed->data, "insert", *position - length, length, inserted_text);
g_free (inserted_text);
changed->text_changed (changed->data, "insert", *position - length, length, new_text);
}
static void
@@ -1632,10 +1629,6 @@ delete_text_cb (GtkEditable *editable,
return;
text = gtk_editable_get_chars (editable, start, end);
if (end < 0)
end = g_utf8_strlen(text, -1);
changed->text_changed (changed->data, "delete", start, end - start, text);
g_free (text);
}
@@ -1714,9 +1707,7 @@ insert_range_cb (GtkTextBuffer *buffer,
position = gtk_text_iter_get_offset (iter);
length = g_utf8_strlen (text, len);
char *inserted_text = g_utf8_substring (text, 0, length);
changed->text_changed (changed->data, "insert", position - length, length, inserted_text);
g_free (inserted_text);
changed->text_changed (changed->data, "insert", position - length, length, text);
update_cursor (buffer, changed);
}
@@ -1793,7 +1784,7 @@ buffer_changed (GtkWidget *widget,
if (changed->buffer)
{
g_object_ref (changed->buffer);
g_signal_connect_after (changed->buffer, "insert-text", G_CALLBACK (insert_range_cb), changed);
g_signal_connect (changed->buffer, "insert-text", G_CALLBACK (insert_range_cb), changed);
g_signal_connect (changed->buffer, "delete-range", G_CALLBACK (delete_range_cb), changed);
g_signal_connect_after (changed->buffer, "delete-range", G_CALLBACK (delete_range_after_cb), changed);
g_signal_connect_after (changed->buffer, "mark-set", G_CALLBACK (mark_set_cb), changed);
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -46,7 +46,7 @@ static gboolean
gtk_accessible_range_default_set_current_value (GtkAccessibleRange *accessible_range,
double value)
{
return TRUE;
return FALSE;
}
static void
+1 -1
View File
@@ -511,7 +511,7 @@ gtk_color_dialog_button_set_dialog (GtkColorDialogButton *self,
*
* This function is what should be used to obtain
* the color that was chosen by the user. To get
* informed about changes, listen to "notify::rgba".
* informed about changes, listen to "notify::color".
*
* Returns: the color
*
-1
View File
@@ -177,7 +177,6 @@ response_cb (GDBusConnection *connection,
self->custom_files = NULL;
for (i = 0; uris[i]; i++)
self->custom_files = g_slist_prepend (self->custom_files, g_file_new_for_uri (uris[i]));
self->custom_files = g_slist_reverse (self->custom_files);
g_free (uris);
g_variant_unref (response_data);
+2 -2
View File
@@ -4772,7 +4772,7 @@ gtk_file_chooser_widget_add_filter (GtkFileChooser *chooser,
return;
}
g_object_ref (filter);
g_object_ref_sink (filter);
g_list_store_append (impl->filters, filter);
g_object_unref (filter);
@@ -6000,7 +6000,7 @@ set_current_filter (GtkFileChooserWidget *impl,
g_object_unref (impl->current_filter);
impl->current_filter = filter;
if (impl->current_filter)
g_object_ref (impl->current_filter);
g_object_ref_sink (impl->current_filter);
gtk_drop_down_set_selected (GTK_DROP_DOWN (impl->filter_combo), filter_index);
+1 -1
View File
@@ -86,7 +86,7 @@ struct _GtkMenuTrackerItem
char *action_namespace;
char *action_and_target;
GMenuItem *item;
guint role : 4; /* GtkMenuTrackerItemRole */
GtkMenuTrackerItemRole role : 4;
guint is_separator : 1;
guint can_activate : 1;
guint sensitive : 1;
+1 -1
View File
@@ -70,7 +70,7 @@ typedef struct {
CachedSizeX cached_size_x;
CachedSizeY cached_size_y;
guint request_mode : 3; /* GtkSizeRequestMode */
GtkSizeRequestMode request_mode : 3;
guint request_mode_valid : 1;
struct {
guint n_cached_requests : 15;
+1 -1
View File
@@ -6536,7 +6536,7 @@ gtk_widget_update_default_pango_context (GtkWidget *widget)
return;
if (gtk_widget_update_pango_context (widget, context, _gtk_widget_get_direction (widget)))
gtk_widget_queue_resize (widget);
gtk_widget_queue_draw (widget);
}
/**
-7
View File
@@ -855,27 +855,20 @@ else
endif
foreach lang : [
'bn',
'de',
'da',
'fr',
'es',
'et',
'fi',
'hi',
'hu',
'it',
'ja',
'ko',
'lt',
'ms',
'nb',
'nl',
'pl',
'pt',
'ru',
'sv',
'th',
'uk',
'zh'
]
+1 -15
View File
@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.13.3',
version: '4.13.2',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',
@@ -618,20 +618,6 @@ else
vulkan_pkg_found = false
endif
if cc.has_header('linux/dma-buf.h')
dmabuf_dep = dependency('libdrm',
required: os_linux)
else
if os_linux
error('OS is Linux, but linux/dma-buf.h not found.')
endif
dmabuf_dep = dependency('', required: false)
endif
cdata.set('HAVE_DMABUF', dmabuf_dep.found())
# We only care about drm_fourcc.h for all the fourccs,
# but not about linking to libdrm
dmabuf_dep = dmabuf_dep.partial_dependency(includes: true, compile_args: true)
cloudproviders_dep = dependency('cloudproviders',
required: get_option('cloudproviders'),
version: cloudproviders_req,
-1
View File
@@ -23,7 +23,6 @@ gdk/gdkseat.c
gdk/gdksurface.c
gdk/gdktexture.c
gdk/gdktoplevel.c
gdk/gdkvulkancontext.c
gdk/keynamesprivate.h
gdk/loaders/gdkjpeg.c
gdk/loaders/gdkpng.c
+140 -165
View File
File diff suppressed because it is too large Load Diff
+745 -1042
View File
File diff suppressed because it is too large Load Diff
+190 -514
View File
File diff suppressed because it is too large Load Diff
+31 -34
View File
@@ -22,8 +22,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gtk\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-10-16 11:58+0000\n"
"PO-Revision-Date: 2023-10-17 18:20+0300\n"
"POT-Creation-Date: 2023-09-19 12:32+0000\n"
"PO-Revision-Date: 2023-09-19 18:25+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n"
@@ -31,7 +31,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 3.4\n"
"X-Generator: Poedit 3.2.2\n"
#: gdk/broadway/gdkbroadway-server.c:135
#, c-format
@@ -61,58 +61,58 @@ msgstr "İçerikler “%s” olarak sağlanamıyor"
msgid "Cannot provide contents as %s"
msgstr "İçerikler %s olarak sağlanamıyor"
#: gdk/gdkdisplay.c:164 gdk/gdkglcontext.c:442
#: gdk/gdkdisplay.c:156 gdk/gdkglcontext.c:442
msgid "The current backend does not support OpenGL"
msgstr "Şimdiki arka uç OpenGLi desteklemiyor"
#: gdk/gdkdisplay.c:1259 gdk/gdksurface.c:1252
#: gdk/gdkdisplay.c:1244 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Vulkan desteği GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1291
#: gdk/gdkdisplay.c:1276
msgid "GL support disabled via GDK_DEBUG"
msgstr "GL desteği, GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1589
#: gdk/gdkdisplay.c:1574
msgid "No EGL configuration available"
msgstr "Kullanılabilir EGL yapılandırması yok"
#: gdk/gdkdisplay.c:1597
#: gdk/gdkdisplay.c:1582
msgid "Failed to get EGL configurations"
msgstr "EGL yapılandırmaları alınamadı"
#: gdk/gdkdisplay.c:1627
#: gdk/gdkdisplay.c:1612
msgid "No EGL configuration with required features found"
msgstr "Gerekli özellikleri olan EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1634
#: gdk/gdkdisplay.c:1619
msgid "No perfect EGL configuration found"
msgstr "Kusursuz EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1676
#: gdk/gdkdisplay.c:1661
#, c-format
msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
msgstr[0] "EGL uygulamasında %2$d eksik uzantı: %1$s"
# https://twitter.com/mserdark/status/932936929213079559
#: gdk/gdkdisplay.c:1709
#: gdk/gdkdisplay.c:1694
msgid "libEGL not available in this sandbox"
msgstr "libEGL bu kum havuzunda kullanılamıyor"
#: gdk/gdkdisplay.c:1710
#: gdk/gdkdisplay.c:1695
msgid "libEGL not available"
msgstr "libEGL kullanılamıyor"
#: gdk/gdkdisplay.c:1720
#: gdk/gdkdisplay.c:1705
msgid "Failed to create EGL display"
msgstr "EGL ekranı oluşturulamadı"
#: gdk/gdkdisplay.c:1730
#: gdk/gdkdisplay.c:1715
msgid "Could not initialize EGL display"
msgstr "EGL ekranı ilklendirilemedi"
#: gdk/gdkdisplay.c:1741
#: gdk/gdkdisplay.c:1726
#, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d"
msgstr "EGL sürümü %d.%d çok eski. GTK, %d.%d gerektiriyor"
@@ -147,12 +147,12 @@ msgstr "Uygulama %s APIsini desteklemiyor"
#. translators: This is about OpenGL backend names, like
#. * "Trying to use X11 GLX, but EGL is already in use"
#: gdk/gdkglcontext.c:1914
#: gdk/gdkglcontext.c:1864
#, c-format
msgid "Trying to use %s, but %s is already in use"
msgstr "%s kullanılmaya çalışılıyor ancak şu anda %s kullanılıyor"
#: gdk/gdktexture.c:530
#: gdk/gdktexture.c:528
msgid "Unknown image format."
msgstr "Bilinmeyen resim biçimi."
@@ -1719,11 +1719,6 @@ msgctxt "accessibility"
msgid "toggle button"
msgstr "aç/kapat düğmesi"
#: gtk/gtkaccessible.c:835
msgctxt "accessibility"
msgid "paragraph"
msgstr "paragraf"
#: gtk/gtkalertdialog.c:668 gtk/print/gtkcustompaperunixdialog.c:322
#: gtk/gtkmessagedialog.c:166 gtk/ui/gtkassistant.ui:40
msgid "_Close"
@@ -2209,11 +2204,11 @@ msgstr "Bu adda dosya zaten var"
#: gtk/gtkmessagedialog.c:179 gtk/gtkmountoperation.c:608
#: gtk/print/gtkpagesetupunixdialog.c:282 gtk/print/gtkprintbackend.c:638
#: gtk/print/gtkprintunixdialog.c:682 gtk/print/gtkprintunixdialog.c:839
#: gtk/gtkwindow.c:6243 gtk/ui/gtkappchooserdialog.ui:48
#: gtk/gtkwindow.c:6242 gtk/ui/gtkappchooserdialog.ui:48
#: gtk/ui/gtkassistant.ui:52 gtk/ui/gtkcolorchooserdialog.ui:36
#: gtk/ui/gtkfontchooserdialog.ui:27
msgid "_Cancel"
msgstr "İ_ptal"
msgstr "_İptal Et"
#: gtk/gtkfilechoosernative.c:521 gtk/gtkfilechoosernative.c:594
#: gtk/gtkfiledialog.c:815 gtk/gtkplacessidebar.c:3149
@@ -2733,7 +2728,7 @@ msgid "Play"
msgstr "Oynat"
#: gtk/gtkmessagedialog.c:162 gtk/gtkmessagedialog.c:180
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6244
#: gtk/print/gtkprintbackend.c:639 gtk/gtkwindow.c:6243
msgid "_OK"
msgstr "_Tamam"
@@ -3149,12 +3144,12 @@ msgstr "Ba_ğlan"
#. if it wasn't cancelled show a dialog
#: gtk/gtkplacesview.c:1353
msgid "Unable to unmount volume"
msgstr "Birim ayrılamadı"
msgstr "Birim ayrılamıyor"
#. Allow to cancel the operation
#: gtk/gtkplacesview.c:1445
msgid "Cance_l"
msgstr "İ_ptal"
msgstr "İpta_l"
#: gtk/gtkplacesview.c:1592
msgid "AppleTalk"
@@ -3205,7 +3200,7 @@ msgstr "_Bağlan"
#: gtk/gtkplacesview.c:1894
msgid "Unable to get remote server location"
msgstr "Uzak sunucu konumu alınamadı"
msgstr "Uzak sunucu konumu alınamıyor"
#: gtk/gtkplacesview.c:2038 gtk/gtkplacesview.c:2047
msgid "Networks"
@@ -3331,8 +3326,8 @@ msgstr "En olası nedeni geçici dosyanın oluşturulamamasıdır."
#. window
#: gtk/print/gtkprintoperation-portal.c:264
#: gtk/print/gtkprintoperation-portal.c:594
#: gtk/print/gtkprintoperation-portal.c:663 gtk/print/gtkprintunixdialog.c:3008
#: gtk/print/gtkprintoperation-portal.c:584
#: gtk/print/gtkprintoperation-portal.c:653 gtk/print/gtkprintunixdialog.c:3008
msgid "Print"
msgstr "Yazdır"
@@ -3607,12 +3602,12 @@ msgstr "_Geri Al"
msgid "_Redo"
msgstr "_Yinele"
#: gtk/gtkwindow.c:6232
#: gtk/gtkwindow.c:6231
#, c-format
msgid "Do you want to use GTK Inspector?"
msgstr "GTK Denetleyicisi kullanmak istiyor musunuz?"
#: gtk/gtkwindow.c:6234
#: gtk/gtkwindow.c:6233
#, c-format
msgid ""
"GTK Inspector is an interactive debugger that lets you explore and modify "
@@ -3623,7 +3618,7 @@ msgstr ""
"izin veren etkileşimli hata ayıklayıcıdır. Bunun kullanılması uygulamanın "
"kesilmesine ya da çökmesine neden olabilir."
#: gtk/gtkwindow.c:6239
#: gtk/gtkwindow.c:6238
msgid "Dont show this message again"
msgstr "Bu iletiyi yeniden gösterme"
@@ -7538,6 +7533,7 @@ msgstr "%d kübik"
#: tools/gtk-path-tool-info.c:159
#, c-format
#| msgid "%d cubics"
msgid "%d conics"
msgstr "%d konik"
@@ -7847,6 +7843,7 @@ msgstr "%s. satırda hata: %s\n"
#: tools/gtk-rendernode-tool-utils.c:69
#, c-format
#| msgid "Failed to open file %s : %s\n"
msgid "Failed to load node file: %s\n"
msgstr "Düğüm dosyası yüklenemedi: %s\n"
+1 -12
View File
@@ -125,10 +125,7 @@ gtk_tests = [
]
if os_unix
gtk_tests += [
['testfontchooserdialog'],
['testdmabuf'],
]
gtk_tests += [['testfontchooserdialog']]
endif
if x11_enabled
@@ -149,11 +146,3 @@ foreach t: gtk_tests
dependencies: [libgtk_dep, libm],
)
endforeach
executable('testsubsurface',
sources: '@0@.c'.format('testsubsurface'),
c_args: common_cflags + ['-DGTK_COMPILATION'],
dependencies: libgtk_static_dep,
install: false,
)
-525
View File
@@ -1,525 +0,0 @@
#include <gtk/gtk.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/dma-heap.h>
#include <drm_fourcc.h>
/* For this to work, you may need to give /dev/dma_heap/system
* lax permissions.
*/
static int dma_heap_fd = -1;
static gboolean
initialize_dma_heap (void)
{
dma_heap_fd = open ("/dev/dma_heap/system", O_RDONLY | O_CLOEXEC);
return dma_heap_fd != -1;
}
static int
allocate_dma_buf (gsize size)
{
struct dma_heap_allocation_data heap_data;
int ret;
heap_data.len = size;
heap_data.fd = 0;
heap_data.fd_flags = O_RDWR | O_CLOEXEC;
heap_data.heap_flags = 0;
ret = ioctl (dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data);
if (ret)
g_error ("dma-buf allocation failed");
return heap_data.fd;
}
static int
allocate_memfd (gsize size)
{
int fd;
fd = memfd_create ("buffer", MFD_CLOEXEC);
if (fd == -1)
g_error ("memfd allocation failed");
ftruncate (fd, size);
return fd;
}
static int
allocate_buffer (gsize size)
{
if (dma_heap_fd != -1)
return allocate_dma_buf (size);
else
return allocate_memfd (size);
}
static void
populate_buffer (int fd,
const guchar *data,
gsize size)
{
guchar *buf;
buf = mmap (NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
memcpy (buf, data, size);
munmap (buf, size);
}
/* The YUV conversion code is adapted from weston/tests/yuv-buffer-test.c */
/*
* Based on Rec. ITU-R BT.601-7
*
* This is intended to be obvious and accurate, not fast.
*/
static void
x8r8g8b8_to_ycbcr8_bt601 (guint32 xrgb,
guchar *y_out,
guchar *cb_out,
guchar *cr_out)
{
double y, cb, cr;
double r = (xrgb >> 16) & 0xff;
double g = (xrgb >> 8) & 0xff;
double b = (xrgb >> 0) & 0xff;
/* normalize to [0.0, 1.0] */
r /= 255.0;
g /= 255.0;
b /= 255.0;
/* Y normalized to [0.0, 1.0], Cb and Cr [-0.5, 0.5] */
y = 0.299 * r + 0.587 * g + 0.114 * b;
cr = (r - y) / 1.402;
cb = (b - y) / 1.772;
/* limited range quantization to 8 bit */
*y_out = round(219.0 * y + 16.0);
if (cr_out)
*cr_out = round(224.0 * cr + 128.0);
if (cb_out)
*cb_out = round(224.0 * cb + 128.0);
}
/*
* 3 plane YCbCr
* plane 0: Y plane, [7:0] Y
* plane 1: Cb plane, [7:0] Cb
* plane 2: Cr plane, [7:0] Cr
* YUV420: 2x2 subsampled Cb (1) and Cr (2) planes
* YUV444: no subsampling
*/
static guchar *
y_u_v_create_buffer (uint32_t drm_format,
guchar *rgb_data,
int rgb_width,
int rgb_height,
int *size,
int *u_offset,
int *v_offset)
{
gsize bytes;
int x, y;
guint32 *rgb_row;
guchar *y_base;
guchar *u_base;
guchar *v_base;
guchar *y_row;
guchar *u_row;
guchar *v_row;
guint32 argb;
int sub = (drm_format == DRM_FORMAT_YUV420) ? 2 : 1;
guchar *buf;
g_assert (drm_format == DRM_FORMAT_YUV420 ||
drm_format == DRM_FORMAT_YUV444);
/* Full size Y plus quarter U and V */
bytes = rgb_width * rgb_height +
(rgb_width / sub) * (rgb_height / sub) * 2;
buf = g_new (guchar, bytes);
*size = bytes;
*u_offset = rgb_width * rgb_height;
*v_offset = *u_offset + (rgb_width / sub) * (rgb_height / sub);
y_base = buf;
u_base = y_base + rgb_width * rgb_height;
v_base = u_base + (rgb_width / sub) * (rgb_height / sub);
for (y = 0; y < rgb_height; y++)
{
rgb_row = (guint32 *) (rgb_data + y * 4 * rgb_width);
y_row = y_base + y * rgb_width;
u_row = u_base + (y / sub) * (rgb_width / sub);
v_row = v_base + (y / sub) * (rgb_width / sub);
for (x = 0; x < rgb_width; x++)
{
/*
* Sub-sample the source image instead, so that U and V
* sub-sampling does not require proper
* filtering/averaging/siting.
*/
argb = rgb_row[x];
/*
* A stupid way of "sub-sampling" chroma. This does not
* do the necessary filtering/averaging/siting or
* alternate Cb/Cr rows.
*/
if ((y & (sub - 1)) == 0 && (x & (sub - 1)) == 0)
x8r8g8b8_to_ycbcr8_bt601 (argb, y_row + x, u_row + x / sub, v_row + x / sub);
else
x8r8g8b8_to_ycbcr8_bt601 (argb, y_row + x, NULL, NULL);
}
}
return buf;
}
/*
* 2 plane YCbCr
* plane 0 = Y plane, [7:0] Y
* plane 1 = Cr:Cb plane, [15:0] Cr:Cb little endian
* 2x2 subsampled Cr:Cb plane
*/
static guchar *
nv12_create_buffer (uint32_t drm_format,
guchar *rgb_data,
int rgb_width,
int rgb_height,
int *size,
int *uv_offset)
{
size_t bytes;
int x, y;
uint32_t *rgb_row;
uint8_t *y_base;
uint8_t *uv_base;
uint8_t *y_row;
uint16_t *uv_row;
uint32_t argb;
uint8_t cr;
uint8_t cb;
guchar *buf;
g_assert (drm_format == DRM_FORMAT_NV12);
/* Full size Y plane, half size UV plane */
bytes = rgb_width * rgb_height +
rgb_width * (rgb_height / 2);
*size = bytes;
buf = g_new0 (guchar, bytes);
*uv_offset = rgb_width * rgb_height;
y_base = buf;
uv_base = y_base + rgb_width * rgb_height;
for (y = 0; y < rgb_height; y++)
{
rgb_row = (uint32_t *) (rgb_data + y * 4 * rgb_width);
y_row = y_base + y * rgb_width;
uv_row = (uint16_t *) (uv_base + (y / 2) * rgb_width);
for (x = 0; x < rgb_width; x++)
{
/*
* Sub-sample the source image instead, so that U and V
* sub-sampling does not require proper
* filtering/averaging/siting.
*/
argb = rgb_row[x];
/*
* A stupid way of "sub-sampling" chroma. This does not
* do the necessary filtering/averaging/siting.
*/
if ((y & 1) == 0 && (x & 1) == 0)
{
x8r8g8b8_to_ycbcr8_bt601(argb, y_row + x, &cb, &cr);
*(uv_row + x / 2) = ((uint16_t)cr << 8) | cb;
}
else
{
x8r8g8b8_to_ycbcr8_bt601(argb, y_row + x, NULL, NULL);
}
}
}
return buf;
}
static void
texture_builder_set_planes (GdkDmabufTextureBuilder *builder,
gboolean disjoint,
const guchar *buf,
unsigned size,
unsigned n_planes,
unsigned strides[4],
unsigned sizes[4])
{
gdk_dmabuf_texture_builder_set_n_planes (builder, n_planes);
if (disjoint)
{
unsigned offset = 0;
unsigned i;
for (i = 0; i < n_planes; i++)
{
int fd = allocate_buffer (sizes[i]);
populate_buffer (fd, buf + offset, sizes[i]);
gdk_dmabuf_texture_builder_set_fd (builder, i, fd);
gdk_dmabuf_texture_builder_set_stride (builder, i, strides[i]);
gdk_dmabuf_texture_builder_set_offset (builder, i, 0);
offset += sizes[i];
}
}
else
{
unsigned offset = 0;
unsigned i;
int fd = allocate_buffer (size);
populate_buffer (fd, buf, size);
for (i = 0; i < n_planes; i++)
{
gdk_dmabuf_texture_builder_set_fd (builder, i, fd);
gdk_dmabuf_texture_builder_set_stride (builder, i, strides[i]);
gdk_dmabuf_texture_builder_set_offset (builder, i, offset);
offset += sizes[i];
}
}
}
static GdkTexture *
make_dmabuf_texture (const char *filename,
guint32 format,
gboolean disjoint)
{
GdkTexture *texture;
int width, height;
gsize rgb_stride, rgb_size;
guchar *rgb_data;
int fd;
GdkDmabufTextureBuilder *builder;
GError *error = NULL;
if (initialize_dma_heap ())
g_print ("Using dma_heap\n");
else
g_print ("Using memfd\n");
texture = gdk_texture_new_from_filename (filename, NULL);
width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture);
rgb_stride = 4 * width;
rgb_size = rgb_stride * height;
rgb_data = g_new0 (guchar, rgb_size);
gdk_texture_download (texture, rgb_data, rgb_stride);
g_object_unref (texture);
builder = gdk_dmabuf_texture_builder_new ();
gdk_dmabuf_texture_builder_set_display (builder, gdk_display_get_default ());
gdk_dmabuf_texture_builder_set_width (builder, width);
gdk_dmabuf_texture_builder_set_height (builder, height);
gdk_dmabuf_texture_builder_set_fourcc (builder, format);
gdk_dmabuf_texture_builder_set_modifier (builder, DRM_FORMAT_MOD_LINEAR);
if (format == DRM_FORMAT_XRGB8888 ||
format == DRM_FORMAT_ARGB8888)
{
gdk_dmabuf_texture_builder_set_n_planes (builder, 1);
fd = allocate_buffer (rgb_size);
populate_buffer (fd, rgb_data, rgb_size);
gdk_dmabuf_texture_builder_set_fd (builder, 0, fd);
gdk_dmabuf_texture_builder_set_stride (builder, 0, rgb_stride);
}
else if (format == DRM_FORMAT_YUV420)
{
guchar *buf;
int size, u_offset, v_offset;
buf = y_u_v_create_buffer (format, rgb_data, width, height, &size, &u_offset, &v_offset);
texture_builder_set_planes (builder,
disjoint,
buf,
size,
3,
(unsigned[4]) { width, width / 2, width / 2 },
(unsigned[4]) { width * height, width * height / 4, width * height / 4 });
g_free (buf);
}
else if (format == DRM_FORMAT_NV12)
{
guchar *buf;
int size, uv_offset;
buf = nv12_create_buffer (format, rgb_data, width, height, &size, &uv_offset);
texture_builder_set_planes (builder,
disjoint,
buf,
size,
2,
(unsigned[4]) { width, width, },
(unsigned[4]) { width * height, width * height / 2 });
g_free (buf);
}
g_free (rgb_data);
texture = gdk_dmabuf_texture_builder_build (builder, NULL, NULL, &error);
if (!texture)
g_error ("Failed to create dmabuf texture: %s", error->message);
g_object_unref (builder);
return texture;
}
static guint32 supported_formats[] = {
DRM_FORMAT_ARGB8888,
DRM_FORMAT_XRGB8888,
DRM_FORMAT_YUV420,
DRM_FORMAT_NV12,
};
static gboolean
format_is_supported (guint32 fmt)
{
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (supported_formats[i] == fmt)
return TRUE;
}
return FALSE;
}
static char *
supported_formats_to_string (void)
{
GString *s;
s = g_string_new ("");
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
{
if (s->len)
g_string_append (s, ", ");
g_string_append_printf (s, "%.4s", (char *)&supported_formats[i]);
}
return g_string_free (s, FALSE);
}
G_GNUC_NORETURN
static void
usage (void)
{
char *formats = supported_formats_to_string ();
g_print ("Usage: testdmabuf [--undecorated] [--disjoint][--download-to FILE] FORMAT FILE\n"
"Supported formats: %s\n", formats);
g_free (formats);
exit (1);
}
static guint32
parse_format (const char *a)
{
if (strlen (a) == 4)
{
guint32 format = fourcc_code (a[0], a[1], a[2], a[3]);
if (format_is_supported (format))
return format;
}
usage ();
return 0;
}
int
main (int argc, char *argv[])
{
GdkTexture *texture;
GtkWidget *window, *picture;
char *filename;
guint32 format;
gboolean disjoint = FALSE;
gboolean decorated = TRUE;
unsigned int i;
const char *save_filename = NULL;
for (i = 1; i < argc; i++)
{
if (g_str_equal (argv[i], "--disjoint"))
disjoint = TRUE;
else if (g_str_equal (argv[i], "--undecorated"))
decorated = FALSE;
else if (g_str_equal (argv[i], "--download-to"))
{
i++;
if (i == argc)
usage ();
save_filename = argv[i];
}
else
break;
}
if (argc - i != 2)
{
usage ();
return 1;
}
format = parse_format (argv[argc - 2]);
filename = argv[argc - 1];
gtk_init ();
/* Get the list of supported formats with GDK_DEBUG=opengl */
gdk_display_get_dmabuf_formats (gdk_display_get_default ());
texture = make_dmabuf_texture (filename, format, disjoint);
if (save_filename)
gdk_texture_save_to_png (texture, save_filename);
window = gtk_window_new ();
gtk_window_set_decorated (GTK_WINDOW (window), decorated);
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));
gtk_window_set_child (GTK_WINDOW (window), picture);
gtk_window_present (GTK_WINDOW (window));
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
g_main_context_iteration (NULL, TRUE);
return 0;
}
-257
View File
@@ -1,257 +0,0 @@
#include <gtk/gtk.h>
#include "gtk/gtkwidgetprivate.h"
#include "gdk/gdksurfaceprivate.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/dma-heap.h>
#include <drm_fourcc.h>
static int dma_heap_fd = -1;
static gboolean
initialize_dma_heap (void)
{
dma_heap_fd = open ("/dev/dma_heap/system", O_RDONLY | O_CLOEXEC);
return dma_heap_fd != -1;
}
static int
allocate_dma_buf (gsize size)
{
struct dma_heap_allocation_data heap_data;
int ret;
heap_data.len = size;
heap_data.fd = 0;
heap_data.fd_flags = O_RDWR | O_CLOEXEC;
heap_data.heap_flags = 0;
ret = ioctl (dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &heap_data);
if (ret)
g_error ("dma-buf allocation failed");
return heap_data.fd;
}
static void
free_dmabuf (gpointer data)
{
close (GPOINTER_TO_INT (data));
}
static GdkTexture *
make_dmabuf_color_texture (int width,
int height,
GdkRGBA *color)
{
int fd;
guchar *buf;
GdkDmabufTextureBuilder *builder;
GdkTexture *texture;
gsize stride, size;
GError *error = NULL;
stride = width * 4;
size = height * stride;
fd = allocate_dma_buf (size);
buf = mmap (NULL, size, PROT_WRITE, MAP_SHARED, fd, 0);
for (gsize i = 0; i < width * height * 4; i += 4)
{
buf[i] = 255 * color->blue;
buf[i + 1] = 255 * color->green;
buf[i + 2] = 255 * color->red;
buf[i + 3] = 255 * color->alpha;
}
munmap (buf, size);
builder = gdk_dmabuf_texture_builder_new ();
gdk_dmabuf_texture_builder_set_display (builder, gdk_display_get_default ());
gdk_dmabuf_texture_builder_set_width (builder, width);
gdk_dmabuf_texture_builder_set_height (builder, height);
gdk_dmabuf_texture_builder_set_fourcc (builder, DRM_FORMAT_ARGB8888);
gdk_dmabuf_texture_builder_set_modifier (builder, DRM_FORMAT_MOD_LINEAR);
gdk_dmabuf_texture_builder_set_n_planes (builder, 1);
gdk_dmabuf_texture_builder_set_fd (builder, 0, fd);
gdk_dmabuf_texture_builder_set_offset (builder, 0, 0);
gdk_dmabuf_texture_builder_set_stride (builder, 0, stride);
texture = gdk_dmabuf_texture_builder_build (builder, free_dmabuf, GINT_TO_POINTER (fd), &error);
if (texture == NULL)
g_error ("%s", error->message);
g_object_unref (builder);
return texture;
}
static GdkTexture *
make_shm_color_texture (int width,
int height,
GdkRGBA *color)
{
cairo_surface_t *surface;
cairo_t *cr;
guchar *data;
gsize stride;
GBytes *bytes;
GdkTexture *texture;
stride = 4 * width;
data = g_new (guchar, stride * height);
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
width, height,
stride);
cr = cairo_create (surface);
gdk_cairo_set_source_rgba (cr, color);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (surface);
bytes = g_bytes_new_take (data, stride * height);
texture = gdk_memory_texture_new (width, height, GDK_MEMORY_DEFAULT, bytes, stride);
g_bytes_unref (bytes);
return texture;
}
static GdkTexture *
make_color_texture (int width,
int height,
GdkRGBA *color)
{
if (dma_heap_fd != -1)
return make_dmabuf_color_texture (width, height, color);
else
return make_shm_color_texture (width, height, color);
}
static GdkSubsurface *
add_subsurface (GtkWidget *window,
GdkRGBA *color,
const graphene_rect_t *rect)
{
GdkSurface *surface;
GdkSubsurface *subsurface;
GdkTexture *texture;
surface = gtk_widget_get_surface (GTK_WIDGET (window));
subsurface = gdk_surface_create_subsurface (surface);
texture = make_color_texture (20, 20, color);
gdk_subsurface_attach (subsurface, texture, rect);
g_object_unref (texture);
return subsurface;
}
static GdkSubsurface *red, *blue;
static void red_above_blue (GtkButton *button) { gdk_subsurface_place_above (red, blue); }
static void red_below_blue (GtkButton *button) { gdk_subsurface_place_below (red, blue); }
static void blue_above_red (GtkButton *button) { gdk_subsurface_place_above (blue, red); }
static void blue_below_red (GtkButton *button) { gdk_subsurface_place_below (blue, red); }
static void red_above_main (GtkButton *button) { gdk_subsurface_place_above (red, NULL); }
static void red_below_main (GtkButton *button) { gdk_subsurface_place_below (red, NULL); }
static void blue_above_main (GtkButton *button) { gdk_subsurface_place_above (blue, NULL); }
static void blue_below_main (GtkButton *button) { gdk_subsurface_place_below (blue, NULL); }
static GtkWidget *
make_button (const char *name, gpointer cb)
{
GtkWidget *button;
button = gtk_button_new_with_label (name);
g_signal_connect (button, "clicked", G_CALLBACK (cb), NULL);
return button;
}
static void
change_colors (GtkButton *button)
{
GdkRGBA color;
GdkTexture *texture;
color.red = g_random_double_range (0.5, 1);
color.green = g_random_double_range (0, 0.5);
color.blue = g_random_double_range (0, 0.5);
color.alpha = 1;
texture = make_color_texture (20, 20, &color);
gdk_subsurface_attach (red, texture, &GRAPHENE_RECT_INIT (200, 100, 50, 50));
g_object_unref (texture);
color.red = g_random_double_range (0, 0.5);
color.green = g_random_double_range (0, 0.5);
color.blue = g_random_double_range (0.5, 1);
color.alpha = 1;
texture = make_color_texture (20, 20, &color);
gdk_subsurface_attach (blue, texture, &GRAPHENE_RECT_INIT (180, 120, 100, 20));
g_object_unref (texture);
}
static GtkWidget *
make_buttons (void)
{
GtkWidget *box;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_append (GTK_BOX (box), make_button ("Red above blue", red_above_blue));
gtk_box_append (GTK_BOX (box), make_button ("Red below blue", red_below_blue));
gtk_box_append (GTK_BOX (box), make_button ("Red above main", red_above_main));
gtk_box_append (GTK_BOX (box), make_button ("Red below main", red_below_main));
gtk_box_append (GTK_BOX (box), make_button ("Blue above red", blue_above_red));
gtk_box_append (GTK_BOX (box), make_button ("Blue below red", blue_below_red));
gtk_box_append (GTK_BOX (box), make_button ("Blue above main", blue_above_main));
gtk_box_append (GTK_BOX (box), make_button ("Blue below main", blue_below_main));
gtk_box_append (GTK_BOX (box), make_button ("Change colors", change_colors));
return box;
}
int
main (int argc, char *argv[])
{
GtkWidget *window, *box;
gtk_init ();
window = gtk_window_new ();
gtk_window_set_default_size (GTK_WINDOW (window), 210, -1);
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_widget_realize (window);
if (initialize_dma_heap ())
g_print ("Using dambufs\n");
else
g_print ("Failed to initialize dma-heap, using shm\n");
red = add_subsurface (window, &(GdkRGBA) { 1, 0, 0, 1 }, &GRAPHENE_RECT_INIT (200, 100, 50, 50));
blue = add_subsurface (window, &(GdkRGBA) { 0, 0, 1, 1 }, &GRAPHENE_RECT_INIT (180, 120, 100, 20));
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
gtk_box_append (GTK_BOX (box), make_buttons ());
gtk_window_present (GTK_WINDOW (window));
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
g_main_context_iteration (NULL, TRUE);
return 0;
}
-295
View File
@@ -1,295 +0,0 @@
#include "config.h"
#include <gtk/gtk.h>
#include <gdk/gdkdisplayprivate.h>
#include <gdk/gdkglcontextprivate.h>
#include <gdk/gdkdmabuftextureprivate.h>
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
static void
test_dmabuf_formats (void)
{
GdkDisplay *display;
GdkDmabufFormats *formats;
display = gdk_display_get_default ();
formats = gdk_display_get_dmabuf_formats (display);
#ifdef HAVE_DMABUF
/* We always have basic linear formats */
g_assert_true (gdk_dmabuf_formats_get_n_formats (formats) >= 6);
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_ARGB8888, DRM_FORMAT_MOD_LINEAR));
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_RGBA8888, DRM_FORMAT_MOD_LINEAR));
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_BGRA8888, DRM_FORMAT_MOD_LINEAR));
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_ABGR16161616F, DRM_FORMAT_MOD_LINEAR));
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_RGB888, DRM_FORMAT_MOD_LINEAR));
g_assert_true (gdk_dmabuf_formats_contains (formats, DRM_FORMAT_BGR888, DRM_FORMAT_MOD_LINEAR));
#else
g_assert_true (gdk_dmabuf_formats_get_n_formats (formats) == 0);
#endif
}
static cairo_surface_t *
make_surface (int width,
int height)
{
cairo_surface_t *surface;
cairo_t *cr;
guchar *data;
int stride;
stride = width * 4;
data = g_malloc (stride * height);
surface = cairo_image_surface_create_for_data (data,
CAIRO_FORMAT_ARGB32,
width, height, stride);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_paint (cr);
cairo_destroy (cr);
return surface;
}
static unsigned int
upload_gl_texture (GdkGLContext *context,
cairo_surface_t *surface)
{
unsigned int id;
int width, height;
width = cairo_image_surface_get_width (surface);
height = cairo_image_surface_get_height (surface);
glGenTextures (1, &id);
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, id);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE,
cairo_image_surface_get_data (surface));
g_assert_true (glGetError () == GL_NO_ERROR);
return id;
}
static void
export_dmabuf (GdkGLContext *context,
unsigned int texture_id,
GdkDmabuf *dmabuf)
{
gboolean ret;
ret = gdk_gl_context_export_dmabuf (context, texture_id, dmabuf);
g_assert_true (ret);
}
static void
free_dmabuf (gpointer data)
{
GdkDmabuf *dmabuf = data;
for (int i = 0; i < dmabuf->n_planes; i++)
close (dmabuf->planes[i].fd);
g_free (dmabuf);
}
static GdkTexture *
make_dmabuf_texture (GdkDisplay *display,
int width,
int height,
gboolean premultiplied,
GdkDmabuf *dmabuf)
{
GdkDmabufTextureBuilder *builder;
GdkTexture *texture;
GdkDmabuf *dmabuf2;
builder = gdk_dmabuf_texture_builder_new ();
gdk_dmabuf_texture_builder_set_display (builder, display);
gdk_dmabuf_texture_builder_set_width (builder, width);
gdk_dmabuf_texture_builder_set_premultiplied (builder, premultiplied);
gdk_dmabuf_texture_builder_set_height (builder, height);
gdk_dmabuf_texture_builder_set_fourcc (builder, dmabuf->fourcc);
gdk_dmabuf_texture_builder_set_modifier (builder, dmabuf->modifier);
gdk_dmabuf_texture_builder_set_n_planes (builder, dmabuf->n_planes);
for (int i = 0; i < dmabuf->n_planes; i++)
{
gdk_dmabuf_texture_builder_set_fd (builder, i, dmabuf->planes[i].fd);
gdk_dmabuf_texture_builder_set_stride (builder, i, dmabuf->planes[i].stride);
gdk_dmabuf_texture_builder_set_offset (builder, i, dmabuf->planes[i].offset);
}
dmabuf2 = g_new (GdkDmabuf, 1);
memcpy (dmabuf2, dmabuf, sizeof (GdkDmabuf));
texture = gdk_dmabuf_texture_builder_build (builder, free_dmabuf, dmabuf2, NULL);
g_assert_true (texture != NULL);
g_object_unref (builder);
return texture;
}
/* Make a dmabuftexture by exporting a GL texture,
* then download it and compare with the original
*/
static void
test_dmabuf_export (void)
{
GdkDisplay *display;
GdkGLContext *context;
GError *error = NULL;
cairo_surface_t *surface;
unsigned int texture_id;
GdkDmabuf dmabuf;
GdkTexture *texture;
guchar *data;
display = gdk_display_get_default ();
if (!gdk_display_prepare_gl (display, &error))
{
g_test_skip_printf ("no GL support: %s", error->message);
g_clear_error (&error);
return;
}
if (gdk_dmabuf_formats_get_n_formats (gdk_display_get_dmabuf_formats (display)) == 0)
{
g_test_skip_printf ("no dmabuf support");
return;
}
context = gdk_display_create_gl_context (display, &error);
g_assert_nonnull (context);
g_assert_no_error (error);
gdk_gl_context_realize (context, &error);
g_assert_no_error (error);
surface = make_surface (64, 64);
gdk_gl_context_make_current (context);
texture_id = upload_gl_texture (context, surface);
export_dmabuf (context, texture_id, &dmabuf);
texture = make_dmabuf_texture (display, 64, 64, TRUE, &dmabuf);
data = g_malloc (64 * 64 * 4);
gdk_texture_download (texture, data, 64 * 4);
g_assert_true (memcmp (cairo_image_surface_get_data (surface), data, 64 * 64 * 4) == 0);
g_free (data);
g_object_unref (texture);
cairo_surface_destroy (surface);
gdk_gl_context_make_current (context);
glDeleteTextures (1, &texture_id);
g_object_unref (context);
}
/* Make a dmabuftexture by exporting a GL texture,
* then import it into another GL context, download
* the resulting texture, and compare it to the original.
*/
static void
test_dmabuf_import (void)
{
GdkDisplay *display;
GdkGLContext *context;
GdkGLContext *context2;
GError *error = NULL;
cairo_surface_t *surface;
unsigned int texture_id;
unsigned int texture_id2;
GdkDmabuf dmabuf;
const GdkDmabuf *dmabuf2;
GdkTexture *texture;
GdkTexture *texture2;
GdkGLTextureBuilder *builder;
guchar *data;
display = gdk_display_get_default ();
if (!gdk_display_prepare_gl (display, &error))
{
g_test_skip_printf ("no GL support: %s", error->message);
g_clear_error (&error);
return;
}
if (gdk_dmabuf_formats_get_n_formats (gdk_display_get_dmabuf_formats (display)) == 0)
{
g_test_skip_printf ("no dmabuf support");
return;
}
context = gdk_display_create_gl_context (display, &error);
g_assert_nonnull (context);
g_assert_no_error (error);
gdk_gl_context_realize (context, &error);
g_assert_no_error (error);
surface = make_surface (64, 64);
gdk_gl_context_make_current (context);
texture_id = upload_gl_texture (context, surface);
export_dmabuf (context, texture_id, &dmabuf);
texture = make_dmabuf_texture (display, 64, 64, TRUE, &dmabuf);
context2 = gdk_display_create_gl_context (display, &error);
g_assert_nonnull (context2);
g_assert_no_error (error);
gdk_gl_context_realize (context2, &error);
g_assert_no_error (error);
dmabuf2 = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
texture_id2 = gdk_gl_context_import_dmabuf (context2, 64, 64, dmabuf2, GL_TEXTURE_2D);
builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, context2);
gdk_gl_texture_builder_set_id (builder, texture_id2);
gdk_gl_texture_builder_set_width (builder, 64);
gdk_gl_texture_builder_set_height (builder, 64);
gdk_gl_texture_builder_set_format (builder, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED);
texture2 = gdk_gl_texture_builder_build (builder, NULL, NULL);
data = g_malloc (64 * 64 * 4);
gdk_texture_download (texture2, data, 64 * 4);
g_assert_true (memcmp (cairo_image_surface_get_data (surface), data, 64 * 64 * 4) == 0);
g_free (data);
g_object_unref (texture);
g_object_unref (texture2);
gdk_gl_context_make_current (context);
glDeleteTextures (1, &texture_id);
g_object_unref (context);
g_object_unref (context2);
}
int
main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/dmabuf/formats", test_dmabuf_formats);
g_test_add_func ("/dmabuf/export", test_dmabuf_export);
g_test_add_func ("/dmabuf/import", test_dmabuf_import);
return g_test_run ();
}
+39 -50
View File
@@ -102,15 +102,10 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A32_FLOAT:
@@ -150,15 +145,10 @@ gdk_memory_format_get_channel_type (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
case GDK_MEMORY_G8:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
@@ -207,15 +197,10 @@ gdk_memory_format_n_colors (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
@@ -257,16 +242,11 @@ gdk_memory_format_has_alpha (GdkMemoryFormat format)
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_G8:
case GDK_MEMORY_G16:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
return FALSE;
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
@@ -302,7 +282,6 @@ gdk_memory_format_is_premultiplied (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
@@ -323,10 +302,6 @@ gdk_memory_format_is_premultiplied (GdkMemoryFormat format)
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT:
@@ -346,7 +321,45 @@ gdk_memory_format_is_premultiplied (GdkMemoryFormat format)
static gboolean
gdk_memory_format_is_deep (GdkMemoryFormat format)
{
return gdk_memory_format_get_channel_type (format) != CHANNEL_UINT_8;
switch (format)
{
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_G8A8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8:
case GDK_MEMORY_G8:
case GDK_MEMORY_G8A8:
case GDK_MEMORY_A8:
return FALSE;
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_G16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_R32G32B32_FLOAT:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT:
case GDK_MEMORY_G16:
case GDK_MEMORY_G16A16:
case GDK_MEMORY_A16:
case GDK_MEMORY_A16_FLOAT:
case GDK_MEMORY_A32_FLOAT:
return TRUE;
case GDK_MEMORY_N_FORMATS:
default:
g_assert_not_reached ();
return FALSE;
}
}
static gboolean
@@ -360,7 +373,6 @@ gdk_memory_format_pixel_equal (GdkMemoryFormat format,
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_B8G8R8A8:
@@ -373,14 +385,6 @@ gdk_memory_format_pixel_equal (GdkMemoryFormat format,
case GDK_MEMORY_G8A8_PREMULTIPLIED:
return memcmp (pixel1, pixel2, gdk_memory_format_bytes_per_pixel (format)) == 0;
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_R8G8B8X8:
return memcmp (pixel1, pixel2, 3) == 0;
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_X8B8G8R8:
return memcmp (pixel1 + 1, pixel2 + 1, 3) == 0;
case GDK_MEMORY_R16G16B16:
case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
@@ -577,9 +581,6 @@ texture_builder_set_pixel (TextureBuilder *builder,
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
set_pixel_u8 (data, 0, 1, 2, 3, TRUE, color);
break;
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
set_pixel_u8 (data, 3, 2, 1, 0, TRUE, color);
break;
case GDK_MEMORY_B8G8R8A8:
set_pixel_u8 (data, 2, 1, 0, 3, FALSE, color);
break;
@@ -592,18 +593,6 @@ texture_builder_set_pixel (TextureBuilder *builder,
case GDK_MEMORY_A8B8G8R8:
set_pixel_u8 (data, 3, 2, 1, 0, FALSE, color);
break;
case GDK_MEMORY_B8G8R8X8:
set_pixel_u8 (data, 2, 1, 0, -1, TRUE, color);
break;
case GDK_MEMORY_X8R8G8B8:
set_pixel_u8 (data, 1, 2, 3, -1, TRUE, color);
break;
case GDK_MEMORY_R8G8B8X8:
set_pixel_u8 (data, 0, 1, 2, -1, TRUE, color);
break;
case GDK_MEMORY_X8B8G8R8:
set_pixel_u8 (data, 3, 2, 1, -1, TRUE, color);
break;
case GDK_MEMORY_R8G8B8:
set_pixel_u8 (data, 0, 1, 2, -1, TRUE, color);
break;
+6 -11
View File
@@ -52,24 +52,19 @@ foreach t : tests
endforeach
internal_tests = [
{ 'name': 'image' },
{ 'name': 'texture' },
{ 'name': 'gltexture' },
{ 'name': 'dmabuftexture', 'suites': 'failing' },
'image',
'texture',
'gltexture',
]
foreach t : internal_tests
test_name = t.get('name')
test_exe = executable(test_name,
sources: '@0@.c'.format(test_name),
test_exe = executable(t, '@0@.c'.format(t),
c_args: common_cflags + ['-DGTK_COMPILATION'],
dependencies: libgtk_static_dep,
install: false,
)
suites = ['gdk'] + t.get('suites', [])
test(test_name, test_exe,
test(t, test_exe,
args: [ '--tap', '-k' ],
protocol: 'tap',
env: [
@@ -77,6 +72,6 @@ foreach t : internal_tests
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
'DBUS_SESSION_BUS_ADDRESS=',
],
suite: suites,
suite: 'gdk',
)
endforeach
@@ -1,10 +1 @@
linear-gradient {
stops: 0.2 red,
0.2 blue,
0.4 blue,
0.4 yellow,
0.6 yellow,
0.6 lime,
0.8 lime,
0.8 teal;
}
linear-gradient { }
Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 203 B

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