Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -554,6 +554,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 @@ -818,6 +820,7 @@ if have_wayland
['pointer-gestures', 'unstable', 'v1', ],
['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
179 changes: 179 additions & 0 deletions src/wayland/meta-wayland-single-pixel-buffer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* 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)
return TRUE;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


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_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