Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,8 @@ if have_wayland
'wayland/meta-wayland-seat.h',
'wayland/meta-wayland-shell-surface.c',
'wayland/meta-wayland-shell-surface.h',
'wayland/meta-wayland-single-pixel-buffer.c',
'wayland/meta-wayland-single-pixel-buffer.h',
'wayland/meta-wayland-subsurface.c',
'wayland/meta-wayland-subsurface.h',
'wayland/meta-wayland-surface.c',
Expand Down Expand Up @@ -821,6 +823,7 @@ if have_wayland
['pointer-warp-v1', 'private',],
['primary-selection', 'unstable', 'v1', ],
['relative-pointer', 'unstable', 'v1', ],
['single-pixel-buffer', 'staging', 'v1', ],
['xdg-system-bell', 'staging', 'v1', ],
['tablet', 'unstable', 'v2', ],
['text-input', 'unstable', 'v3', ],
Expand Down
18 changes: 18 additions & 0 deletions src/wayland/meta-wayland-buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
MetaWaylandEglStream *stream;
#endif
MetaWaylandDmaBufBuffer *dma_buf;
MetaWaylandSinglePixelBuffer *single_pixel_buffer;

if (wl_shm_buffer_get (buffer->resource) != NULL)
{
Expand Down Expand Up @@ -184,6 +185,14 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
return TRUE;
}

single_pixel_buffer = meta_wayland_single_pixel_buffer_from_buffer (buffer);
if (single_pixel_buffer)
{
buffer->single_pixel.single_pixel_buffer = single_pixel_buffer;
buffer->type = META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL;
return TRUE;
}

return FALSE;
}

Expand Down Expand Up @@ -522,6 +531,10 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
return meta_wayland_dma_buf_buffer_attach (buffer,
texture,
error);
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
return meta_wayland_single_pixel_buffer_attach (buffer,
texture,
error);
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
g_assert_not_reached ();
return FALSE;
Expand Down Expand Up @@ -628,6 +641,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
#endif
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
res = TRUE;
break;
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
Expand Down Expand Up @@ -706,6 +720,7 @@ meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
switch (buffer->type)
{
case META_WAYLAND_BUFFER_TYPE_SHM:
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
return NULL;
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
return try_acquire_egl_image_scanout (buffer, onscreen);
Expand Down Expand Up @@ -744,6 +759,9 @@ meta_wayland_buffer_finalize (GObject *object)
#endif
g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref);
g_clear_object (&buffer->dma_buf.dma_buf);
g_clear_pointer (&buffer->single_pixel.single_pixel_buffer,
meta_wayland_single_pixel_buffer_free);
cogl_clear_object (&buffer->single_pixel.texture);

G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object);
}
Expand Down
7 changes: 7 additions & 0 deletions src/wayland/meta-wayland-buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "wayland/meta-wayland-types.h"
#include "wayland/meta-wayland-egl-stream.h"
#include "wayland/meta-wayland-dma-buf.h"
#include "wayland/meta-wayland-single-pixel-buffer.h"

typedef enum _MetaWaylandBufferType
{
Expand All @@ -42,6 +43,7 @@ typedef enum _MetaWaylandBufferType
META_WAYLAND_BUFFER_TYPE_EGL_STREAM,
#endif
META_WAYLAND_BUFFER_TYPE_DMA_BUF,
META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL,
} MetaWaylandBufferType;

struct _MetaWaylandBuffer
Expand Down Expand Up @@ -70,6 +72,11 @@ struct _MetaWaylandBuffer
MetaWaylandDmaBufBuffer *dma_buf;
CoglTexture *texture;
} dma_buf;

struct {
MetaWaylandSinglePixelBuffer *single_pixel_buffer;
CoglTexture *texture;
} single_pixel;
};

#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ())
Expand Down
182 changes: 182 additions & 0 deletions src/wayland/meta-wayland-single-pixel-buffer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Copyright (C) 2022 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/

#include "config.h"

#include "wayland/meta-wayland-single-pixel-buffer.h"

#include "backends/meta-backend-private.h"
#include "wayland/meta-wayland-buffer.h"
#include "wayland/meta-wayland-private.h"

#include "single-pixel-buffer-v1-server-protocol.h"

struct _MetaWaylandSinglePixelBuffer
{
uint32_t r;
uint32_t g;
uint32_t b;
uint32_t a;
};

static void
buffer_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}

static const struct wl_buffer_interface single_pixel_buffer_implementation =
{
buffer_destroy,
};

static void
single_pixel_buffer_manager_destroy (struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy (resource);
}

static void
single_pixel_buffer_manager_create_1px_rgba32_buffer (struct wl_client *client,
struct wl_resource *resource,
uint32_t buffer_id,
uint32_t r,
uint32_t g,
uint32_t b,
uint32_t a)
{
MetaWaylandSinglePixelBuffer *single_pixel_buffer;
struct wl_resource *buffer_resource;

single_pixel_buffer = g_new0 (MetaWaylandSinglePixelBuffer, 1);
single_pixel_buffer->r = r;
single_pixel_buffer->g = g;
single_pixel_buffer->b = b;
single_pixel_buffer->a = a;

buffer_resource =
wl_resource_create (client, &wl_buffer_interface, 1, buffer_id);
wl_resource_set_implementation (buffer_resource,
&single_pixel_buffer_implementation,
single_pixel_buffer, NULL);
meta_wayland_buffer_from_resource (buffer_resource);
}

static const struct wp_single_pixel_buffer_manager_v1_interface
single_pixel_buffer_manager_implementation =
{
single_pixel_buffer_manager_destroy,
single_pixel_buffer_manager_create_1px_rgba32_buffer,
};

static void
single_pixel_buffer_manager_bind (struct wl_client *client,
void *user_data,
uint32_t version,
uint32_t id)
{
MetaWaylandCompositor *compositor = user_data;
struct wl_resource *resource;

resource = wl_resource_create (client,
&wp_single_pixel_buffer_manager_v1_interface,
version, id);
wl_resource_set_implementation (resource,
&single_pixel_buffer_manager_implementation,
compositor, NULL);
}

gboolean
meta_wayland_single_pixel_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
GError **error)
{
MetaBackend *backend = meta_get_backend ();
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
CoglContext *cogl_context =
clutter_backend_get_cogl_context (clutter_backend);
MetaWaylandSinglePixelBuffer *single_pixel_buffer =
wl_resource_get_user_data (buffer->resource);
uint8_t data[4];
CoglPixelFormat pixel_format;
CoglTexture2D *tex_2d;

if (buffer->single_pixel.texture)
{
*texture = g_object_ref (buffer->single_pixel.texture);
return TRUE;
}

data[0] = single_pixel_buffer->b / (UINT32_MAX / 0xff);
data[1] = single_pixel_buffer->g / (UINT32_MAX / 0xff);
data[2] = single_pixel_buffer->r / (UINT32_MAX / 0xff);
data[3] = single_pixel_buffer->a / (UINT32_MAX / 0xff);

if (data[3] == UINT8_MAX)
pixel_format = COGL_PIXEL_FORMAT_BGR_888;
else
pixel_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;

tex_2d = cogl_texture_2d_new_from_data (cogl_context,
1, 1,
pixel_format,
4, data,
error);
if (!tex_2d)
return FALSE;

buffer->single_pixel.texture = COGL_TEXTURE (tex_2d);

cogl_clear_object (texture);
*texture = cogl_object_ref (buffer->single_pixel.texture);
return TRUE;
}

MetaWaylandSinglePixelBuffer *
meta_wayland_single_pixel_buffer_from_buffer (MetaWaylandBuffer *buffer)
{
if (!buffer->resource)
return NULL;

if (wl_resource_instance_of (buffer->resource, &wl_buffer_interface,
&single_pixel_buffer_implementation))
return wl_resource_get_user_data (buffer->resource);

return NULL;
}

void
meta_wayland_single_pixel_buffer_free (MetaWaylandSinglePixelBuffer *single_pixel_buffer)
{
g_free (single_pixel_buffer);
}

void
meta_wayland_init_single_pixel_buffer_manager (MetaWaylandCompositor *compositor)
{
if (!wl_global_create (compositor->wayland_display,
&wp_single_pixel_buffer_manager_v1_interface,
META_WP_SINGLE_PIXEL_BUFFER_V1_VERSION,
compositor,
single_pixel_buffer_manager_bind))
g_warning ("Failed to create wp_single_pixel_buffer_manager_v1 global");
}
41 changes: 41 additions & 0 deletions src/wayland/meta-wayland-single-pixel-buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/

#ifndef META_WAYLAND_SINGLE_PIXEL_BUFFER_H
#define META_WAYLAND_SINGLE_PIXEL_BUFFER_H

#include <glib.h>

#include "cogl/cogl.h"
#include "wayland/meta-wayland-types.h"

typedef struct _MetaWaylandSinglePixelBuffer MetaWaylandSinglePixelBuffer;

gboolean meta_wayland_single_pixel_buffer_attach (MetaWaylandBuffer *buffer,
CoglTexture **texture,
GError **error);

MetaWaylandSinglePixelBuffer * meta_wayland_single_pixel_buffer_from_buffer (MetaWaylandBuffer *buffer);

void meta_wayland_init_single_pixel_buffer_manager (MetaWaylandCompositor *compositor);

void meta_wayland_single_pixel_buffer_free (MetaWaylandSinglePixelBuffer *single_pixel_buffer);

#endif /* META_WAYLAND_SINGLE_PIXEL_BUFFER_H */
6 changes: 4 additions & 2 deletions src/wayland/meta-wayland-surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,10 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
* it until is replaced by a subsequent wl_surface.commit or when the
* wl_surface is destroyed.
*/
surface->buffer_held = (state->buffer &&
!wl_shm_buffer_get (state->buffer->resource));
surface->buffer_held =
(state->buffer &&
(state->buffer->type != META_WAYLAND_BUFFER_TYPE_SHM &&
state->buffer->type != META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL));
}

if (state->scale > 0)
Expand Down
1 change: 1 addition & 0 deletions src/wayland/meta-wayland-versions.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1
#define META_XDG_TOPLEVEL_TAG_V1_VERSION 1
#define META_WP_CURSOR_SHAPE_VERSION 2
#define META_WP_SINGLE_PIXEL_BUFFER_V1_VERSION 1
#define META_WP_POINTER_WARP_VERSION 1
#define META_WP_SYSTEM_BELL_V1_VERSION 1
#define META_ZWLR_LAYER_SHELL_V1_VERSION 4
Expand Down
1 change: 1 addition & 0 deletions src/wayland/meta-wayland.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ meta_wayland_compositor_setup (MetaWaylandCompositor *wayland_compositor)
meta_wayland_xdg_foreign_init (compositor);
meta_wayland_legacy_xdg_foreign_init (compositor);
meta_wayland_dma_buf_init (compositor);
meta_wayland_init_single_pixel_buffer_manager (compositor);
meta_wayland_keyboard_shortcuts_inhibit_init (compositor);
meta_wayland_surface_inhibit_shortcuts_dialog_init ();
meta_wayland_text_input_init (compositor);
Expand Down
Loading