mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 18:11:05 -05:00
wayland: Add single pixel buffer support
The "single pixel buffer" Wayland protocol extension provides a way for clients to create 1x1 buffers with a single color, specified by providing the color channels (red, green and blue) as well as the alpha channel as a 32 bit unsigned integer. For now, this is turned into a 1x1 texture. Future potential improvements is to hook things up to the scanout candidate logic and turn it into a scanout capable DMA buffer. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2246>
This commit is contained in:
parent
823e3a5c72
commit
2cb7499735
@ -611,6 +611,8 @@ if have_wayland
|
|||||||
'wayland/meta-wayland-seat.h',
|
'wayland/meta-wayland-seat.h',
|
||||||
'wayland/meta-wayland-shell-surface.c',
|
'wayland/meta-wayland-shell-surface.c',
|
||||||
'wayland/meta-wayland-shell-surface.h',
|
'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.c',
|
||||||
'wayland/meta-wayland-subsurface.h',
|
'wayland/meta-wayland-subsurface.h',
|
||||||
'wayland/meta-wayland-surface.c',
|
'wayland/meta-wayland-surface.c',
|
||||||
@ -928,6 +930,7 @@ if have_wayland
|
|||||||
['presentation-time', 'stable', ],
|
['presentation-time', 'stable', ],
|
||||||
['primary-selection', 'unstable', 'v1', ],
|
['primary-selection', 'unstable', 'v1', ],
|
||||||
['relative-pointer', 'unstable', 'v1', ],
|
['relative-pointer', 'unstable', 'v1', ],
|
||||||
|
['single-pixel-buffer', 'staging', 'v1', ],
|
||||||
['tablet', 'unstable', 'v2', ],
|
['tablet', 'unstable', 'v2', ],
|
||||||
['text-input', 'unstable', 'v3', ],
|
['text-input', 'unstable', 'v3', ],
|
||||||
['viewporter', 'stable', ],
|
['viewporter', 'stable', ],
|
||||||
|
@ -140,6 +140,7 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
|||||||
MetaWaylandEglStream *stream;
|
MetaWaylandEglStream *stream;
|
||||||
#endif
|
#endif
|
||||||
MetaWaylandDmaBufBuffer *dma_buf;
|
MetaWaylandDmaBufBuffer *dma_buf;
|
||||||
|
MetaWaylandSinglePixelBuffer *single_pixel_buffer;
|
||||||
|
|
||||||
if (wl_shm_buffer_get (buffer->resource) != NULL)
|
if (wl_shm_buffer_get (buffer->resource) != NULL)
|
||||||
{
|
{
|
||||||
@ -194,6 +195,14 @@ meta_wayland_buffer_realize (MetaWaylandBuffer *buffer)
|
|||||||
return TRUE;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,6 +585,10 @@ meta_wayland_buffer_attach (MetaWaylandBuffer *buffer,
|
|||||||
return meta_wayland_dma_buf_buffer_attach (buffer,
|
return meta_wayland_dma_buf_buffer_attach (buffer,
|
||||||
texture,
|
texture,
|
||||||
error);
|
error);
|
||||||
|
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
|
||||||
|
return meta_wayland_single_pixel_buffer_attach (buffer,
|
||||||
|
texture,
|
||||||
|
error);
|
||||||
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
|
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -682,6 +695,7 @@ meta_wayland_buffer_process_damage (MetaWaylandBuffer *buffer,
|
|||||||
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
|
case META_WAYLAND_BUFFER_TYPE_EGL_STREAM:
|
||||||
#endif
|
#endif
|
||||||
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
|
case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
|
||||||
|
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
break;
|
break;
|
||||||
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
|
case META_WAYLAND_BUFFER_TYPE_UNKNOWN:
|
||||||
@ -757,6 +771,7 @@ meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
|
|||||||
switch (buffer->type)
|
switch (buffer->type)
|
||||||
{
|
{
|
||||||
case META_WAYLAND_BUFFER_TYPE_SHM:
|
case META_WAYLAND_BUFFER_TYPE_SHM:
|
||||||
|
case META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL:
|
||||||
return NULL;
|
return NULL;
|
||||||
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
|
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
|
||||||
return try_acquire_egl_image_scanout (buffer, onscreen);
|
return try_acquire_egl_image_scanout (buffer, onscreen);
|
||||||
@ -795,6 +810,9 @@ meta_wayland_buffer_finalize (GObject *object)
|
|||||||
#endif
|
#endif
|
||||||
g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref);
|
g_clear_pointer (&buffer->dma_buf.texture, cogl_object_unref);
|
||||||
g_clear_object (&buffer->dma_buf.dma_buf);
|
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);
|
G_OBJECT_CLASS (meta_wayland_buffer_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "wayland/meta-wayland-types.h"
|
#include "wayland/meta-wayland-types.h"
|
||||||
#include "wayland/meta-wayland-egl-stream.h"
|
#include "wayland/meta-wayland-egl-stream.h"
|
||||||
#include "wayland/meta-wayland-dma-buf.h"
|
#include "wayland/meta-wayland-dma-buf.h"
|
||||||
|
#include "wayland/meta-wayland-single-pixel-buffer.h"
|
||||||
|
|
||||||
typedef enum _MetaWaylandBufferType
|
typedef enum _MetaWaylandBufferType
|
||||||
{
|
{
|
||||||
@ -42,6 +43,7 @@ typedef enum _MetaWaylandBufferType
|
|||||||
META_WAYLAND_BUFFER_TYPE_EGL_STREAM,
|
META_WAYLAND_BUFFER_TYPE_EGL_STREAM,
|
||||||
#endif
|
#endif
|
||||||
META_WAYLAND_BUFFER_TYPE_DMA_BUF,
|
META_WAYLAND_BUFFER_TYPE_DMA_BUF,
|
||||||
|
META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL,
|
||||||
} MetaWaylandBufferType;
|
} MetaWaylandBufferType;
|
||||||
|
|
||||||
struct _MetaWaylandBuffer
|
struct _MetaWaylandBuffer
|
||||||
@ -71,6 +73,11 @@ struct _MetaWaylandBuffer
|
|||||||
MetaWaylandDmaBufBuffer *dma_buf;
|
MetaWaylandDmaBufBuffer *dma_buf;
|
||||||
CoglTexture *texture;
|
CoglTexture *texture;
|
||||||
} dma_buf;
|
} dma_buf;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
MetaWaylandSinglePixelBuffer *single_pixel_buffer;
|
||||||
|
CoglTexture *texture;
|
||||||
|
} single_pixel;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ())
|
#define META_TYPE_WAYLAND_BUFFER (meta_wayland_buffer_get_type ())
|
||||||
|
180
src/wayland/meta-wayland-single-pixel-buffer.c
Normal file
180
src/wayland/meta-wayland-single-pixel-buffer.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor = wl_resource_get_user_data (resource);
|
||||||
|
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 (compositor, 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;
|
||||||
|
|
||||||
|
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
src/wayland/meta-wayland-single-pixel-buffer.h
Normal file
41
src/wayland/meta-wayland-single-pixel-buffer.h
Normal file
@ -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 */
|
@ -780,8 +780,10 @@ meta_wayland_surface_apply_state (MetaWaylandSurface *surface,
|
|||||||
* it until is replaced by a subsequent wl_surface.commit or when the
|
* it until is replaced by a subsequent wl_surface.commit or when the
|
||||||
* wl_surface is destroyed.
|
* wl_surface is destroyed.
|
||||||
*/
|
*/
|
||||||
surface->buffer_held = (state->buffer &&
|
surface->buffer_held =
|
||||||
!wl_shm_buffer_get (state->buffer->resource));
|
(state->buffer &&
|
||||||
|
(state->buffer->type != META_WAYLAND_BUFFER_TYPE_SHM &&
|
||||||
|
state->buffer->type != META_WAYLAND_BUFFER_TYPE_SINGLE_PIXEL));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->scale > 0)
|
if (state->scale > 0)
|
||||||
|
@ -54,5 +54,6 @@
|
|||||||
#define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1
|
#define META_ZWP_PRIMARY_SELECTION_V1_VERSION 1
|
||||||
#define META_WP_PRESENTATION_VERSION 1
|
#define META_WP_PRESENTATION_VERSION 1
|
||||||
#define META_XDG_ACTIVATION_V1_VERSION 1
|
#define META_XDG_ACTIVATION_V1_VERSION 1
|
||||||
|
#define META_WP_SINGLE_PIXEL_BUFFER_V1_VERSION 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -627,6 +627,7 @@ meta_wayland_compositor_new (MetaContext *context)
|
|||||||
meta_wayland_pointer_constraints_init (compositor);
|
meta_wayland_pointer_constraints_init (compositor);
|
||||||
meta_wayland_xdg_foreign_init (compositor);
|
meta_wayland_xdg_foreign_init (compositor);
|
||||||
init_dma_buf_support (compositor);
|
init_dma_buf_support (compositor);
|
||||||
|
meta_wayland_init_single_pixel_buffer_manager (compositor);
|
||||||
meta_wayland_keyboard_shortcuts_inhibit_init (compositor);
|
meta_wayland_keyboard_shortcuts_inhibit_init (compositor);
|
||||||
meta_wayland_surface_inhibit_shortcuts_dialog_init ();
|
meta_wayland_surface_inhibit_shortcuts_dialog_init ();
|
||||||
meta_wayland_text_input_init (compositor);
|
meta_wayland_text_input_init (compositor);
|
||||||
|
Loading…
Reference in New Issue
Block a user