Compare commits

..

1 Commits

Author SHA1 Message Date
Emmanuele Bassi
2d370768db Update CODEOWNERS file
GitLab has standardised the CODEOWNERS file and made it available on
self-hosted instances.
2023-10-19 13:23:46 +01:00
67 changed files with 1138 additions and 4748 deletions

30
NEWS
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 Overview of Changes in 4.13.1, 28-09-2023
========================================= =========================================

View File

@@ -2,8 +2,9 @@
# a merge request for files listed here, please add the following people to # a merge request for files listed here, please add the following people to
# the list of reviewers # the list of reviewers
# The syntax of this file is similar to the GitHub CODEOWNERS file: # The syntax of this file is defined in the GitLab documentation:
# https://help.github.com/articles/about-codeowners/ # https://docs.gitlab.com/ee/user/project/codeowners/reference.html
#
# Which, in turn, is similar to the .gitignore and .gitattributes files: # Which, in turn, is similar to the .gitignore and .gitattributes files:
# #
# - comments start with `#` # - comments start with `#`
@@ -14,64 +15,61 @@
# If you want to be responsible for code reviews in specific sections of # If you want to be responsible for code reviews in specific sections of
# the GTK code base, add yourself here. # the GTK code base, add yourself here.
# Maintainer [Maintainer]
* @matthiasc * @matthiasc
# Build system [Build system]
meson.build @ebassi @nirbheek meson.build @ebassi @nirbheek @xclaesse
*.py @ebassi *.py @ebassi
# CSS [CSS]
gtk/gtkcss*.[ch] @otte @baedert /gtk/gtkcss*.[ch] @otte @matthiasc
gtk/gtkstyle*.[ch] @otte @baedert /gtk/gtkstyle*.[ch] @otte @matthiasc
# Gestures [Gestures]
gtk/gtkeventcontroller* @carlosg /gtk/gtkeventcontroller* @carlosg
gtk/gtkgesture*.[ch] @carlosg /gtk/gtkgesture*.[ch] @carlosg
# GtkFileChooser [Input methods]
gtk/gtkfilechooser* @federico @ebassi /gtk/gtkimcontext* @carlosg
gtk/gtkfilesystem* @federico @ebassi
gtk/gtkfilefilter* @federico @ebassi
# GtkFontChooser [Media]
gtk/gtkfontchooser* @matthiasc /gtk/gtkmedia* @otte
# Input methods [GSK]
gtk/gtkimcontext* @carlosg /gsk/ @otte @chergert @ebassi
# Media [GL rendering]
gtk/gtkmedia* @otte /gsk/gl/ @otte @chergert
# GSK [Vulkan rendering]
gsk @otte @baedert @ebassi /gsk/vulkan @otte
# GL rendering [Documentation]
gsk/gl @baedert @ebassi /docs/ @ebassi @dboles
README.md @ebassi
CONTRIBUTING.md @ebassi @matthiasc
# Vulkan rendering [Wayland]
gsk/vulkan /gdk/wayland @jadahl
# Documentation [X11]
docs/ @ebassi @dboles /gdk/x11 @ofourdan @matthiasc @carlosg
# Wayland [macOS]
gdk/wayland @jadahl /gdk/macos @chergert
# X11 [Themes]
gdk/x11 @ofourdan @matthiasc /gtk/themes @lapoc @jimmac
# Themes [Inspector]
gtk/themes @lapoc @jimmac /gtk/inspector @otte @matthiasc
# Inspector [Layout managers]
gtk/inspector @otte @matthiasc /gtk/gtklayout* @ebassi
/gtk/gtkconstraint* @ebassi
# Layout managers [Accessibility]
gtk/gtklayout* @ebassi /gtk/gtkaccessible*.[ch] @ebassi @tyrylu @matthiasc
gtk/gtkconstraint* @ebassi /gtk/gtkatcontext*.[ch] @ebassi @tyrylu @matthiasc
/gtk/a11y @ebassi @tyrylu
# Accessibility
gtk/gtkaccessible*.[ch] @ebassi
gtk/gtkatcontext*.[ch] @ebassi
gtk/a11y @ebassi

View File

@@ -391,9 +391,6 @@ gdk_display_dispose (GObject *object)
g_queue_clear (&display->queued_events); 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); g_clear_object (&priv->gl_context);
#ifdef HAVE_EGL #ifdef HAVE_EGL
g_clear_pointer (&priv->egl_display, eglTerminate); g_clear_pointer (&priv->egl_display, eglTerminate);
@@ -1773,10 +1770,6 @@ gdk_display_init_egl (GdkDisplay *self,
epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context"); epoxy_has_egl_extension (priv->egl_display, "EGL_KHR_no_config_context");
self->have_egl_pixel_format_float = self->have_egl_pixel_format_float =
epoxy_has_egl_extension (priv->egl_display, "EGL_EXT_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) if (self->have_egl_no_config_context)
priv->egl_config_high_depth = gdk_display_create_egl_config (self, priv->egl_config_high_depth = gdk_display_create_egl_config (self,
@@ -1846,7 +1839,7 @@ gdk_display_get_egl_display (GdkDisplay *self)
#endif #endif
} }
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
static void static void
gdk_display_add_dmabuf_downloader (GdkDisplay *display, gdk_display_add_dmabuf_downloader (GdkDisplay *display,
const GdkDmabufDownloader *downloader, const GdkDmabufDownloader *downloader,
@@ -1854,8 +1847,7 @@ gdk_display_add_dmabuf_downloader (GdkDisplay *display,
{ {
gsize i; gsize i;
if (!downloader->add_formats (downloader, display, builder)) downloader->add_formats (downloader, display, builder);
return;
/* dmabuf_downloaders is NULL-terminated */ /* dmabuf_downloaders is NULL-terminated */
for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++) for (i = 0; i < G_N_ELEMENTS (display->dmabuf_downloaders) - 1; i++)
@@ -1874,39 +1866,27 @@ gdk_display_add_dmabuf_downloader (GdkDisplay *display,
* using the relevant EGL extensions, and download it into a memory * using the relevant EGL extensions, and download it into a memory
* texture, possibly doing format conversion with shaders (in GSK). * texture, possibly doing format conversion with shaders (in GSK).
*/ */
void static void
gdk_display_init_dmabuf (GdkDisplay *self) init_dmabuf_formats (GdkDisplay *display)
{ {
GdkDmabufFormatsBuilder *builder; GdkDmabufFormatsBuilder *builder;
if (self->dmabuf_formats != NULL) if (display->dmabuf_formats != NULL)
return; return;
GDK_DISPLAY_DEBUG (self, DMABUF,
"Beginning initialization of dmabuf support");
builder = gdk_dmabuf_formats_builder_new (); builder = gdk_dmabuf_formats_builder_new ();
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
if (!GDK_DEBUG_CHECK (DMABUF_DISABLE)) if (!GDK_DEBUG_CHECK (DMABUF_DISABLE))
{ {
gdk_display_prepare_gl (self, NULL); gdk_display_prepare_gl (display, NULL);
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_direct_downloader (), builder); gdk_display_add_dmabuf_downloader (display, 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 #endif
self->dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (builder); display->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: * gdk_display_get_dmabuf_formats:
@@ -1917,9 +1897,6 @@ gdk_display_init_dmabuf (GdkDisplay *self)
* GTK may use OpenGL or Vulkan to support some formats. * GTK may use OpenGL or Vulkan to support some formats.
* Calling this function will then initialize them if they aren't yet. * Calling this function will then initialize them if they aren't yet.
* *
* The formats returned by this function can be used for negotiating
* buffer formats with producers such as v4l, pipewire or GStreamer.
*
* Returns: (transfer none): a `GdkDmabufFormats` object * Returns: (transfer none): a `GdkDmabufFormats` object
* *
* Since: 4.14 * Since: 4.14
@@ -1927,7 +1904,7 @@ gdk_display_init_dmabuf (GdkDisplay *self)
GdkDmabufFormats * GdkDmabufFormats *
gdk_display_get_dmabuf_formats (GdkDisplay *display) gdk_display_get_dmabuf_formats (GdkDisplay *display)
{ {
gdk_display_init_dmabuf (display); init_dmabuf_formats (display);
return display->dmabuf_formats; return display->dmabuf_formats;
} }

View File

@@ -114,15 +114,9 @@ struct _GdkDisplay
guint have_egl_buffer_age : 1; guint have_egl_buffer_age : 1;
guint have_egl_no_config_context : 1; guint have_egl_no_config_context : 1;
guint have_egl_pixel_format_float : 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; GdkDmabufFormats *dmabuf_formats;
const GdkDmabufDownloader *dmabuf_downloaders[4]; const GdkDmabufDownloader *dmabuf_downloaders[4];
/* Cached data the EGL dmabuf downloader */
gpointer egl_gsk_renderer;
GdkDmabufFormats *egl_external_formats;
}; };
struct _GdkDisplayClass struct _GdkDisplayClass
@@ -217,8 +211,6 @@ gulong _gdk_display_get_next_serial (GdkDisplay *display
void _gdk_display_pause_events (GdkDisplay *display); void _gdk_display_pause_events (GdkDisplay *display);
void _gdk_display_unpause_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, GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
GError **error); GError **error);

View File

@@ -24,338 +24,31 @@
#include "gdkdmabuftextureprivate.h" #include "gdkdmabuftextureprivate.h"
#include "gdkmemoryformatprivate.h" #include "gdkmemoryformatprivate.h"
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include <drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <epoxy/egl.h> #include <epoxy/egl.h>
typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo; typedef struct _GdkDrmFormatInfo GdkDrmFormatInfo;
struct _GdkDrmFormatInfo struct _GdkDrmFormatInfo
{ {
guint32 fourcc; guint32 fourcc;
GdkMemoryFormat premultiplied_memory_format; GdkMemoryFormat premultiplied_memory_format;
GdkMemoryFormat unpremultiplied_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 static GdkDrmFormatInfo supported_formats[] = {
download_memcpy (guchar *dst_data, { DRM_FORMAT_ARGB8888, GDK_MEMORY_A8R8G8B8_PREMULTIPLIED, GDK_MEMORY_A8R8G8B8 },
gsize dst_stride, { DRM_FORMAT_RGBA8888, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, GDK_MEMORY_R8G8B8A8 },
GdkMemoryFormat dst_format, { DRM_FORMAT_BGRA8888, GDK_MEMORY_B8G8R8A8_PREMULTIPLIED, GDK_MEMORY_B8G8R8A8 },
gsize width, { DRM_FORMAT_ABGR16161616F, GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED, GDK_MEMORY_R16G16B16A16_FLOAT },
gsize height, { DRM_FORMAT_RGB888, GDK_MEMORY_R8G8B8, GDK_MEMORY_R8G8B8 },
const GdkDmabuf *dmabuf, { DRM_FORMAT_BGR888, GDK_MEMORY_B8G8R8, GDK_MEMORY_B8G8R8 },
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 GdkDrmFormatInfo *
//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) get_drm_format_info (guint32 fourcc)
{ {
for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++) for (int i = 0; i < G_N_ELEMENTS (supported_formats); i++)
@@ -367,7 +60,7 @@ get_drm_format_info (guint32 fourcc)
return NULL; return NULL;
} }
static gboolean static void
gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader, gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
GdkDisplay *display, GdkDisplay *display,
GdkDmabufFormatsBuilder *builder) GdkDmabufFormatsBuilder *builder)
@@ -376,16 +69,10 @@ gdk_dmabuf_direct_downloader_add_formats (const GdkDmabufDownloader *downloader,
for (i = 0; i < G_N_ELEMENTS (supported_formats); 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, gdk_dmabuf_formats_builder_add_format (builder,
supported_formats[i].fourcc, supported_formats[i].fourcc,
DRM_FORMAT_MOD_LINEAR); DRM_FORMAT_MOD_LINEAR);
} }
return TRUE;
} }
static gboolean static gboolean
@@ -396,7 +83,7 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
GdkMemoryFormat *out_format, GdkMemoryFormat *out_format,
GError **error) GError **error)
{ {
const GdkDrmFormatInfo *info; GdkDrmFormatInfo *info;
info = get_drm_format_info (dmabuf->fourcc); info = get_drm_format_info (dmabuf->fourcc);
@@ -418,6 +105,14 @@ gdk_dmabuf_direct_downloader_supports (const GdkDmabufDownloader *downloader,
return FALSE; return FALSE;
} }
if (dmabuf->n_planes > 1)
{
g_set_error_literal (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_CREATION_FAILED,
"Multiplanar dmabufs are not supported");
return FALSE;
}
*out_format = premultiplied ? info->premultiplied_memory_format *out_format = premultiplied ? info->premultiplied_memory_format
: info->unpremultiplied_memory_format; : info->unpremultiplied_memory_format;
@@ -429,75 +124,39 @@ gdk_dmabuf_direct_downloader_do_download (GdkTexture *texture,
guchar *data, guchar *data,
gsize stride) gsize stride)
{ {
const GdkDrmFormatInfo *info;
const GdkDmabuf *dmabuf; const GdkDmabuf *dmabuf;
const guchar *src_data[GDK_DMABUF_MAX_PLANES]; gsize size;
gsize sizes[GDK_DMABUF_MAX_PLANES]; unsigned int height;
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, }; gsize src_stride;
gsize i, j; guchar *src_data;
int bpp;
GDK_DEBUG (DMABUF, "Using mmap() and memcpy() for downloading a dmabuf");
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)); dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
info = get_drm_format_info (dmabuf->fourcc); height = gdk_texture_get_height (texture);
bpp = gdk_memory_format_bytes_per_pixel (gdk_texture_get_format (texture));
GDK_DEBUG (DMABUF, src_stride = dmabuf->planes[0].stride;
"Using mmap() and memcpy() for downloading a dmabuf (format %.4s:%#lx)", size = dmabuf->planes[0].stride * height;
(char *)&dmabuf->fourcc, dmabuf->modifier);
for (i = 0; i < dmabuf->n_planes; i++) if (ioctl (dmabuf->planes[0].fd, 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, dmabuf->planes[0].fd, dmabuf->planes[0].offset);
if (stride == src_stride)
memcpy (data, src_data, size);
else
{ {
for (j = 0; j < i; j++) for (unsigned int i = 0; i < height; i++)
{ memcpy (data + i * stride, src_data + i * src_stride, height * bpp);
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, munmap (src_data, size);
stride,
gdk_texture_get_format (texture),
gdk_texture_get_width (texture),
gdk_texture_get_height (texture),
dmabuf,
src_data,
sizes);
out: if (ioctl (dmabuf->planes[0].fd, DMA_BUF_IOCTL_SYNC, &(struct dma_buf_sync) { DMA_BUF_SYNC_END|DMA_BUF_SYNC_READ }) < 0)
for (i = 0; i < dmabuf->n_planes; i++) g_warning ("Failed to sync dma-buf: %s", g_strerror (errno));
{
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 static void
@@ -513,14 +172,16 @@ gdk_dmabuf_direct_downloader_download (const GdkDmabufDownloader *downloader,
gdk_dmabuf_direct_downloader_do_download (texture, data, stride); gdk_dmabuf_direct_downloader_do_download (texture, data, stride);
else else
{ {
const GdkDmabuf *dmabuf;
unsigned int width, height; unsigned int width, height;
guchar *src_data; guchar *src_data;
gsize src_stride; gsize src_stride;
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
width = gdk_texture_get_width (texture); width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture); height = gdk_texture_get_height (texture);
src_stride = width * gdk_memory_format_bytes_per_pixel (src_format); src_stride = dmabuf->planes[0].stride;
src_data = g_new (guchar, src_stride * height); src_data = g_new (guchar, src_stride * height);
gdk_dmabuf_direct_downloader_do_download (texture, src_data, src_stride); gdk_dmabuf_direct_downloader_do_download (texture, src_data, src_stride);
@@ -537,7 +198,6 @@ const GdkDmabufDownloader *
gdk_dmabuf_get_direct_downloader (void) gdk_dmabuf_get_direct_downloader (void)
{ {
static const GdkDmabufDownloader downloader = { static const GdkDmabufDownloader downloader = {
"mmap",
gdk_dmabuf_direct_downloader_add_formats, gdk_dmabuf_direct_downloader_add_formats,
gdk_dmabuf_direct_downloader_supports, gdk_dmabuf_direct_downloader_supports,
gdk_dmabuf_direct_downloader_download, gdk_dmabuf_direct_downloader_download,
@@ -546,200 +206,4 @@ gdk_dmabuf_get_direct_downloader (void)
return &downloader; return &downloader;
} }
/* #endif /* HAVE_LINUX_DMA_BUF_H */
* 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 */

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 */

View File

@@ -22,10 +22,6 @@
#include "gdkdmabufformatsprivate.h" #include "gdkdmabufformatsprivate.h"
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#define GDK_ARRAY_NAME gdk_dmabuf_formats_builder #define GDK_ARRAY_NAME gdk_dmabuf_formats_builder
#define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder #define GDK_ARRAY_TYPE_NAME GdkDmabufFormatsBuilder
#define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat #define GDK_ARRAY_ELEMENT_TYPE GdkDmabufFormat
@@ -121,12 +117,6 @@ gdk_dmabuf_formats_builder_add_format (GdkDmabufFormatsBuilder *self,
guint32 fourcc, guint32 fourcc,
guint64 modifier) 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 }); gdk_dmabuf_formats_builder_append (self, &(GdkDmabufFormat) { fourcc, modifier });
} }

View File

@@ -21,10 +21,10 @@ struct _GdkDmabuf
struct _GdkDmabufDownloader struct _GdkDmabufDownloader
{ {
const char *name; void (* add_formats) (const GdkDmabufDownloader *downloader,
gboolean (* add_formats) (const GdkDmabufDownloader *downloader,
GdkDisplay *display, GdkDisplay *display,
GdkDmabufFormatsBuilder *builder); GdkDmabufFormatsBuilder *builder);
gboolean (* supports) (const GdkDmabufDownloader *downloader, gboolean (* supports) (const GdkDmabufDownloader *downloader,
GdkDisplay *display, GdkDisplay *display,
const GdkDmabuf *dmabuf, const GdkDmabuf *dmabuf,
@@ -38,17 +38,7 @@ struct _GdkDmabufDownloader
gsize stride); gsize stride);
}; };
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
const GdkDmabufDownloader *
const GdkDmabufDownloader * gdk_dmabuf_get_direct_downloader (void) G_GNUC_CONST; 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 #endif

View File

@@ -22,17 +22,16 @@
#include "gdkdisplayprivate.h" #include "gdkdisplayprivate.h"
#include "gdkdmabufformatsbuilderprivate.h" #include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabufprivate.h"
#include "gdktextureprivate.h" #include "gdktextureprivate.h"
#include <gdk/gdkglcontext.h> #include <gdk/gdkglcontext.h>
#include <gdk/gdkgltexturebuilder.h> #include <gdk/gdkgltexturebuilder.h>
#include <gdk/gdktexturedownloader.h> #include <gdk/gdktexturedownloader.h>
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include <drm_fourcc.h> #include <drm/drm_fourcc.h>
#include <epoxy/egl.h> #include <epoxy/egl.h>
#endif #endif
@@ -129,28 +128,17 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
gpointer data, gpointer data,
GError **error) GError **error)
{ {
#ifdef HAVE_DMABUF #ifdef HAVE_LINUX_DMA_BUF_H
GdkDmabufTexture *self; GdkDmabufTexture *self;
GdkTexture *update_texture; GdkTexture *update_texture;
GdkDisplay *display; GdkDisplay *display;
GdkDmabuf dmabuf; const GdkDmabuf *dmabuf;
GdkMemoryFormat format; GdkMemoryFormat format;
GError *local_error = NULL; GError *local_error = NULL;
int width, height;
gsize i; gsize i;
display = gdk_dmabuf_texture_builder_get_display (builder); display = gdk_dmabuf_texture_builder_get_display (builder);
width = gdk_dmabuf_texture_builder_get_width (builder); dmabuf = gdk_dmabuf_texture_builder_get_dmabuf (builder);
height = gdk_dmabuf_texture_builder_get_height (builder);
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++) for (i = 0; display->dmabuf_downloaders[i] != NULL; i++)
{ {
@@ -159,7 +147,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i], if (display->dmabuf_downloaders[i]->supports (display->dmabuf_downloaders[i],
display, display,
&dmabuf, dmabuf,
gdk_dmabuf_texture_builder_get_premultiplied (builder), gdk_dmabuf_texture_builder_get_premultiplied (builder),
&format, &format,
local_error ? NULL : &local_error)) local_error ? NULL : &local_error))
@@ -172,23 +160,15 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
return NULL; 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);
self = g_object_new (GDK_TYPE_DMABUF_TEXTURE, self = g_object_new (GDK_TYPE_DMABUF_TEXTURE,
"width", width, "width", gdk_dmabuf_texture_builder_get_width (builder),
"height", height, "height", gdk_dmabuf_texture_builder_get_height (builder),
NULL); NULL);
GDK_TEXTURE (self)->format = format; GDK_TEXTURE (self)->format = format;
g_set_object (&self->display, display); g_set_object (&self->display, display);
self->downloader = display->dmabuf_downloaders[i]; self->downloader = display->dmabuf_downloaders[i];
self->dmabuf = dmabuf; self->dmabuf = *dmabuf;
self->destroy = destroy; self->destroy = destroy;
self->data = data; self->data = data;
@@ -210,7 +190,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
return GDK_TEXTURE (self); return GDK_TEXTURE (self);
#else /* !HAVE_DMABUF */ #else /* !HAVE_LINUX_DMA_BUF_H */
g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE, g_set_error_literal (error, GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_NOT_AVAILABLE,
"dmabuf support disabled at compile-time."); "dmabuf support disabled at compile-time.");
return NULL; return NULL;

View File

@@ -27,11 +27,6 @@
#include "gdkdmabuftextureprivate.h" #include "gdkdmabuftextureprivate.h"
#include <cairo-gobject.h> #include <cairo-gobject.h>
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#else
#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
#endif
struct _GdkDmabufTextureBuilder struct _GdkDmabufTextureBuilder
@@ -86,7 +81,7 @@ struct _GdkDmabufTextureBuilderClass
* *
* The format of the data (for graphics data, essentially its colorspace) is described * 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 * 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) * [drm/drm_fourcc.h](https://github.com/torvalds/linux/blob/master/include/uapi/drm/drm_fourcc.h)
* and commonly referred to as **_fourcc_** values, since they are identified by 4 ASCII * 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 * 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. * that describes driver-specific details of the memory layout, such as tiling or compression.
@@ -96,12 +91,9 @@ struct _GdkDmabufTextureBuilderClass
* to create the new texture. * to create the new texture.
* *
* The required properties for a dma-buf texture are * The required properties for a dma-buf texture are
* * - The width and height in pixels
* * 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 `fourcc` code and `modifier` which identify the format and memory layout of the dma-buf
*
* * The file descriptor, offset and stride for each of the planes
* *
* `GdkDmabufTextureBuilder` can be used for quick one-shot construction of * `GdkDmabufTextureBuilder` can be used for quick one-shot construction of
* textures as well as kept around and reused to construct multiple textures. * textures as well as kept around and reused to construct multiple textures.
@@ -339,7 +331,7 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
*/ */
properties[PROP_N_PLANES] = properties[PROP_N_PLANES] =
g_param_spec_uint ("n-planes", NULL, NULL, 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); G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
/** /**
@@ -373,9 +365,6 @@ static void
gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self) gdk_dmabuf_texture_builder_init (GdkDmabufTextureBuilder *self)
{ {
self->premultiplied = TRUE; self->premultiplied = TRUE;
self->display = gdk_display_get_default ();
self->dmabuf.n_planes = 1;
for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++) for (int i = 0; i < GDK_DMABUF_MAX_PLANES; i++)
self->dmabuf.planes[i].fd = -1; self->dmabuf.planes[i].fd = -1;
} }
@@ -402,7 +391,7 @@ gdk_dmabuf_texture_builder_new (void)
* Returns the display that this texture builder is * Returns the display that this texture builder is
* associated with. * associated with.
* *
* Returns: (transfer none): the display * Returns: (transfer none) (nullable): the display
* *
* Since: 4.14 * Since: 4.14
*/ */
@@ -432,7 +421,6 @@ gdk_dmabuf_texture_builder_set_display (GdkDmabufTextureBuilder *self,
GdkDisplay *display) GdkDisplay *display)
{ {
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); 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)) if (g_set_object (&self->display, display))
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISPLAY]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DISPLAY]);
@@ -606,13 +594,6 @@ gdk_dmabuf_texture_builder_set_modifier (GdkDmabufTextureBuilder *self,
guint64 modifier) guint64 modifier)
{ {
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); 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->dmabuf.modifier == modifier)
return; return;
@@ -698,7 +679,6 @@ gdk_dmabuf_texture_builder_set_n_planes (GdkDmabufTextureBuilder *self,
unsigned int n_planes) unsigned int n_planes)
{ {
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self)); 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->dmabuf.n_planes == n_planes)
return; return;
@@ -979,17 +959,16 @@ gdk_dmabuf_texture_builder_build (GdkDmabufTextureBuilder *self,
gpointer data, gpointer data,
GError **error) GError **error)
{ {
unsigned i;
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), NULL); 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 (destroy == NULL || data != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == 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->width > 0, NULL);
g_return_val_if_fail (self->height > 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->dmabuf.fourcc != 0, NULL);
g_return_val_if_fail (self->dmabuf.n_planes > 0, NULL);
for (i = 0; i < self->dmabuf.n_planes; i++) for (int i = 0; i < self->dmabuf.n_planes; i++)
g_return_val_if_fail (self->dmabuf.planes[i].fd != -1, NULL); g_return_val_if_fail (self->dmabuf.planes[i].fd != -1 || self->dmabuf.planes[i].offset != 0, NULL);
if (GDK_DEBUG_CHECK (DMABUF_DISABLE)) if (GDK_DEBUG_CHECK (DMABUF_DISABLE))
{ {

View File

@@ -684,7 +684,7 @@ gdk_drop_read_async (GdkDrop *self,
* gdk_drop_read_finish: * gdk_drop_read_finish:
* @self: a `GdkDrop` * @self: a `GdkDrop`
* @result: a `GAsyncResult` * @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 * @error: (nullable): location to store error information on failure
* *
* Finishes an async drop read operation. * Finishes an async drop read operation.

View File

@@ -298,16 +298,10 @@ typedef enum
* The color values are premultiplied with the alpha value. * The color values are premultiplied with the alpha value.
* @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha * @GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: 4 bytes; for red, green, blue, alpha
* The color values are premultiplied with the alpha value. * 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_B8G8R8A8: 4 bytes; for blue, green, red, alpha.
* @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue. * @GDK_MEMORY_A8R8G8B8: 4 bytes; for alpha, red, green, blue.
* @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha. * @GDK_MEMORY_R8G8B8A8: 4 bytes; for red, green, blue, alpha.
* @GDK_MEMORY_A8B8G8R8: 4 bytes; for alpha, blue, green, red. * @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_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_B8G8R8: 3 bytes; for blue, green, red. The data is opaque.
* @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6 * @GDK_MEMORY_R16G16B16: 3 guint16 values; for red, green, blue. Since: 4.6
@@ -388,11 +382,6 @@ typedef enum {
GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12, GDK_MEMORY_A16 GDK_AVAILABLE_ENUMERATOR_IN_4_12,
GDK_MEMORY_A16_FLOAT 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_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 GDK_MEMORY_N_FORMATS
} GdkMemoryFormat; } GdkMemoryFormat;

View File

@@ -83,7 +83,6 @@
#include "gdkmemorytextureprivate.h" #include "gdkmemorytextureprivate.h"
#include "gdkprofilerprivate.h" #include "gdkprofilerprivate.h"
#include "gdkglversionprivate.h" #include "gdkglversionprivate.h"
#include "gdkdmabufformatsprivate.h"
#include "gdkprivate.h" #include "gdkprivate.h"
@@ -96,10 +95,6 @@
#include <epoxy/egl.h> #include <epoxy/egl.h>
#endif #endif
#ifdef HAVE_DMABUF
#include <drm_fourcc.h>
#endif
#include <math.h> #include <math.h>
#define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES #define DEFAULT_ALLOWED_APIS GDK_GL_API_GL | GDK_GL_API_GLES
@@ -114,8 +109,6 @@ typedef struct {
guint has_sync : 1; guint has_sync : 1;
guint has_unpack_subimage : 1; guint has_unpack_subimage : 1;
guint has_debug_output : 1; guint has_debug_output : 1;
guint has_bgra : 1;
guint has_image_storage : 1;
guint extensions_checked : 1; guint extensions_checked : 1;
guint debug_enabled : 1; guint debug_enabled : 1;
guint forward_compatible : 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)) || 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"); epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug"); priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
priv->has_bgra = epoxy_has_gl_extension ("GL_EXT_texture_format_BGRA8888");
} }
else else
{ {
priv->has_unpack_subimage = TRUE; priv->has_unpack_subimage = TRUE;
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug"); 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 */ /* 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))) 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_ARB_sync") ||
epoxy_has_gl_extension ("GL_APPLE_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 #ifdef G_ENABLE_DEBUG
{ {
int max_texture_size; int max_texture_size;
@@ -1577,8 +1566,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
"* Extensions checked:\n" "* Extensions checked:\n"
" - GL_KHR_debug: %s\n" " - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %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" " - half float: %s\n"
" - sync: %s", " - sync: %s",
gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL", gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
@@ -1588,8 +1575,6 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
max_texture_size, max_texture_size,
priv->has_khr_debug ? "yes" : "no", priv->has_khr_debug ? "yes" : "no",
priv->has_unpack_subimage ? "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_half_float ? "yes" : "no",
priv->has_sync ? "yes" : "no"); priv->has_sync ? "yes" : "no");
} }
@@ -1877,44 +1862,6 @@ gdk_gl_context_has_sync (GdkGLContext *self)
return priv->has_sync; 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! */ /* This is currently private! */
/* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */ /* When using GL/ES, don't flip the 'R' and 'B' bits on Windows/ANGLE for glReadPixels() */
gboolean gboolean
@@ -1995,201 +1942,3 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
g_assert (the_gl_backend_type == 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
}

View File

@@ -23,7 +23,6 @@
#include "gdkglcontext.h" #include "gdkglcontext.h"
#include "gdkdrawcontextprivate.h" #include "gdkdrawcontextprivate.h"
#include "gdkglversionprivate.h" #include "gdkglversionprivate.h"
#include "gdkdmabufprivate.h"
G_BEGIN_DECLS 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_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); 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 G_END_DECLS

View File

@@ -141,7 +141,9 @@ struct _Download
}; };
static gboolean 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, GdkMemoryAlpha alpha,
GLint gl_format, GLint gl_format,
GLint gl_type, GLint gl_type,
@@ -157,7 +159,7 @@ gdk_gl_texture_find_format (GdkGLContext *context,
if (gdk_memory_format_alpha (format) != alpha) if (gdk_memory_format_alpha (format) != alpha)
continue; 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; continue;
if (q_format != gl_format || q_type != gl_type) if (q_format != gl_format || q_type != gl_type)
@@ -181,13 +183,16 @@ gdk_gl_texture_do_download (GdkGLTexture *self,
Download *download = download_; Download *download = download_;
GLenum gl_internal_format, gl_format, gl_type; GLenum gl_internal_format, gl_format, gl_type;
GLint gl_swizzle[4]; GLint gl_swizzle[4];
int major, minor;
format = gdk_texture_get_format (texture), format = gdk_texture_get_format (texture),
expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format); 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) && if (!gdk_gl_context_get_use_es (context) &&
gdk_memory_format_gl_format (format, gdk_memory_format_gl_format (format,
context, FALSE,
major, minor,
&gl_internal_format, &gl_internal_format,
&gl_format, &gl_type, gl_swizzle)) &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_FORMAT, &gl_read_format);
glGetFramebufferParameteriv (GL_FRAMEBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &gl_read_type); 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_format = GL_RGBA;
gl_read_type = GL_UNSIGNED_BYTE; gl_read_type = GL_UNSIGNED_BYTE;

View File

@@ -20,7 +20,6 @@
#include "config.h" #include "config.h"
#include "gdkmemoryformatprivate.h" #include "gdkmemoryformatprivate.h"
#include "gdkglcontextprivate.h"
#include "gsk/gl/fp16private.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 (b8g8r8a8_premultiplied, guchar, 2, 1, 0, 3, 4, 255)
TYPED_FUNCS (a8r8g8b8_premultiplied, guchar, 1, 2, 3, 0, 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 (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 (b8g8r8a8, guchar, 2, 1, 0, 3, 4, 255)
TYPED_FUNCS (a8r8g8b8, guchar, 1, 2, 3, 0, 4, 255) TYPED_FUNCS (a8r8g8b8, guchar, 1, 2, 3, 0, 4, 255)
TYPED_FUNCS (r8g8b8a8, guchar, 0, 1, 2, 3, 4, 255) TYPED_FUNCS (r8g8b8a8, guchar, 0, 1, 2, 3, 4, 255)
TYPED_FUNCS (a8b8g8r8, guchar, 3, 2, 1, 0, 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 (r8g8b8, guchar, 0, 1, 2, -1, 3, 255)
TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255) TYPED_FUNCS (b8g8r8, guchar, 2, 1, 0, -1, 3, 255)
TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535) TYPED_FUNCS (r16g16b16, guint16, 0, 1, 2, -1, 6, 65535)
@@ -360,7 +352,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
4, 4,
G_ALIGNOF (guchar), G_ALIGNOF (guchar),
GDK_MEMORY_U8, 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 } }, { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_premultiplied_to_float, b8g8r8a8_premultiplied_to_float,
b8g8r8a8_premultiplied_from_float, b8g8r8a8_premultiplied_from_float,
@@ -385,22 +377,12 @@ static const GdkMemoryFormatDescription memory_formats[] = {
r8g8b8a8_premultiplied_to_float, r8g8b8a8_premultiplied_to_float,
r8g8b8a8_premultiplied_from_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_B8G8R8A8] = {
GDK_MEMORY_ALPHA_STRAIGHT, GDK_MEMORY_ALPHA_STRAIGHT,
4, 4,
G_ALIGNOF (guchar), G_ALIGNOF (guchar),
GDK_MEMORY_U8, 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 } }, { GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
b8g8r8a8_to_float, b8g8r8a8_to_float,
b8g8r8a8_from_float, b8g8r8a8_from_float,
@@ -435,46 +417,6 @@ static const GdkMemoryFormatDescription memory_formats[] = {
a8b8g8r8_to_float, a8b8g8r8_to_float,
a8b8g8r8_from_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_R8G8B8] = {
GDK_MEMORY_ALPHA_OPAQUE, GDK_MEMORY_ALPHA_OPAQUE,
3, 3,
@@ -569,7 +511,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
GDK_MEMORY_ALPHA_PREMULTIPLIED, GDK_MEMORY_ALPHA_PREMULTIPLIED,
16, 16,
G_ALIGNOF (float), G_ALIGNOF (float),
GDK_MEMORY_FLOAT32, TRUE,
{ 0, 0, 3, 0 }, { 0, 0, 3, 0 },
{ GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } }, { GL_RGBA32F, GL_RGBA, GL_FLOAT, { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA } },
r32g32b32a32_float_to_float, r32g32b32a32_float_to_float,
@@ -791,19 +733,14 @@ gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth)
gboolean gboolean
gdk_memory_format_gl_format (GdkMemoryFormat format, gdk_memory_format_gl_format (GdkMemoryFormat format,
GdkGLContext *context, gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format, guint *out_internal_format,
guint *out_format, guint *out_format,
guint *out_type, guint *out_type,
GLint out_swizzle[4]) 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_internal_format = memory_formats[format].gl.internal_format;
*out_format = memory_formats[format].gl.format; *out_format = memory_formats[format].gl.format;
*out_type = memory_formats[format].gl.type; *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_major == gl_major &&
memory_formats[format].min_gl_version.gles_minor > gl_minor)) memory_formats[format].min_gl_version.gles_minor > gl_minor))
return FALSE; return FALSE;
if (*out_format == GL_BGRA && !gdk_gl_context_has_bgra (context))
return FALSE;
} }
else else
{ {

View File

@@ -20,7 +20,6 @@
#pragma once #pragma once
#include "gdkenums.h" #include "gdkenums.h"
#include "gdktypes.h"
#include <epoxy/gl.h> #include <epoxy/gl.h>
@@ -47,7 +46,9 @@ GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth
GdkMemoryDepth depth2) G_GNUC_CONST; GdkMemoryDepth depth2) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST; GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
gboolean gdk_memory_format_gl_format (GdkMemoryFormat format, gboolean gdk_memory_format_gl_format (GdkMemoryFormat format,
GdkGLContext *context, gboolean gles,
guint gl_major,
guint gl_minor,
guint *out_internal_format, guint *out_internal_format,
guint *out_format, guint *out_format,
guint *out_type, guint *out_type,

View File

@@ -493,12 +493,6 @@ gdk_surface_real_get_scale (GdkSurface *surface)
return 1.0; return 1.0;
} }
static GdkSubsurface *
gdk_surface_real_create_subsurface (GdkSurface *surface)
{
return NULL;
}
static void static void
gdk_surface_constructed (GObject *object) gdk_surface_constructed (GObject *object)
{ {
@@ -521,7 +515,6 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
klass->beep = gdk_surface_real_beep; klass->beep = gdk_surface_real_beep;
klass->get_scale = gdk_surface_real_get_scale; 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) * 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); 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);
}

View File

@@ -23,14 +23,9 @@
#include "gdkenumtypes.h" #include "gdkenumtypes.h"
#include "gdksurface.h" #include "gdksurface.h"
#include "gdktoplevel.h" #include "gdktoplevel.h"
#include <graphene.h>
G_BEGIN_DECLS G_BEGIN_DECLS
typedef struct _GdkSubsurface GdkSubsurface;
typedef struct _GskRenderNode GskRenderNode;
struct _GdkSurface struct _GdkSurface
{ {
GObject parent_instance; GObject parent_instance;
@@ -151,9 +146,6 @@ struct _GdkSurfaceClass
cairo_region_t *region); cairo_region_t *region);
void (* request_layout) (GdkSurface *surface); void (* request_layout) (GdkSurface *surface);
gboolean (* compute_size) (GdkSurface *surface); gboolean (* compute_size) (GdkSurface *surface);
GdkSubsurface *
(* create_subsurface) (GdkSurface *surface);
}; };
#define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed) #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); 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 G_END_DECLS

View File

@@ -1475,13 +1475,6 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
gboolean validate = FALSE, have_debug_report = FALSE; gboolean validate = FALSE, have_debug_report = FALSE;
VkResult res; 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) if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)
{ {
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED, g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,

View File

@@ -329,7 +329,6 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
@@ -341,10 +340,6 @@ gdk_save_png (GdkTexture *texture)
case GDK_MEMORY_R8G8B8: case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8: case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8B8G8R8:
format = GDK_MEMORY_R8G8B8; format = GDK_MEMORY_R8G8B8;
png_format = PNG_COLOR_TYPE_RGB; png_format = PNG_COLOR_TYPE_RGB;
depth = 8; depth = 8;

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_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_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_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_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_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_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_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_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_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_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_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 }, [GDK_MEMORY_R16G16B16A16] = { GDK_MEMORY_R16G16B16A16, 16, 4, SAMPLEFORMAT_UINT, EXTRASAMPLE_UNASSALPHA, PHOTOMETRIC_RGB },

View File

@@ -18,7 +18,6 @@ gdk_public_sources = files([
'gdkdisplay.c', 'gdkdisplay.c',
'gdkdisplaymanager.c', 'gdkdisplaymanager.c',
'gdkdmabuf.c', 'gdkdmabuf.c',
'gdkdmabufegl.c',
'gdkdmabufformats.c', 'gdkdmabufformats.c',
'gdkdmabufformatsbuilder.c', 'gdkdmabufformatsbuilder.c',
'gdkdmabuftexture.c', 'gdkdmabuftexture.c',
@@ -217,7 +216,6 @@ gdk_deps = [
platform_gio_dep, platform_gio_dep,
pangocairo_dep, pangocairo_dep,
vulkan_dep, vulkan_dep,
dmabuf_dep,
png_dep, png_dep,
tiff_dep, tiff_dep,
jpeg_dep, jpeg_dep,

View File

@@ -24,7 +24,6 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/sysmacros.h>
#ifdef HAVE_LINUX_MEMFD_H #ifdef HAVE_LINUX_MEMFD_H
#include <linux/memfd.h> #include <linux/memfd.h>
@@ -57,7 +56,6 @@
#include <wayland/xdg-foreign-unstable-v1-client-protocol.h> #include <wayland/xdg-foreign-unstable-v1-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h> #include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include <wayland/server-decoration-client-protocol.h> #include <wayland/server-decoration-client-protocol.h>
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "wm-button-layout-translation.h" #include "wm-button-layout-translation.h"
@@ -269,105 +267,45 @@ postpone_on_globals_closure (GdkWaylandDisplay *display_wayland,
g_list_append (display_wayland->on_has_globals_closures, closure); 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 static void
wl_shm_format (void *data, wl_shm_format (void *data,
struct wl_shm *wl_shm, struct wl_shm *wl_shm,
uint32_t format) 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 pixel format %s (0x%X)",
get_format_name (format, buf), (guint) format);
} }
static const struct wl_shm_listener wl_shm_listener = { static const struct wl_shm_listener wl_shm_listener = {
wl_shm_format wl_shm_format
}; };
static void
linux_dmabuf_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
GDK_DEBUG (MISC, "dmabuf feedback done");
}
static void
linux_dmabuf_format_table (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
int32_t fd,
uint32_t size)
{
GdkWaylandDisplay *display_wayland = data;
display_wayland->linux_dmabuf_n_formats = size / 16;
display_wayland->linux_dmabuf_formats = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
GDK_DEBUG (MISC, "got dmabuf format table (%lu entries)", display_wayland->linux_dmabuf_n_formats);
}
static void
linux_dmabuf_main_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *device)
{
dev_t dev = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf main device: %u %u", major (dev), minor (dev));
}
static void
linux_dmabuf_tranche_done (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1)
{
GDK_DEBUG (MISC, "dmabuf feedback tranche done");
}
static void
linux_dmabuf_tranche_target_device (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *device)
{
dev_t dev = *(dev_t *)device->data;
GDK_DEBUG (MISC, "got dmabuf tranche target device: %u %u", major (dev), minor (dev));
}
static void
linux_dmabuf_tranche_formats (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
struct wl_array *indices)
{
GdkWaylandDisplay *display_wayland = data;
GDK_DEBUG (MISC, "got dmabuf tranche formats (%lu entries):", indices->size / sizeof (guint16));
guint16 *pos;
wl_array_for_each (pos, indices)
{
LinuxDmabufFormat *fmt = &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);
}
}
static void
linux_dmabuf_tranche_flags (void *data,
struct zwp_linux_dmabuf_feedback_v1 *zwp_linux_dmabuf_feedback_v1,
uint32_t flags)
{
GDK_DEBUG (MISC,
"got dmabuf tranche flags: %s",
flags & ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT ? "scanout" : "");
}
static const struct zwp_linux_dmabuf_feedback_v1_listener linux_dmabuf_feedback_listener = {
linux_dmabuf_done,
linux_dmabuf_format_table,
linux_dmabuf_main_device,
linux_dmabuf_tranche_done,
linux_dmabuf_tranche_target_device,
linux_dmabuf_tranche_formats,
linux_dmabuf_tranche_flags,
};
static void static void
server_decoration_manager_default_mode (void *data, server_decoration_manager_default_mode (void *data,
struct org_kde_kwin_server_decoration_manager *manager, struct org_kde_kwin_server_decoration_manager *manager,
@@ -444,16 +382,6 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1); wl_registry_bind (display_wayland->wl_registry, id, &wl_shm_interface, 1);
wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland); wl_shm_add_listener (display_wayland->shm, &wl_shm_listener, display_wayland);
} }
else if (strcmp (interface, "zwp_linux_dmabuf_v1") == 0 && version >= 4)
{
display_wayland->linux_dmabuf =
wl_registry_bind (display_wayland->wl_registry, id, &zwp_linux_dmabuf_v1_interface, version);
display_wayland->linux_dmabuf_feedback =
zwp_linux_dmabuf_v1_get_default_feedback (display_wayland->linux_dmabuf);
zwp_linux_dmabuf_feedback_v1_add_listener (display_wayland->linux_dmabuf_feedback,
&linux_dmabuf_feedback_listener, display_wayland);
_gdk_wayland_display_async_roundtrip (display_wayland);
}
else if (strcmp (interface, "xdg_wm_base") == 0) else if (strcmp (interface, "xdg_wm_base") == 0)
{ {
display_wayland->xdg_wm_base_id = id; display_wayland->xdg_wm_base_id = id;
@@ -798,10 +726,6 @@ gdk_wayland_display_dispose (GObject *object)
g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy); g_clear_pointer (&display_wayland->xdg_activation, xdg_activation_v1_destroy);
g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy); g_clear_pointer (&display_wayland->fractional_scale, wp_fractional_scale_manager_v1_destroy);
g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy); g_clear_pointer (&display_wayland->viewporter, wp_viewporter_destroy);
g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy);
g_clear_pointer (&display_wayland->linux_dmabuf_feedback, zwp_linux_dmabuf_feedback_v1_destroy);
if (display_wayland->linux_dmabuf_formats)
munmap (display_wayland->linux_dmabuf_formats, display_wayland->linux_dmabuf_n_formats * 16);
g_clear_pointer (&display_wayland->shm, wl_shm_destroy); g_clear_pointer (&display_wayland->shm, wl_shm_destroy);
g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy); g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy);

View File

@@ -71,13 +71,6 @@ typedef enum _GdkWaylandShellVariant
GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6 GDK_WAYLAND_SHELL_VARIANT_ZXDG_SHELL_V6
} GdkWaylandShellVariant; } GdkWaylandShellVariant;
typedef struct
{
uint32_t fourcc;
uint32_t padding;
uint64_t modifier;
} LinuxDmabufFormat;
struct _GdkWaylandDisplay struct _GdkWaylandDisplay
{ {
GdkDisplay parent_instance; GdkDisplay parent_instance;
@@ -102,10 +95,6 @@ struct _GdkWaylandDisplay
struct wl_registry *wl_registry; struct wl_registry *wl_registry;
struct wl_compositor *compositor; struct wl_compositor *compositor;
struct wl_shm *shm; struct wl_shm *shm;
struct zwp_linux_dmabuf_v1 *linux_dmabuf;
struct zwp_linux_dmabuf_feedback_v1 *linux_dmabuf_feedback;
gsize linux_dmabuf_n_formats;
LinuxDmabufFormat *linux_dmabuf_formats;
struct xdg_wm_base *xdg_wm_base; struct xdg_wm_base *xdg_wm_base;
struct zxdg_shell_v6 *zxdg_shell_v6; struct zxdg_shell_v6 *zxdg_shell_v6;
struct gtk_shell1 *gtk_shell; struct gtk_shell1 *gtk_shell;

View File

@@ -75,7 +75,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
WL_SURFACE_OFFSET_SINCE_VERSION) WL_SURFACE_OFFSET_SINCE_VERSION)
wl_surface_offset (impl->display_server.wl_surface, dx, dy); 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); 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); GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);

View File

@@ -35,7 +35,6 @@
#include <gdk/wayland/gdkdisplay-wayland.h> #include <gdk/wayland/gdkdisplay-wayland.h>
#include <gdk/wayland/gdkseat-wayland.h> #include <gdk/wayland/gdkseat-wayland.h>
#include <gsk/gsk.h>
#include <xkbcommon/xkbcommon.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, GdkModifierType gdk_wayland_keymap_get_gdk_modifiers (GdkKeymap *keymap,
guint32 mods); guint32 mods);

View File

@@ -86,8 +86,6 @@ struct _GdkWaylandSurface
uint32_t last_configure_serial; uint32_t last_configure_serial;
int state_freeze_count; int state_freeze_count;
GPtrArray *subsurfaces;
}; };
typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass; typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;

View File

@@ -33,11 +33,9 @@
#include "gdksurfaceprivate.h" #include "gdksurfaceprivate.h"
#include "gdktoplevelprivate.h" #include "gdktoplevelprivate.h"
#include "gdkdevice-wayland-private.h" #include "gdkdevice-wayland-private.h"
#include "gdkdmabuftextureprivate.h"
#include <wayland/xdg-shell-unstable-v6-client-protocol.h> #include <wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h> #include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
#include "linux-dmabuf-unstable-v1-client-protocol.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@@ -50,7 +48,6 @@
#include "gdksurface-wayland-private.h" #include "gdksurface-wayland-private.h"
#include "gdktoplevel-wayland-private.h" #include "gdktoplevel-wayland-private.h"
/** /**
* GdkWaylandSurface: * GdkWaylandSurface:
* *
@@ -155,17 +152,13 @@ wl_region_from_cairo_region (GdkWaylandDisplay *display,
} }
/* }}} */ /* }}} */
/* {{{ Surface implementation */ /* {{{ Surface implementation */
static void gdk_wayland_subsurface_destroy (GdkSubsurface *sub);
static void static void
gdk_wayland_surface_init (GdkWaylandSurface *impl) gdk_wayland_surface_init (GdkWaylandSurface *impl)
{ {
impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (1); impl->scale = GDK_FRACTIONAL_SCALE_INIT_INT (1);
impl->viewport_dirty = TRUE; impl->viewport_dirty = TRUE;
impl->subsurfaces = g_ptr_array_new ();
} }
void void
@@ -559,7 +552,6 @@ gdk_wayland_surface_finalize (GObject *object)
g_clear_pointer (&impl->opaque_region, cairo_region_destroy); g_clear_pointer (&impl->opaque_region, cairo_region_destroy);
g_clear_pointer (&impl->input_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); 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; 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 static void
gdk_wayland_surface_destroy (GdkSurface *surface, gdk_wayland_surface_destroy (GdkSurface *surface,
gboolean foreign_destroy) gboolean foreign_destroy)
@@ -1170,7 +1151,6 @@ gdk_wayland_surface_destroy (GdkSurface *surface,
if (GDK_IS_TOPLEVEL (surface)) if (GDK_IS_TOPLEVEL (surface))
gdk_wayland_toplevel_destroy (GDK_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)); gdk_wayland_surface_destroy_wl_surface (GDK_WAYLAND_SURFACE (surface));
frame_clock = gdk_surface_get_frame_clock (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 static void
gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass) 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->get_scale = gdk_wayland_surface_get_scale;
surface_class->set_opaque_region = gdk_wayland_surface_set_opaque_region; surface_class->set_opaque_region = gdk_wayland_surface_set_opaque_region;
surface_class->request_layout = gdk_wayland_surface_request_layout; 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_configure = gdk_wayland_surface_default_handle_configure;
klass->handle_frame = gdk_wayland_surface_default_handle_frame; 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: */ /* vim:set foldmethod=marker expandtab: */

View File

@@ -67,7 +67,6 @@ proto_sources = [
['idle-inhibit', 'unstable', 'v1', ], ['idle-inhibit', 'unstable', 'v1', ],
['xdg-activation', 'staging', 'v1', ], ['xdg-activation', 'staging', 'v1', ],
['fractional-scale', 'staging', 'v1', ], ['fractional-scale', 'staging', 'v1', ],
['linux-dmabuf', 'unstable', 'v1', ],
] ]
gdk_wayland_gen_headers = [] gdk_wayland_gen_headers = []

View File

@@ -76,8 +76,7 @@ gsk_gl_attachment_state_bind_texture (GskGLAttachmentState *self,
g_assert (self != NULL); g_assert (self != NULL);
g_assert (target == GL_TEXTURE_1D || g_assert (target == GL_TEXTURE_1D ||
target == GL_TEXTURE_2D || target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D || target == GL_TEXTURE_3D);
target == GL_TEXTURE_EXTERNAL_OES);
g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16); g_assert (texture >= GL_TEXTURE0 && texture <= GL_TEXTURE16);
g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures)); g_assert (texture - GL_TEXTURE0 < G_N_ELEMENTS (self->textures));

View File

@@ -29,9 +29,6 @@ typedef struct _GskGLBindFramebuffer GskGLBindFramebuffer;
typedef struct _GskGLBindTexture GskGLBindTexture; typedef struct _GskGLBindTexture GskGLBindTexture;
#define GSK_GL_N_FILTERS 3 #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 static inline guint
filter_index (GLint filter) filter_index (GLint filter)

View File

@@ -282,10 +282,7 @@ snapshot_attachments (const GskGLAttachmentState *state,
{ {
bind[count].id = state->textures[i].id; bind[count].id = state->textures[i].id;
bind[count].texture = state->textures[i].texture; bind[count].texture = state->textures[i].texture;
if (state->textures[i].target == GL_TEXTURE_EXTERNAL_OES) bind[count].sampler = state->textures[i].sampler;
bind[count].sampler = SAMPLER_EXTERNAL;
else
bind[count].sampler = state->textures[i].sampler;
count++; count++;
} }
} }
@@ -1073,7 +1070,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation (GL_FUNC_ADD); 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); glGenVertexArrays (1, &vao_id);
glBindVertexArray (vao_id); glBindVertexArray (vao_id);
@@ -1193,23 +1190,12 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
s->sync = NULL; s->sync = NULL;
} }
if (bind->sampler == SAMPLER_EXTERNAL) glBindTexture (GL_TEXTURE_2D, bind->id);
glBindTexture (GL_TEXTURE_EXTERNAL_OES, bind->id);
else
glBindTexture (GL_TEXTURE_2D, bind->id);
textures[bind->texture] = bind->id; textures[bind->texture] = bind->id;
if (!self->has_samplers) if (!self->has_samplers)
{ {
if (bind->sampler == SAMPLER_EXTERNAL) 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_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));
}
} }
} }
@@ -1219,16 +1205,8 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
glBindSampler (bind->texture, self->samplers[bind->sampler]); glBindSampler (bind->texture, self->samplers[bind->sampler]);
else else
{ {
if (bind->sampler == SAMPLER_EXTERNAL) 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_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));
}
} }
samplers[bind->texture] = bind->sampler; samplers[bind->texture] = bind->sampler;
} }
@@ -1279,7 +1257,7 @@ gsk_gl_command_queue_execute (GskGLCommandQueue *self,
} }
glDeleteBuffers (1, &vbo_id); 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); glDeleteVertexArrays (1, &vao_id);
gdk_profiler_set_int_counter (self->metrics.n_binds, n_binds); 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) if (self->attachments->textures[i].id != 0)
{ {
glActiveTexture (GL_TEXTURE0 + i); 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].id = 0;
self->attachments->textures[i].changed = FALSE; self->attachments->textures[i].changed = FALSE;
@@ -1423,7 +1401,7 @@ gsk_gl_command_queue_create_texture (GskGLCommandQueue *self,
glActiveTexture (GL_TEXTURE0); glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, texture_id); glBindTexture (GL_TEXTURE_2D, texture_id);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 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 */ /* Restore the previous texture if it was set */
if (self->attachments->textures[0].id != 0 && if (self->attachments->textures[0].id != 0)
self->attachments->textures[0].target == GL_TEXTURE_2D) glBindTexture (GL_TEXTURE_2D, self->attachments->textures[0].id);
glBindTexture (self->attachments->textures[0].target, self->attachments->textures[0].id);
return (int)texture_id; return (int)texture_id;
} }
@@ -1473,7 +1450,9 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
static GdkMemoryFormat static GdkMemoryFormat
memory_format_gl_format (GdkMemoryFormat data_format, memory_format_gl_format (GdkMemoryFormat data_format,
GdkGLContext *context, gboolean use_es,
guint major,
guint minor,
guint *gl_internalformat, guint *gl_internalformat,
guint *gl_format, guint *gl_format,
guint *gl_type, guint *gl_type,
@@ -1483,7 +1462,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
/* First, try the format itself */ /* First, try the format itself */
if (gdk_memory_format_gl_format (data_format, if (gdk_memory_format_gl_format (data_format,
context, use_es,
major,
minor,
gl_internalformat, gl_internalformat,
gl_format, gl_format,
gl_type, gl_type,
@@ -1499,7 +1480,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
case GDK_MEMORY_FLOAT16: case GDK_MEMORY_FLOAT16:
data_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED; data_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format, if (gdk_memory_format_gl_format (data_format,
context, use_es,
major,
minor,
gl_internalformat, gl_internalformat,
gl_format, gl_format,
gl_type, gl_type,
@@ -1510,7 +1493,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
case GDK_MEMORY_U16: case GDK_MEMORY_U16:
data_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED; data_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format, if (gdk_memory_format_gl_format (data_format,
context, use_es,
major,
minor,
gl_internalformat, gl_internalformat,
gl_format, gl_format,
gl_type, gl_type,
@@ -1532,7 +1517,9 @@ memory_format_gl_format (GdkMemoryFormat data_format,
{ {
data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED; data_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
if (gdk_memory_format_gl_format (data_format, if (gdk_memory_format_gl_format (data_format,
context, use_es,
major,
minor,
gl_internalformat, gl_internalformat,
gl_format, gl_format,
gl_type, 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 */ /* If all else fails, pick the one format that's always supported */
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format, if (!gdk_memory_format_gl_format (data_format,
context, use_es,
major,
minor,
gl_internalformat, gl_internalformat,
gl_format, gl_format,
gl_type, gl_type,
@@ -1572,13 +1561,19 @@ gsk_gl_command_queue_do_upload_texture_chunk (GskGLCommandQueue *self,
GLenum gl_type; GLenum gl_type;
GLint gl_swizzle[4]; GLint gl_swizzle[4];
gsize bpp; 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); data_format = gdk_texture_get_format (texture);
width = gdk_texture_get_width (texture); width = gdk_texture_get_width (texture);
height = gdk_texture_get_height (texture); height = gdk_texture_get_height (texture);
data_format = memory_format_gl_format (data_format, data_format = memory_format_gl_format (data_format,
self->context, use_es,
major,
minor,
&gl_internalformat, &gl_internalformat,
&gl_format, &gl_format,
&gl_type, &gl_type,
@@ -1643,7 +1638,9 @@ gsk_gl_command_queue_upload_texture_chunks (GskGLCommandQueue *self,
GLenum gl_format; GLenum gl_format;
GLenum gl_type; GLenum gl_type;
GLint gl_swizzle[4]; GLint gl_swizzle[4];
gboolean use_es;
int texture_id; int texture_id;
int major, minor;
g_assert (GSK_IS_GL_COMMAND_QUEUE (self)); 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); glBindTexture (GL_TEXTURE_2D, texture_id);
/* Initialize the texture */ /* 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 = gdk_texture_get_format (chunks[0].texture);
data_format = memory_format_gl_format (data_format, data_format = memory_format_gl_format (data_format,
self->context, use_es,
major,
minor,
&gl_internalformat, &gl_internalformat,
&gl_format, &gl_format,
&gl_type, &gl_type,

View File

@@ -54,7 +54,6 @@ typedef struct _GskGLCommandBind
*/ */
guint texture : 4; guint texture : 4;
/* the sampler to use. We set sampler to 15 to indicate external textures */
guint sampler : 4; guint sampler : 4;
/* The identifier for the texture created with glGenTextures(). */ /* 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 /* Array of samplers that we use for mag/min filter handling. It is indexed
* by the sampler_index() function. * by the sampler_index() function.
*
* Note that when samplers are not supported (hello GLES), we fall back to * 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. * 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]; GLuint samplers[GSK_GL_N_FILTERS * GSK_GL_N_FILTERS];

View File

@@ -54,7 +54,6 @@ struct _GskGLCompiler
guint gl3 : 1; guint gl3 : 1;
guint gles : 1; guint gles : 1;
guint gles3 : 1;
guint legacy : 1; guint legacy : 1;
guint debug_shaders : 1; guint debug_shaders : 1;
}; };
@@ -135,10 +134,7 @@ gsk_gl_compiler_new (GskGLDriver *driver,
gdk_gl_context_get_version (context, &maj, &min); gdk_gl_context_get_version (context, &maj, &min);
if (maj >= 3) if (maj >= 3)
{ self->glsl_version = SHADER_VERSION_GLES3;
self->glsl_version = SHADER_VERSION_GLES3;
self->gles3 = TRUE;
}
else else
{ {
self->glsl_version = SHADER_VERSION_GLES; self->glsl_version = SHADER_VERSION_GLES;
@@ -547,7 +543,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
const char *legacy = ""; const char *legacy = "";
const char *gl3 = ""; const char *gl3 = "";
const char *gles = ""; const char *gles = "";
const char *gles3 = "";
int program_id; int program_id;
int vertex_id; int vertex_id;
int fragment_id; int fragment_id;
@@ -574,17 +569,15 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
if (self->gles) if (self->gles)
gles = "#define GSK_GLES 1\n"; gles = "#define GSK_GLES 1\n";
if (self->gles3)
gles3 = "#define GSK_GLES3 1\n";
if (self->gl3) if (self->gl3)
gl3 = "#define GSK_GL3 1\n"; gl3 = "#define GSK_GL3 1\n";
vertex_id = glCreateShader (GL_VERTEX_SHADER); vertex_id = glCreateShader (GL_VERTEX_SHADER);
glShaderSource (vertex_id, glShaderSource (vertex_id,
11, 10,
(const char *[]) { (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->all_preamble),
get_shader_string (self->vertex_preamble), get_shader_string (self->vertex_preamble),
get_shader_string (self->vertex_source), get_shader_string (self->vertex_source),
@@ -596,7 +589,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
strlen (legacy), strlen (legacy),
strlen (gl3), strlen (gl3),
strlen (gles), strlen (gles),
strlen (gles3),
strlen (clip), strlen (clip),
g_bytes_get_size (self->all_preamble), g_bytes_get_size (self->all_preamble),
g_bytes_get_size (self->vertex_preamble), g_bytes_get_size (self->vertex_preamble),
@@ -615,9 +607,10 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
fragment_id = glCreateShader (GL_FRAGMENT_SHADER); fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource (fragment_id, glShaderSource (fragment_id,
11, 10,
(const char *[]) { (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->all_preamble),
get_shader_string (self->fragment_preamble), get_shader_string (self->fragment_preamble),
get_shader_string (self->fragment_source), get_shader_string (self->fragment_source),
@@ -629,7 +622,6 @@ gsk_gl_compiler_compile (GskGLCompiler *self,
strlen (legacy), strlen (legacy),
strlen (gl3), strlen (gl3),
strlen (gles), strlen (gles),
strlen (gles3),
strlen (clip), strlen (clip),
g_bytes_get_size (self->all_preamble), g_bytes_get_size (self->all_preamble),
g_bytes_get_size (self->fragment_preamble), g_bytes_get_size (self->fragment_preamble),

View File

@@ -44,8 +44,6 @@
#include <gdk/gdktextureprivate.h> #include <gdk/gdktextureprivate.h>
#include <gdk/gdkmemoryformatprivate.h> #include <gdk/gdkmemoryformatprivate.h>
#include <gdk/gdkdmabuftextureprivate.h>
G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT) G_DEFINE_TYPE (GskGLDriver, gsk_gl_driver, G_TYPE_OBJECT)
@@ -226,8 +224,6 @@ gsk_gl_driver_dispose (GObject *object)
GSK_GL_DELETE_PROGRAM(name); \ GSK_GL_DELETE_PROGRAM(name); \
GSK_GL_DELETE_PROGRAM(name ## _no_clip); \ GSK_GL_DELETE_PROGRAM(name ## _no_clip); \
GSK_GL_DELETE_PROGRAM(name ## _rect_clip); GSK_GL_DELETE_PROGRAM(name ## _rect_clip);
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) \
GSK_GL_DELETE_PROGRAM(name);
#define GSK_GL_DELETE_PROGRAM(name) \ #define GSK_GL_DELETE_PROGRAM(name) \
G_STMT_START { \ G_STMT_START { \
if (self->name) \ if (self->name) \
@@ -242,7 +238,6 @@ gsk_gl_driver_dispose (GObject *object)
#undef GSK_GL_SHADER_JOINED #undef GSK_GL_SHADER_JOINED
#undef GSK_GL_ADD_UNIFORM #undef GSK_GL_ADD_UNIFORM
#undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_DEFINE_PROGRAM
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
if (self->shader_cache != NULL) if (self->shader_cache != NULL)
{ {
@@ -378,11 +373,6 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \ GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
GSK_GL_COMPILE_PROGRAM(name, uniforms, ""); GSK_GL_COMPILE_PROGRAM(name, uniforms, "");
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, sources, uniforms) \
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \
sources \
GSK_GL_COMPILE_PROGRAM(name, uniforms, "#define NO_CLIP 1\n");
#define GSK_GL_COMPILE_PROGRAM(name, uniforms, clip) \ #define GSK_GL_COMPILE_PROGRAM(name, uniforms, clip) \
G_STMT_START { \ G_STMT_START { \
GskGLProgram *program; \ GskGLProgram *program; \
@@ -410,7 +400,6 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
} G_STMT_END; } G_STMT_END;
# include "gskglprograms.defs" # include "gskglprograms.defs"
#undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_DEFINE_PROGRAM
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
#undef GSK_GL_ADD_UNIFORM #undef GSK_GL_ADD_UNIFORM
#undef GSK_GL_SHADER_SINGLE #undef GSK_GL_SHADER_SINGLE
#undef GSK_GL_SHADER_JOINED #undef GSK_GL_SHADER_JOINED
@@ -713,180 +702,6 @@ gsk_gl_driver_cache_texture (GskGLDriver *self,
} }
} }
#if defined(HAVE_DMABUF) && defined (HAVE_EGL)
static void
set_viewport_for_size (GskGLDriver *self,
GskGLProgram *program,
float width,
float height)
{
float viewport[4] = { 0, 0, width, height };
gsk_gl_uniform_state_set4fv (program->uniforms,
program->program_info,
UNIFORM_SHARED_VIEWPORT, 0,
1,
(const float *)&viewport);
self->stamps[UNIFORM_SHARED_VIEWPORT]++;
}
#define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000
static void
set_projection_for_size (GskGLDriver *self,
GskGLProgram *program,
float width,
float height)
{
graphene_matrix_t projection;
graphene_matrix_init_ortho (&projection, 0, width, 0, height, ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE);
graphene_matrix_scale (&projection, 1, -1, 1);
gsk_gl_uniform_state_set_matrix (program->uniforms,
program->program_info,
UNIFORM_SHARED_PROJECTION, 0,
&projection);
self->stamps[UNIFORM_SHARED_PROJECTION]++;
}
static void
reset_modelview (GskGLDriver *self,
GskGLProgram *program)
{
graphene_matrix_t modelview;
graphene_matrix_init_identity (&modelview);
gsk_gl_uniform_state_set_matrix (program->uniforms,
program->program_info,
UNIFORM_SHARED_MODELVIEW, 0,
&modelview);
self->stamps[UNIFORM_SHARED_MODELVIEW]++;
}
static void
draw_rect (GskGLCommandQueue *command_queue,
float min_x,
float min_y,
float max_x,
float max_y)
{
GskGLDrawVertex *vertices = gsk_gl_command_queue_add_vertices (command_queue);
float min_u = 0;
float max_u = 1;
float min_v = 1;
float max_v = 0;
guint16 c = FP16_ZERO;
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { min_u, min_v }, .color = { c, c, c, c } };
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { min_u, max_v }, .color = { c, c, c, c } };
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .uv = { max_u, max_v }, .color = { c, c, c, c } };
vertices[4] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { min_u, max_v }, .color = { c, c, c, c } };
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
}
static unsigned int release_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target,
gboolean release_texture,
gboolean cache_texture);
static guint
gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
GdkDmabufTexture *texture)
{
GdkGLContext *context = self->command_queue->context;
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;
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));
if (width > max_texture_size || height > max_texture_size)
{
GDK_DEBUG (DMABUF, "Can't import dmabuf bigger than MAX_TEXTURE_SIZE (%d)", max_texture_size);
return 0;
}
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
GDK_DEBUG (DMABUF, "DMA-buf Format %.4s:%#lx", (char *) &dmabuf->fourcc, dmabuf->modifier);
gdk_display_init_dmabuf (display);
if (!gdk_dmabuf_formats_contains (display->egl_external_formats, dmabuf->fourcc, dmabuf->modifier))
{
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_2D texture");
return gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
GL_TEXTURE_2D);
}
if (!gdk_gl_context_get_use_es (context))
{
GDK_DEBUG (DMABUF, "Can't import external_only dmabuf outside of GLES");
return 0;
}
GDK_DEBUG (DMABUF, "Import dmabuf as GL_TEXTURE_EXTERNAL_OES texture");
texture_id = gdk_gl_context_import_dmabuf (context, width, height,
dmabuf,
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))
{
set_projection_for_size (self, program, width, height);
set_viewport_for_size (self, program, width, height);
reset_modelview (self, program);
gsk_gl_program_set_uniform_texture (program,
UNIFORM_EXTERNAL_SOURCE, 0,
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
draw_rect (self->command_queue, 0, 0, width, height);
gsk_gl_command_queue_end_draw (self->command_queue);
}
gsk_gl_command_queue_bind_framebuffer (self->command_queue, prev_fbo);
return release_render_target (self, render_target, FALSE, FALSE);
}
#else
static guint
gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
GdkDmabufTexture *texture)
{
return 0;
}
#endif /* HAVE_DMABUF && HAVE_EGL */
/** /**
* gsk_gl_driver_load_texture: * gsk_gl_driver_load_texture:
* @self: a `GdkTexture` * @self: a `GdkTexture`
@@ -943,11 +758,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
return t->texture_id; return t->texture_id;
} }
if (GDK_IS_DMABUF_TEXTURE (texture)) if (GDK_IS_GL_TEXTURE (texture))
{
texture_id = gsk_gl_driver_import_dmabuf_texture (self, GDK_DMABUF_TEXTURE (texture));
}
else if (GDK_IS_GL_TEXTURE (texture))
{ {
GdkGLTexture *gl_texture = (GdkGLTexture *) texture; GdkGLTexture *gl_texture = (GdkGLTexture *) texture;
GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture); GdkGLContext *texture_context = gdk_gl_texture_get_context (gl_texture);
@@ -1150,47 +961,6 @@ gsk_gl_driver_create_render_target (GskGLDriver *self,
return FALSE; return FALSE;
} }
static unsigned int
release_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target,
gboolean release_texture,
gboolean cache_texture)
{
guint texture_id;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
g_return_val_if_fail (render_target != NULL, 0);
if (release_texture)
{
texture_id = 0;
g_ptr_array_add (self->render_targets, render_target);
}
else
{
texture_id = render_target->texture_id;
if (cache_texture)
{
GskGLTexture *texture;
texture = gsk_gl_texture_new (render_target->texture_id,
render_target->width,
render_target->height,
self->current_frame_id);
g_hash_table_insert (self->textures,
GUINT_TO_POINTER (texture_id),
g_steal_pointer (&texture));
}
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
g_free (render_target);
}
return texture_id;
}
/** /**
* gsk_gl_driver_release_render_target: * gsk_gl_driver_release_render_target:
* @self: a `GskGLDriver` * @self: a `GskGLDriver`
@@ -1216,7 +986,36 @@ gsk_gl_driver_release_render_target (GskGLDriver *self,
GskGLRenderTarget *render_target, GskGLRenderTarget *render_target,
gboolean release_texture) gboolean release_texture)
{ {
return release_render_target (self, render_target, release_texture, TRUE); guint texture_id;
g_return_val_if_fail (GSK_IS_GL_DRIVER (self), 0);
g_return_val_if_fail (render_target != NULL, 0);
if (release_texture)
{
texture_id = 0;
g_ptr_array_add (self->render_targets, render_target);
}
else
{
GskGLTexture *texture;
texture_id = render_target->texture_id;
texture = gsk_gl_texture_new (render_target->texture_id,
render_target->width,
render_target->height,
self->current_frame_id);
g_hash_table_insert (self->textures,
GUINT_TO_POINTER (texture_id),
g_steal_pointer (&texture));
gsk_gl_driver_autorelease_framebuffer (self, render_target->framebuffer_id);
g_free (render_target);
}
return texture_id;
} }
/** /**
@@ -1801,9 +1600,8 @@ create_texture_from_texture_destroy (gpointer data)
} }
GdkTexture * GdkTexture *
gsk_gl_driver_create_gdk_texture (GskGLDriver *self, gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id, guint texture_id)
GdkMemoryFormat format)
{ {
GskGLTextureState *state; GskGLTextureState *state;
GdkGLTextureBuilder *builder; GdkGLTextureBuilder *builder;
@@ -1831,7 +1629,6 @@ gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
builder = gdk_gl_texture_builder_new (); builder = gdk_gl_texture_builder_new ();
gdk_gl_texture_builder_set_context (builder, self->command_queue->context); 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_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_width (builder, texture->width);
gdk_gl_texture_builder_set_height (builder, texture->height); gdk_gl_texture_builder_set_height (builder, texture->height);
gdk_gl_texture_builder_set_sync (builder, state->sync); gdk_gl_texture_builder_set_sync (builder, state->sync);

View File

@@ -69,9 +69,7 @@ typedef struct {
#define CONCAT_EXPANDED2(a,b) a##b #define CONCAT_EXPANDED2(a,b) a##b
#define GSK_GL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos, #define GSK_GL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos,
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms }; #define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms };
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) enum { uniforms };
# include "gskglprograms.defs" # include "gskglprograms.defs"
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
#undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_DEFINE_PROGRAM
#undef GSK_GL_ADD_UNIFORM #undef GSK_GL_ADD_UNIFORM
#undef GSK_GL_NO_UNIFORMS #undef GSK_GL_NO_UNIFORMS
@@ -118,13 +116,10 @@ struct _GskGLDriver
GskGLProgram *name ## _no_clip; \ GskGLProgram *name ## _no_clip; \
GskGLProgram *name ## _rect_clip; \ GskGLProgram *name ## _rect_clip; \
GskGLProgram *name; GskGLProgram *name;
#define GSK_GL_DEFINE_PROGRAM_NO_CLIP(name, resource, uniforms) \
GskGLProgram *name;
# include "gskglprograms.defs" # include "gskglprograms.defs"
#undef GSK_GL_NO_UNIFORMS #undef GSK_GL_NO_UNIFORMS
#undef GSK_GL_ADD_UNIFORM #undef GSK_GL_ADD_UNIFORM
#undef GSK_GL_DEFINE_PROGRAM #undef GSK_GL_DEFINE_PROGRAM
#undef GSK_GL_DEFINE_PROGRAM_NO_CLIP
gint64 current_frame_id; gint64 current_frame_id;
@@ -154,8 +149,7 @@ void gsk_gl_driver_begin_frame (GskGLDriver *s
void gsk_gl_driver_end_frame (GskGLDriver *self); void gsk_gl_driver_end_frame (GskGLDriver *self);
void gsk_gl_driver_after_frame (GskGLDriver *self); void gsk_gl_driver_after_frame (GskGLDriver *self);
GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self, GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
guint texture_id, guint texture_id);
GdkMemoryFormat format);
void gsk_gl_driver_cache_texture (GskGLDriver *self, void gsk_gl_driver_cache_texture (GskGLDriver *self,
const GskTextureKey *key, const GskTextureKey *key,
guint texture_id); guint texture_id);

View File

@@ -119,11 +119,7 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
memset (pixel_data, 255, sizeof pixel_data); memset (pixel_data, 255, sizeof pixel_data);
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ()) if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
#if G_BYTE_ORDER == G_BIG_ENDIAN
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
#endif
)
{ {
gl_format = GL_RGBA; gl_format = GL_RGBA;
gl_type = GL_UNSIGNED_BYTE; gl_type = GL_UNSIGNED_BYTE;
@@ -131,8 +127,9 @@ gsk_gl_glyph_library_init_atlas (GskGLTextureLibrary *self,
else else
{ {
gl_format = GL_BGRA; 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); glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
glTexSubImage2D (GL_TEXTURE_2D, 0, glTexSubImage2D (GL_TEXTURE_2D, 0,
@@ -280,7 +277,7 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self,
g_assert (texture_id > 0); 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); pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 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); pixel_data = cairo_image_surface_get_data (surface);
gl_format = GL_BGRA; 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); glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / 4);

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 (), gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
"Uploading texture"); "Uploading texture");
if (!gdk_gl_context_has_bgra (gdk_gl_context_get_current ()) if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
#if G_BYTE_ORDER == G_BIG_ENDIAN
|| gdk_gl_context_get_use_es (gdk_gl_context_get_current ())
#endif
)
{ {
pixel_data = free_data = g_malloc (width * height * 4); pixel_data = free_data = g_malloc (width * height * 4);
gdk_memory_convert (pixel_data, width * 4, gdk_memory_convert (pixel_data, width * 4,
@@ -129,7 +125,7 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self,
{ {
pixel_data = surface_data; pixel_data = surface_data;
gl_format = GL_BGRA; 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); texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);

View File

@@ -87,13 +87,3 @@ GSK_GL_DEFINE_PROGRAM (unblurred_outset_shadow,
GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread) GSK_GL_ADD_UNIFORM (1, UNBLURRED_OUTSET_SHADOW_SPREAD, u_spread)
GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset) GSK_GL_ADD_UNIFORM (2, UNBLURRED_OUTSET_SHADOW_OFFSET, u_offset)
GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect)) GSK_GL_ADD_UNIFORM (3, UNBLURRED_OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
/* Texture conversion shaders.
*
* Note: If you add new formats here, they need to be added
* to the list of supported formats in gdk/gdkdmabuftexture.c.
*/
GSK_GL_DEFINE_PROGRAM_NO_CLIP (external,
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("external.glsl")),
GSK_GL_ADD_UNIFORM (1, EXTERNAL_SOURCE, u_external_source))

View File

@@ -332,7 +332,6 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
GskGLRenderJob *job; GskGLRenderJob *job;
GdkTexture *texture; GdkTexture *texture;
guint texture_id; guint texture_id;
GdkMemoryFormat gdk_format;
int width, height, max_size; int width, height, max_size;
int format; int format;
@@ -376,15 +375,9 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
if (gsk_render_node_get_preferred_depth (root) != GDK_MEMORY_U8 && if (gsk_render_node_get_preferred_depth (root) != GDK_MEMORY_U8 &&
gdk_gl_context_check_version (self->context, "3.0", "3.0")) gdk_gl_context_check_version (self->context, "3.0", "3.0"))
{ format = GL_RGBA32F;
gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
format = GL_RGBA32F;
}
else else
{ format = GL_RGBA8;
format = GL_RGBA8;
gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
}
gdk_gl_context_make_current (self->context); gdk_gl_context_make_current (self->context);
@@ -401,7 +394,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
#endif #endif
gsk_gl_render_job_render_flipped (job, root); gsk_gl_render_job_render_flipped (job, root);
texture_id = gsk_gl_driver_release_render_target (self->driver, render_target, FALSE); 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_driver_end_frame (self->driver);
gsk_gl_render_job_free (job); gsk_gl_render_job_free (job);

View File

@@ -30,7 +30,6 @@
#include <gsk/gskglshaderprivate.h> #include <gsk/gskglshaderprivate.h>
#include <gdk/gdktextureprivate.h> #include <gdk/gdktextureprivate.h>
#include <gdk/gdkmemorytextureprivate.h> #include <gdk/gdkmemorytextureprivate.h>
#include <gdk/gdkdmabuftexture.h>
#include <gsk/gsktransformprivate.h> #include <gsk/gsktransformprivate.h>
#include <gsk/gskroundedrectprivate.h> #include <gsk/gskroundedrectprivate.h>
#include <gsk/gskrectprivate.h> #include <gsk/gskrectprivate.h>
@@ -48,7 +47,6 @@
#include "ninesliceprivate.h" #include "ninesliceprivate.h"
#include "fp16private.h" #include "fp16private.h"
#define ORTHO_NEAR_PLANE -10000 #define ORTHO_NEAR_PLANE -10000
#define ORTHO_FAR_PLANE 10000 #define ORTHO_FAR_PLANE 10000
#define MAX_GRADIENT_STOPS 6 #define MAX_GRADIENT_STOPS 6
@@ -3632,12 +3630,16 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
gboolean ensure_mipmap, gboolean ensure_mipmap,
GskGLRenderOffscreen *offscreen) GskGLRenderOffscreen *offscreen)
{ {
/* Don't put GL or dmabuf textures into icon caches, they are already on the GPU side */ GdkGLTexture *gl_texture = NULL;
if (GDK_IS_GL_TEXTURE (texture))
gl_texture = GDK_GL_TEXTURE (texture);
if (!ensure_mipmap && if (!ensure_mipmap &&
gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library, gsk_gl_texture_library_can_cache ((GskGLTextureLibrary *)job->driver->icons_library,
texture->width, texture->width,
texture->height) && texture->height) &&
!(GDK_IS_GL_TEXTURE (texture) || GDK_IS_DMABUF_TEXTURE (texture))) !gl_texture)
{ {
const GskGLIconData *icon_data; const GskGLIconData *icon_data;
@@ -3651,18 +3653,16 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
/* Only generate a mipmap if it does not make use reupload /* Only generate a mipmap if it does not make use reupload
* a GL texture which we could otherwise use directly. * a GL texture which we could otherwise use directly.
*/ */
if (GDK_IS_GL_TEXTURE (texture) && if (gl_texture &&
gdk_gl_context_is_shared (gdk_gl_texture_get_context (GDK_GL_TEXTURE (texture)), gdk_gl_context_is_shared (gdk_gl_texture_get_context (gl_texture), job->command_queue->context))
job->command_queue->context)) ensure_mipmap = gdk_gl_texture_has_mipmap (gl_texture);
ensure_mipmap = gdk_gl_texture_has_mipmap (GDK_GL_TEXTURE (texture));
offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap); offscreen->texture_id = gsk_gl_driver_load_texture (job->driver, texture, ensure_mipmap);
init_full_texture_region (offscreen); init_full_texture_region (offscreen);
offscreen->has_mipmap = ensure_mipmap; offscreen->has_mipmap = ensure_mipmap;
if (GDK_IS_GL_TEXTURE (texture) && if (gl_texture && offscreen->texture_id == gdk_gl_texture_get_id (gl_texture))
offscreen->texture_id == gdk_gl_texture_get_id (GDK_GL_TEXTURE (texture))) offscreen->sync = gdk_gl_texture_get_sync (gl_texture);
offscreen->sync = gdk_gl_texture_get_sync (GDK_GL_TEXTURE (texture));
} }
} }
@@ -3784,6 +3784,12 @@ gsk_gl_render_job_visit_texture_scale_node (GskGLRenderJob *job,
GskTextureKey key; GskTextureKey key;
guint texture_id; 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); gsk_gl_render_job_untransform_bounds (job, &job->current_clip->rect.bounds, &clip_rect);
if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect)) if (!graphene_rect_intersection (bounds, &clip_rect, &clip_rect))

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);
}

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 #ifndef GSK_LEGACY
precision highp float; precision highp float;
#endif #endif

View File

@@ -684,22 +684,3 @@ gsk_renderer_set_debug_flags (GskRenderer *renderer,
priv->debug_flags = flags; 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;
}

View File

@@ -56,8 +56,5 @@ GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer
void gsk_renderer_set_debug_flags (GskRenderer *renderer, void gsk_renderer_set_debug_flags (GskRenderer *renderer,
GskDebugFlags flags); GskDebugFlags flags);
GdkTexture * gsk_renderer_convert_texture (GskRenderer *renderer,
GdkTexture *texture);
G_END_DECLS G_END_DECLS

View File

@@ -33,7 +33,6 @@
#include "gdk/gdkrgbaprivate.h" #include "gdk/gdkrgbaprivate.h"
#include "gdk/gdktextureprivate.h" #include "gdk/gdktextureprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
#include <gtk/css/gtkcss.h> #include <gtk/css/gtkcss.h>
#include "gtk/css/gtkcssdataurlprivate.h" #include "gtk/css/gtkcssdataurlprivate.h"
#include "gtk/css/gtkcssparserprivate.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); 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_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_U16: 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); bytes = gdk_texture_save_to_png_bytes (texture);
g_string_append (p->str, "url(\"data:image/png;base64,"); g_string_append (p->str, "url(\"data:image/png;base64,");
break; break;
case GDK_MEMORY_FLOAT16: case GDK_MEMORY_R16G16B16_FLOAT:
case GDK_MEMORY_FLOAT32: 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); bytes = gdk_texture_save_to_tiff_bytes (texture);
g_string_append (p->str, "url(\"data:image/tiff;base64,"); g_string_append (p->str, "url(\"data:image/tiff;base64,");
break; break;
case GDK_MEMORY_N_FORMATS:
default: default:
g_assert_not_reached (); g_assert_not_reached ();
} }

View File

@@ -20,7 +20,6 @@ gsk_private_gl_shaders = [
'gl/resources/custom.glsl', 'gl/resources/custom.glsl',
'gl/resources/filled_border.glsl', 'gl/resources/filled_border.glsl',
'gl/resources/mask.glsl', 'gl/resources/mask.glsl',
'gl/resources/external.glsl',
] ]
gsk_public_sources = files([ gsk_public_sources = files([

View File

@@ -80,15 +80,6 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
return info; 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: case GDK_MEMORY_B8G8R8A8:
{ {
static const GskMemoryFormatInfo info[] = { static const GskMemoryFormatInfo info[] = {
@@ -126,17 +117,6 @@ gsk_memory_format_get_vk_format_infos (GdkMemoryFormat format)
return info; 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: case GDK_MEMORY_R8G8B8:
{ {
static const GskMemoryFormatInfo info[] = { static const GskMemoryFormatInfo info[] = {
@@ -344,7 +324,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
@@ -352,10 +331,6 @@ gsk_memory_format_get_fallback (GdkMemoryFormat format)
case GDK_MEMORY_R8G8B8: case GDK_MEMORY_R8G8B8:
return GDK_MEMORY_R8G8B8A8_PREMULTIPLIED; 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: case GDK_MEMORY_B8G8R8:
return GDK_MEMORY_R8G8B8; return GDK_MEMORY_R8G8B8;

View File

@@ -1,5 +1,5 @@
project('gtk', 'c', project('gtk', 'c',
version: '4.13.3', version: '4.13.2',
default_options: [ default_options: [
'buildtype=debugoptimized', 'buildtype=debugoptimized',
'warning_level=1', 'warning_level=1',
@@ -162,6 +162,7 @@ check_headers = [
'inttypes.h', 'inttypes.h',
'linux/input.h', 'linux/input.h',
'linux/memfd.h', 'linux/memfd.h',
'linux/dma-buf.h',
'locale.h', 'locale.h',
'memory.h', 'memory.h',
'stdint.h', 'stdint.h',
@@ -185,6 +186,10 @@ foreach h : check_headers
endif endif
endforeach endforeach
if os_linux and not cc.has_header('linux/dma-buf.h')
error('OS is Linux, but linux/dma-buf.h not found.')
endif
# Maths functions might be implemented in libm # Maths functions might be implemented in libm
libm = cc.find_library('m', required: false) libm = cc.find_library('m', required: false)
@@ -618,20 +623,6 @@ else
vulkan_pkg_found = false vulkan_pkg_found = false
endif 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', cloudproviders_dep = dependency('cloudproviders',
required: get_option('cloudproviders'), required: get_option('cloudproviders'),
version: cloudproviders_req, version: cloudproviders_req,

View File

@@ -23,7 +23,6 @@ gdk/gdkseat.c
gdk/gdksurface.c gdk/gdksurface.c
gdk/gdktexture.c gdk/gdktexture.c
gdk/gdktoplevel.c gdk/gdktoplevel.c
gdk/gdkvulkancontext.c
gdk/keynamesprivate.h gdk/keynamesprivate.h
gdk/loaders/gdkjpeg.c gdk/loaders/gdkjpeg.c
gdk/loaders/gdkpng.c gdk/loaders/gdkpng.c

1787
po/fr.po

File diff suppressed because it is too large Load Diff

View File

@@ -22,9 +22,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gtk\n" "Project-Id-Version: gtk\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
"POT-Creation-Date: 2023-10-16 11:58+0000\n" "POT-Creation-Date: 2023-10-13 09:55+0000\n"
"PO-Revision-Date: 2023-10-17 18:20+0300\n" "PO-Revision-Date: 2023-10-14 08:00+0300\n"
"Last-Translator: Sabri Ünal <libreajans@gmail.com>\n" "Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Türkçe <takim@gnome.org.tr>\n" "Language-Team: Türkçe <takim@gnome.org.tr>\n"
"Language: tr\n" "Language: tr\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@@ -61,58 +61,58 @@ msgstr "İçerikler “%s” olarak sağlanamıyor"
msgid "Cannot provide contents as %s" msgid "Cannot provide contents as %s"
msgstr "İçerikler %s olarak sağlanamıyor" msgstr "İçerikler %s olarak sağlanamıyor"
#: gdk/gdkdisplay.c:164 gdk/gdkglcontext.c:442 #: gdk/gdkdisplay.c:163 gdk/gdkglcontext.c:442
msgid "The current backend does not support OpenGL" msgid "The current backend does not support OpenGL"
msgstr "Şimdiki arka uç OpenGLi desteklemiyor" msgstr "Şimdiki arka uç OpenGLi desteklemiyor"
#: gdk/gdkdisplay.c:1259 gdk/gdksurface.c:1252 #: gdk/gdkdisplay.c:1258 gdk/gdksurface.c:1252
msgid "Vulkan support disabled via GDK_DEBUG" msgid "Vulkan support disabled via GDK_DEBUG"
msgstr "Vulkan desteği GDK_DEBUG yoluyla devre dışı bırakılmış" msgstr "Vulkan desteği GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1291 #: gdk/gdkdisplay.c:1290
msgid "GL support disabled via GDK_DEBUG" msgid "GL support disabled via GDK_DEBUG"
msgstr "GL desteği, GDK_DEBUG yoluyla devre dışı bırakılmış" msgstr "GL desteği, GDK_DEBUG yoluyla devre dışı bırakılmış"
#: gdk/gdkdisplay.c:1589 #: gdk/gdkdisplay.c:1588
msgid "No EGL configuration available" msgid "No EGL configuration available"
msgstr "Kullanılabilir EGL yapılandırması yok" msgstr "Kullanılabilir EGL yapılandırması yok"
#: gdk/gdkdisplay.c:1597 #: gdk/gdkdisplay.c:1596
msgid "Failed to get EGL configurations" msgid "Failed to get EGL configurations"
msgstr "EGL yapılandırmaları alınamadı" msgstr "EGL yapılandırmaları alınamadı"
#: gdk/gdkdisplay.c:1627 #: gdk/gdkdisplay.c:1626
msgid "No EGL configuration with required features found" msgid "No EGL configuration with required features found"
msgstr "Gerekli özellikleri olan EGL yapılandırması bulunamadı" msgstr "Gerekli özellikleri olan EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1634 #: gdk/gdkdisplay.c:1633
msgid "No perfect EGL configuration found" msgid "No perfect EGL configuration found"
msgstr "Kusursuz EGL yapılandırması bulunamadı" msgstr "Kusursuz EGL yapılandırması bulunamadı"
#: gdk/gdkdisplay.c:1676 #: gdk/gdkdisplay.c:1675
#, c-format #, c-format
msgid "EGL implementation is missing extension %s" msgid "EGL implementation is missing extension %s"
msgid_plural "EGL implementation is missing %2$d extensions: %1$s" msgid_plural "EGL implementation is missing %2$d extensions: %1$s"
msgstr[0] "EGL uygulamasında %2$d eksik uzantı: %1$s" msgstr[0] "EGL uygulamasında %2$d eksik uzantı: %1$s"
# https://twitter.com/mserdark/status/932936929213079559 # https://twitter.com/mserdark/status/932936929213079559
#: gdk/gdkdisplay.c:1709 #: gdk/gdkdisplay.c:1708
msgid "libEGL not available in this sandbox" msgid "libEGL not available in this sandbox"
msgstr "libEGL bu kum havuzunda kullanılamıyor" msgstr "libEGL bu kum havuzunda kullanılamıyor"
#: gdk/gdkdisplay.c:1710 #: gdk/gdkdisplay.c:1709
msgid "libEGL not available" msgid "libEGL not available"
msgstr "libEGL kullanılamıyor" msgstr "libEGL kullanılamıyor"
#: gdk/gdkdisplay.c:1720 #: gdk/gdkdisplay.c:1719
msgid "Failed to create EGL display" msgid "Failed to create EGL display"
msgstr "EGL ekranı oluşturulamadı" msgstr "EGL ekranı oluşturulamadı"
#: gdk/gdkdisplay.c:1730 #: gdk/gdkdisplay.c:1729
msgid "Could not initialize EGL display" msgid "Could not initialize EGL display"
msgstr "EGL ekranı ilklendirilemedi" msgstr "EGL ekranı ilklendirilemedi"
#: gdk/gdkdisplay.c:1741 #: gdk/gdkdisplay.c:1740
#, c-format #, c-format
msgid "EGL version %d.%d is too old. GTK requires %d.%d" 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" msgstr "EGL sürümü %d.%d çok eski. GTK, %d.%d gerektiriyor"
@@ -3154,7 +3154,7 @@ msgstr "Birim ayrılamadı"
#. Allow to cancel the operation #. Allow to cancel the operation
#: gtk/gtkplacesview.c:1445 #: gtk/gtkplacesview.c:1445
msgid "Cance_l" msgid "Cance_l"
msgstr "İ_ptal" msgstr "İpta_l"
#: gtk/gtkplacesview.c:1592 #: gtk/gtkplacesview.c:1592
msgid "AppleTalk" msgid "AppleTalk"

View File

@@ -125,10 +125,7 @@ gtk_tests = [
] ]
if os_unix if os_unix
gtk_tests += [ gtk_tests += [['testfontchooserdialog']]
['testfontchooserdialog'],
['testdmabuf'],
]
endif endif
if x11_enabled if x11_enabled
@@ -149,11 +146,3 @@ foreach t: gtk_tests
dependencies: [libgtk_dep, libm], dependencies: [libgtk_dep, libm],
) )
endforeach endforeach
executable('testsubsurface',
sources: '@0@.c'.format('testsubsurface'),
c_args: common_cflags + ['-DGTK_COMPILATION'],
dependencies: libgtk_static_dep,
install: false,
)

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;
}

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;
}

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 ();
}

View File

@@ -102,15 +102,10 @@ gdk_memory_format_bytes_per_pixel (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8: 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_PREMULTIPLIED:
case GDK_MEMORY_G16A16: case GDK_MEMORY_G16A16:
case GDK_MEMORY_A32_FLOAT: 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_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8: 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_G8:
case GDK_MEMORY_G8A8: case GDK_MEMORY_G8A8:
case GDK_MEMORY_G8A8_PREMULTIPLIED: case GDK_MEMORY_G8A8_PREMULTIPLIED:
@@ -207,15 +197,10 @@ gdk_memory_format_n_colors (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8: 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_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16: case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: 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_R32G32B32_FLOAT:
case GDK_MEMORY_G8: case GDK_MEMORY_G8:
case GDK_MEMORY_G16: case GDK_MEMORY_G16:
case GDK_MEMORY_B8G8R8X8:
case GDK_MEMORY_X8R8G8B8:
case GDK_MEMORY_R8G8B8X8:
case GDK_MEMORY_X8B8G8R8:
return FALSE; return FALSE;
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
case GDK_MEMORY_A8R8G8B8: case GDK_MEMORY_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
@@ -302,7 +282,6 @@ gdk_memory_format_is_premultiplied (GdkMemoryFormat format)
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED: case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
case GDK_MEMORY_R32G32B32A32_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_A8R8G8B8:
case GDK_MEMORY_R8G8B8A8: case GDK_MEMORY_R8G8B8A8:
case GDK_MEMORY_A8B8G8R8: 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:
case GDK_MEMORY_R16G16B16A16_FLOAT: case GDK_MEMORY_R16G16B16A16_FLOAT:
case GDK_MEMORY_R32G32B32A32_FLOAT: case GDK_MEMORY_R32G32B32A32_FLOAT:
@@ -346,7 +321,45 @@ gdk_memory_format_is_premultiplied (GdkMemoryFormat format)
static gboolean static gboolean
gdk_memory_format_is_deep (GdkMemoryFormat format) 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 static gboolean
@@ -360,7 +373,6 @@ gdk_memory_format_pixel_equal (GdkMemoryFormat format,
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED: case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED: case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
case GDK_MEMORY_R8G8B8: case GDK_MEMORY_R8G8B8:
case GDK_MEMORY_B8G8R8: case GDK_MEMORY_B8G8R8:
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
@@ -373,14 +385,6 @@ gdk_memory_format_pixel_equal (GdkMemoryFormat format,
case GDK_MEMORY_G8A8_PREMULTIPLIED: case GDK_MEMORY_G8A8_PREMULTIPLIED:
return memcmp (pixel1, pixel2, gdk_memory_format_bytes_per_pixel (format)) == 0; 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_R16G16B16:
case GDK_MEMORY_R16G16B16A16: case GDK_MEMORY_R16G16B16A16:
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED: case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
@@ -577,9 +581,6 @@ texture_builder_set_pixel (TextureBuilder *builder,
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED: case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
set_pixel_u8 (data, 0, 1, 2, 3, TRUE, color); set_pixel_u8 (data, 0, 1, 2, 3, TRUE, color);
break; break;
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
set_pixel_u8 (data, 3, 2, 1, 0, TRUE, color);
break;
case GDK_MEMORY_B8G8R8A8: case GDK_MEMORY_B8G8R8A8:
set_pixel_u8 (data, 2, 1, 0, 3, FALSE, color); set_pixel_u8 (data, 2, 1, 0, 3, FALSE, color);
break; break;
@@ -592,18 +593,6 @@ texture_builder_set_pixel (TextureBuilder *builder,
case GDK_MEMORY_A8B8G8R8: case GDK_MEMORY_A8B8G8R8:
set_pixel_u8 (data, 3, 2, 1, 0, FALSE, color); set_pixel_u8 (data, 3, 2, 1, 0, FALSE, color);
break; 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: case GDK_MEMORY_R8G8B8:
set_pixel_u8 (data, 0, 1, 2, -1, TRUE, color); set_pixel_u8 (data, 0, 1, 2, -1, TRUE, color);
break; break;

View File

@@ -52,24 +52,19 @@ foreach t : tests
endforeach endforeach
internal_tests = [ internal_tests = [
{ 'name': 'image' }, 'image',
{ 'name': 'texture' }, 'texture',
{ 'name': 'gltexture' }, 'gltexture',
{ 'name': 'dmabuftexture', 'suites': 'failing' },
] ]
foreach t : internal_tests foreach t : internal_tests
test_name = t.get('name') test_exe = executable(t, '@0@.c'.format(t),
test_exe = executable(test_name,
sources: '@0@.c'.format(test_name),
c_args: common_cflags + ['-DGTK_COMPILATION'], c_args: common_cflags + ['-DGTK_COMPILATION'],
dependencies: libgtk_static_dep, dependencies: libgtk_static_dep,
install: false, install: false,
) )
suites = ['gdk'] + t.get('suites', []) test(t, test_exe,
test(test_name, test_exe,
args: [ '--tap', '-k' ], args: [ '--tap', '-k' ],
protocol: 'tap', protocol: 'tap',
env: [ env: [
@@ -77,6 +72,6 @@ foreach t : internal_tests
'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()),
'DBUS_SESSION_BUS_ADDRESS=', 'DBUS_SESSION_BUS_ADDRESS=',
], ],
suite: suites, suite: 'gdk',
) )
endforeach endforeach

View File

@@ -1,10 +1 @@
linear-gradient { 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;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

After

Width:  |  Height:  |  Size: 203 B

View File

@@ -1,5 +1,4 @@
opacity { opacity {
opacity: 0.6;
child: transform { child: transform {
transform: translate(15, 15); transform: translate(15, 15);
child: container { child: container {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 127 B

View File

@@ -1,30 +0,0 @@
texture-scale {
bounds: 4 4 24 24;
filter: nearest;
texture: "texture1" url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAJ0lEQVQYlWNkYPjwnwEPYMInSbqC\
AwwCDAcYBPCb4HAAlc9Ie0cCAB8uBo20gfbVAAAAAElFTkSuQmCC\
");
}
repeat {
bounds: 32 0 32 32;
child: texture-scale {
bounds: 0 0 1 1;
filter: nearest;
texture: "texture1";
}
}
repeat {
bounds: 0 32 32 32;
child: texture-scale {
bounds: 0 0 1 1;
texture: "texture1";
}
}
repeat {
bounds: 32 32 32 32;
child: texture-scale {
bounds: 0 0 1 1;
filter: trilinear;
texture: "texture1";
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

View File

@@ -98,7 +98,6 @@ compare_render_tests = [
'shadow-opacity', 'shadow-opacity',
'shrink-rounded-border', 'shrink-rounded-border',
'stroke', 'stroke',
'texture-scale-filters-3d',
'texture-scale-magnify-10000x', 'texture-scale-magnify-10000x',
'texture-scale-magnify-rotate', 'texture-scale-magnify-rotate',
'texture-scale-stripes', 'texture-scale-stripes',

View File

@@ -182,10 +182,6 @@ test_type (gconstpointer data)
strcmp (pspec->name, "storable-formats") == 0) strcmp (pspec->name, "storable-formats") == 0)
check = FALSE; check = FALSE;
if (g_type_is_a (type, GDK_TYPE_DMABUF_TEXTURE_BUILDER) &&
strcmp (pspec->name, "display") == 0)
check = FALSE;
/* set in the constructor */ /* set in the constructor */
if (g_type_is_a (type, GSK_TYPE_GL_SHADER) && if (g_type_is_a (type, GSK_TYPE_GL_SHADER) &&
strcmp (pspec->name, "source") == 0) strcmp (pspec->name, "source") == 0)