Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Gnome/gtk/   (Gnome Linux Desktop Version 4.23.2©)  Datei vom 30.5.2026 mit Größe 465 B image not shown  

SSL udmabuf.c

  Interaktion und
PortierbarkeitC
 

#include "config.h"

#include "udmabuf.h"

#if defined(HAVE_DMABUF) && defined(HAVE_UDMABUF)

#include <inttypes.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/udmabuf.h>
#include <errno.h>
#include <gtk/gtk.h>
#include <gio/gio.h>
#include "gdk/gdkdmabuffourccprivate.h"


typedef struct
{
  int mem_fd;
  int dmabuf_fd;
  size_t size;
  gpointer data;
} UDmabuf;

static int udmabuf_fd;

gboolean
udmabuf_initialize (GError **error)
{
  if (udmabuf_fd == 0)
    {
      udmabuf_fd = open ("/dev/udmabuf", O_RDWR);
      if (udmabuf_fd == -1)
        {
          g_set_error (error,
                       G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Failed to open /dev/udmabuf: %s",
                       g_strerror (errno));
        }
    }

  return udmabuf_fd != -1;
}

static void
udmabuf_free (gpointer data)
{
  UDmabuf *udmabuf = data;

  munmap (udmabuf->data, udmabuf->size);
  close (udmabuf->mem_fd);
  close (udmabuf->dmabuf_fd);

  g_free (udmabuf);
}

#define align(x,y) (((x) + (y) - 1) & ~((y) - 1))

static UDmabuf *
udmabuf_allocate (size_t   size,
                  GError **error)
{
  int mem_fd = -1;
  int dmabuf_fd = -1;
  uint64_t alignment;
  int res;
  gpointer data;
  UDmabuf *udmabuf;

  if (udmabuf_fd == 0)
    {
      if (!udmabuf_initialize (error))
        goto fail;
    }

  if (udmabuf_fd == -1)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "udmabuf not available");
      goto fail;
    }

  alignment = sysconf (_SC_PAGE_SIZE);

  size = align (size, alignment);

  mem_fd = memfd_create ("gtk-testsuite", MFD_ALLOW_SEALING);
  if (mem_fd == -1)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to open /dev/udmabuf: %s",
                   g_strerror (errno));
      goto fail;
    }

  res = ftruncate (mem_fd, size);
  if (res == -1)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "ftruncate failed: %s",
                    g_strerror (errno));
      goto fail;
    }

  if (fcntl (mem_fd, F_ADD_SEALS, F_SEAL_SHRINK) < 0)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "ftruncate failed: %s",
                    g_strerror (errno));
      goto fail;
    }

  dmabuf_fd = ioctl (udmabuf_fd,
                     UDMABUF_CREATE,
                     &(struct udmabuf_create) {
                       .memfd = mem_fd,
                       .flags = UDMABUF_FLAGS_CLOEXEC,
                       .offset = 0,
                       .size = size
                     });

  if (dmabuf_fd < 0)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "UDMABUF_CREATE ioctl failed: %s",
                    g_strerror (errno));
      goto fail;
    }

  data = mmap (NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, mem_fd, 0);

  if (data == NULL || data == MAP_FAILED)
    {
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "mmap failed: %s",
                    g_strerror (errno));
      goto fail;
    }

  udmabuf = g_new0 (UDmabuf, 1);

  udmabuf->mem_fd = mem_fd;
  udmabuf->dmabuf_fd = dmabuf_fd;
  udmabuf->size = size;
  udmabuf->data = data;

  return udmabuf;

fail:
  if (mem_fd != -1)
    close (mem_fd);
  if (dmabuf_fd != -1)
    close (dmabuf_fd);

  return NULL;
}


GdkTexture *
udmabuf_texture_new (gsize           width,
                     gsize           height,
                     guint           fourcc,
                     GdkColorState  *color_state,
                     gboolean        premultiplied,
                     GBytes         *bytes,
                     gsize           stride,
                     GError        **error)
{
  GdkDmabufTextureBuilder *builder;
  GdkTexture *texture;
  UDmabuf *udmabuf;
  gconstpointer data;
  gsize size;

  /* Many graphics cards need this and Mesa tries to align its own buffers this way */
  g_assert (stride % UDMABUF_STRIDE_ALIGN == 0);

  data = g_bytes_get_data (bytes, &size);

  udmabuf = udmabuf_allocate (size, error);
  if (udmabuf == NULL)
    return NULL;

  memcpy (udmabuf->data, data, 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, fourcc);
  gdk_dmabuf_texture_builder_set_modifier (builder, 0);
  gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
  gdk_dmabuf_texture_builder_set_premultiplied (builder, premultiplied);
  gdk_dmabuf_texture_builder_set_n_planes (builder, 1);
  gdk_dmabuf_texture_builder_set_fd (builder, 0, udmabuf->dmabuf_fd);
  gdk_dmabuf_texture_builder_set_stride (builder, 0, stride);
  gdk_dmabuf_texture_builder_set_offset (builder, 00);

  texture = gdk_dmabuf_texture_builder_build (builder, udmabuf_free, udmabuf, error);

  g_object_unref (builder);

  return texture;
}

#else

GdkTexture *
udmabuf_texture_new (gsize           width,
                     gsize           height,
                     guint           fourcc,
                     GdkColorState  *color_state,
                     gboolean        premultiplied,
                     GBytes         *bytes,
                     gsize           stride,
                     GError        **error)
{
  g_set_error (error,
               G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
               "Dmabufs are not supported");
  return NULL;
}

#endif

GdkTexture *
udmabuf_texture_from_texture (GdkTexture  *texture,
                              GError     **error)
{
  GdkTextureDownloader *downloader;
  guint fourcc;
  gboolean premultiplied;
  guchar *data;
  gsize width, height, stride;
  GBytes *bytes;
  GdkTexture *texture2;

  switch ((int) gdk_texture_get_format (texture))
    {
#ifdef HAVE_DMABUF
    case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
      fourcc = DRM_FORMAT_ARGB8888;
      premultiplied = TRUE;
      break;
    case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
      fourcc = DRM_FORMAT_BGRA8888;
      premultiplied = TRUE;
      break;
    case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
      fourcc = DRM_FORMAT_ABGR8888;
      premultiplied = TRUE;
      break;
    case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
      fourcc = DRM_FORMAT_RGBA8888;
      premultiplied = TRUE;
      break;
    case GDK_MEMORY_B8G8R8A8:
      fourcc = DRM_FORMAT_ARGB8888;
      premultiplied = FALSE;
      break;
    case GDK_MEMORY_A8R8G8B8:
      fourcc = DRM_FORMAT_BGRA8888;
      premultiplied = FALSE;
      break;
    case GDK_MEMORY_R8G8B8A8:
      fourcc = DRM_FORMAT_ABGR8888;
      premultiplied = FALSE;
      break;
    case GDK_MEMORY_A8B8G8R8:
      fourcc = DRM_FORMAT_RGBA8888;
      premultiplied = FALSE;
      break;
    case GDK_MEMORY_R16G16B16A16_FLOAT:
      fourcc = DRM_FORMAT_ABGR16161616F;
      premultiplied = FALSE;
      break;
    case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
      fourcc = DRM_FORMAT_ABGR16161616F;
      premultiplied = TRUE;
      break;
#endif
    default:
      g_set_error (error,
                   G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Unsupported memory format %u", gdk_texture_get_format (texture));
      return NULL;
    }

  width = gdk_texture_get_width (texture);
  height = gdk_texture_get_height (texture);
  stride = (width * 4 + (UDMABUF_STRIDE_ALIGN - 1)) & ~(UDMABUF_STRIDE_ALIGN - 1);
  data = g_malloc_n(stride, height);

  downloader = gdk_texture_downloader_new (texture);
  gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (texture));
  gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (texture));
  gdk_texture_downloader_download_into (downloader, data, stride);
  gdk_texture_downloader_free (downloader);

  bytes = g_bytes_new_take(data, stride * height);

  texture2 = udmabuf_texture_new (gdk_texture_get_width (texture),
                                  gdk_texture_get_height (texture),
                                  fourcc,
                                  gdk_texture_get_color_state (texture),
                                  premultiplied,
                                  bytes, stride,
                                  error);
  g_bytes_unref (bytes);

  return texture2;
}


Messung V0.5 in Prozent
C=99 H=92 G=95

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.13Angebot  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-07-03) ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.