2013-10-13 11:47:53 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
|
|
|
|
|
/**
|
2023-03-28 14:35:11 +00:00
|
|
|
* MetaSurfaceActor:
|
2023-05-23 18:25:54 +00:00
|
|
|
*
|
2023-03-28 14:35:11 +00:00
|
|
|
* An actor representing a surface in the scene graph
|
2013-10-13 11:47:53 +00:00
|
|
|
*
|
2018-10-19 07:15:54 +00:00
|
|
|
* MetaSurfaceActor is an abstract class which represents a surface in the
|
|
|
|
* Clutter scene graph. A subclass can implement the specifics of a surface
|
|
|
|
* depending on the way it is handled by a display protocol.
|
|
|
|
*
|
|
|
|
* An important feature of #MetaSurfaceActor is that it allows you to set an
|
|
|
|
* "input region": all events that occur in the surface, but outside of the
|
|
|
|
* input region are to be explicitly ignored. By default, this region is to
|
|
|
|
* %NULL, which means events on the whole surface is allowed.
|
2013-10-13 11:47:53 +00:00
|
|
|
*/
|
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "config.h"
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/meta-surface-actor.h"
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "clutter/clutter.h"
|
2020-02-03 20:25:39 +00:00
|
|
|
#include "compositor/clutter-utils.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "compositor/meta-cullable.h"
|
|
|
|
#include "compositor/meta-shaped-texture-private.h"
|
2019-07-12 17:33:17 +00:00
|
|
|
#include "compositor/meta-window-actor-private.h"
|
2019-07-12 16:56:14 +00:00
|
|
|
#include "compositor/region-utils.h"
|
2018-07-10 08:36:24 +00:00
|
|
|
#include "meta/meta-shaped-texture.h"
|
2013-10-13 11:47:53 +00:00
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
|
|
|
|
PROP_IS_OBSCURED,
|
|
|
|
|
|
|
|
N_PROPS
|
|
|
|
};
|
|
|
|
|
|
|
|
static GParamSpec *obj_props[N_PROPS];
|
|
|
|
|
2018-10-31 10:47:17 +00:00
|
|
|
typedef struct _MetaSurfaceActorPrivate
|
2013-10-13 11:47:53 +00:00
|
|
|
{
|
2013-11-19 16:22:49 +00:00
|
|
|
MetaShapedTexture *texture;
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *input_region;
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2019-01-29 21:53:50 +00:00
|
|
|
/* MetaCullable regions, see that documentation for more details */
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *unobscured_region;
|
2023-05-24 12:37:18 +00:00
|
|
|
gboolean is_obscured;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
/* Freeze/thaw accounting */
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *pending_damage;
|
2014-02-24 21:00:12 +00:00
|
|
|
guint frozen : 1;
|
2018-10-31 10:47:17 +00:00
|
|
|
} MetaSurfaceActorPrivate;
|
2013-10-13 11:47:53 +00:00
|
|
|
|
2013-11-21 21:25:20 +00:00
|
|
|
static void cullable_iface_init (MetaCullableInterface *iface);
|
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_TYPE_ACTOR,
|
2018-07-19 11:40:39 +00:00
|
|
|
G_ADD_PRIVATE (MetaSurfaceActor)
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
|
|
|
|
2018-12-19 08:04:25 +00:00
|
|
|
enum
|
|
|
|
{
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
REPAINT_SCHEDULED,
|
2014-07-31 09:05:34 +00:00
|
|
|
SIZE_CHANGED,
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
|
|
|
LAST_SIGNAL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static guint signals[LAST_SIGNAL];
|
2013-12-06 16:57:40 +00:00
|
|
|
|
2020-06-28 21:56:21 +00:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
IN_STAGE_PERSPECTIVE,
|
|
|
|
IN_ACTOR_PERSPECTIVE
|
|
|
|
} ScalePerspectiveType;
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
static MtkRegion *
|
2019-01-29 21:53:50 +00:00
|
|
|
effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
2020-05-05 14:19:46 +00:00
|
|
|
ClutterActor *actor = CLUTTER_ACTOR (surface_actor);
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
/* Fail if we have any mapped clones. */
|
2020-05-05 14:19:46 +00:00
|
|
|
if (clutter_actor_has_mapped_clones (actor))
|
|
|
|
return NULL;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
return priv->unobscured_region;
|
|
|
|
}
|
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
static void
|
|
|
|
update_is_obscured (MetaSurfaceActor *surface_actor)
|
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *unobscured_region;
|
2023-05-24 12:37:18 +00:00
|
|
|
gboolean is_obscured;
|
|
|
|
|
|
|
|
unobscured_region = priv->unobscured_region;
|
|
|
|
|
|
|
|
if (unobscured_region)
|
2023-09-04 14:30:38 +00:00
|
|
|
is_obscured = mtk_region_is_empty (unobscured_region);
|
2023-05-24 12:37:18 +00:00
|
|
|
else
|
|
|
|
is_obscured = FALSE;
|
|
|
|
|
|
|
|
if (priv->is_obscured == is_obscured)
|
|
|
|
return;
|
|
|
|
|
|
|
|
priv->is_obscured = is_obscured;
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (surface_actor),
|
|
|
|
obj_props[PROP_IS_OBSCURED]);
|
|
|
|
}
|
|
|
|
|
2019-01-29 21:53:50 +00:00
|
|
|
static void
|
|
|
|
set_unobscured_region (MetaSurfaceActor *surface_actor,
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *unobscured_region)
|
2019-01-29 21:53:50 +00:00
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
g_clear_pointer (&priv->unobscured_region, mtk_region_unref);
|
2019-01-29 21:53:50 +00:00
|
|
|
if (unobscured_region)
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
if (mtk_region_is_empty (unobscured_region))
|
2020-02-25 18:59:22 +00:00
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
priv->unobscured_region = mtk_region_ref (unobscured_region);
|
2020-02-25 18:59:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle bounds = { 0, };
|
2020-02-25 18:59:22 +00:00
|
|
|
float width, height;
|
|
|
|
|
|
|
|
clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
|
|
|
|
&width,
|
|
|
|
&height);
|
2023-07-19 14:59:04 +00:00
|
|
|
bounds = (MtkRectangle) {
|
2020-02-25 18:59:22 +00:00
|
|
|
.width = width,
|
|
|
|
.height = height,
|
|
|
|
};
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
priv->unobscured_region = mtk_region_copy (unobscured_region);
|
2020-02-25 18:59:22 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
mtk_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
2020-02-25 18:59:22 +00:00
|
|
|
}
|
2019-01-29 21:53:50 +00:00
|
|
|
}
|
2023-05-24 12:37:18 +00:00
|
|
|
|
|
|
|
update_is_obscured (surface_actor);
|
2019-01-29 21:53:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_clip_region (MetaSurfaceActor *surface_actor,
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *clip_region)
|
2019-01-29 21:53:50 +00:00
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
2020-06-22 13:53:23 +00:00
|
|
|
MetaShapedTexture *stex = priv->texture;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
if (clip_region && !mtk_region_is_empty (clip_region))
|
2023-11-06 19:19:53 +00:00
|
|
|
{
|
|
|
|
g_autoptr (MtkRegion) clip_region_copy = NULL;
|
|
|
|
|
|
|
|
clip_region_copy = mtk_region_copy (clip_region);
|
|
|
|
meta_shaped_texture_set_clip_region (stex, clip_region_copy);
|
|
|
|
}
|
2020-06-22 13:53:23 +00:00
|
|
|
else
|
2023-11-06 19:19:53 +00:00
|
|
|
{
|
|
|
|
meta_shaped_texture_set_clip_region (stex, clip_region);
|
|
|
|
}
|
2019-01-29 21:53:50 +00:00
|
|
|
}
|
|
|
|
|
2014-02-19 02:27:20 +00:00
|
|
|
static void
|
2019-11-20 20:46:41 +00:00
|
|
|
meta_surface_actor_pick (ClutterActor *actor,
|
|
|
|
ClutterPickContext *pick_context)
|
2014-02-19 02:27:20 +00:00
|
|
|
{
|
|
|
|
MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2014-11-23 12:32:08 +00:00
|
|
|
ClutterActorIter iter;
|
|
|
|
ClutterActor *child;
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2020-10-16 13:06:39 +00:00
|
|
|
if (!clutter_actor_should_pick (actor, pick_context))
|
2014-02-19 02:27:20 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* If there is no region then use the regular pick */
|
|
|
|
if (priv->input_region == NULL)
|
2019-11-20 20:46:41 +00:00
|
|
|
{
|
|
|
|
ClutterActorClass *actor_class =
|
|
|
|
CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class);
|
|
|
|
|
|
|
|
actor_class->pick (actor, pick_context);
|
|
|
|
}
|
2014-02-19 02:27:20 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int n_rects;
|
|
|
|
int i;
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
n_rects = mtk_region_num_rectangles (priv->input_region);
|
2014-02-19 02:27:20 +00:00
|
|
|
|
|
|
|
for (i = 0; i < n_rects; i++)
|
|
|
|
{
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle rect;
|
clutter: Introduce geometric picking
Currently, Clutter does picking by drawing with Cogl and reading
the pixel that's beneath the given point. Since Cogl has a journal
that records drawing operations, and has optimizations to read a
single pixel from a list of rectangle, it would be expected that
we would hit this fast path and not flush the journal while picking.
However, that's not the case: dithering, clipping with scissors, etc,
can all flush the journal, issuing commands to the GPU and making
picking slow. On NVidia-based systems, this glReadPixels() call is
extremely costly.
Introduce geometric picking, and avoid using the Cogl journal entirely.
Do this by introducing a stack of actors in ClutterStage. This stack
is cached, but for now, don't use the cache as much as possible.
The picking routines are still tied to painting.
When projecting the actor vertexes, do it manually and take the modelview
matrix of the framebuffer into account as well.
CPU usage on an Intel i7-7700, tested with two different GPUs/drivers:
| | Intel | Nvidia |
| ------: | --------: | -----: |
| Moving the mouse: |
| Before | 10% | 10% |
| After | 6% | 6% |
| Moving a window: |
| Before | 23% | 81% |
| After | 19% | 40% |
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/154,
https://gitlab.gnome.org/GNOME/mutter/issues/691
Helps significantly with: https://gitlab.gnome.org/GNOME/mutter/issues/283,
https://gitlab.gnome.org/GNOME/mutter/issues/590,
https://gitlab.gnome.org/GNOME/mutter/issues/700
v2: Fix code style issues
Simplify quadrilateral checks
Remove the 0.5f hack
Differentiate axis-aligned rectangles
https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
2018-08-02 11:03:30 +00:00
|
|
|
ClutterActorBox box;
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
rect = mtk_region_get_rectangle (priv->input_region, i);
|
2014-02-19 02:27:20 +00:00
|
|
|
|
clutter: Introduce geometric picking
Currently, Clutter does picking by drawing with Cogl and reading
the pixel that's beneath the given point. Since Cogl has a journal
that records drawing operations, and has optimizations to read a
single pixel from a list of rectangle, it would be expected that
we would hit this fast path and not flush the journal while picking.
However, that's not the case: dithering, clipping with scissors, etc,
can all flush the journal, issuing commands to the GPU and making
picking slow. On NVidia-based systems, this glReadPixels() call is
extremely costly.
Introduce geometric picking, and avoid using the Cogl journal entirely.
Do this by introducing a stack of actors in ClutterStage. This stack
is cached, but for now, don't use the cache as much as possible.
The picking routines are still tied to painting.
When projecting the actor vertexes, do it manually and take the modelview
matrix of the framebuffer into account as well.
CPU usage on an Intel i7-7700, tested with two different GPUs/drivers:
| | Intel | Nvidia |
| ------: | --------: | -----: |
| Moving the mouse: |
| Before | 10% | 10% |
| After | 6% | 6% |
| Moving a window: |
| Before | 23% | 81% |
| After | 19% | 40% |
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/154,
https://gitlab.gnome.org/GNOME/mutter/issues/691
Helps significantly with: https://gitlab.gnome.org/GNOME/mutter/issues/283,
https://gitlab.gnome.org/GNOME/mutter/issues/590,
https://gitlab.gnome.org/GNOME/mutter/issues/700
v2: Fix code style issues
Simplify quadrilateral checks
Remove the 0.5f hack
Differentiate axis-aligned rectangles
https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
2018-08-02 11:03:30 +00:00
|
|
|
box.x1 = rect.x;
|
|
|
|
box.y1 = rect.y;
|
|
|
|
box.x2 = rect.x + rect.width;
|
|
|
|
box.y2 = rect.y + rect.height;
|
2019-11-20 20:46:41 +00:00
|
|
|
clutter_actor_pick_box (actor, pick_context, &box);
|
2014-02-19 02:27:20 +00:00
|
|
|
}
|
2014-11-23 12:32:08 +00:00
|
|
|
}
|
2014-10-20 16:44:55 +00:00
|
|
|
|
2014-11-23 12:32:08 +00:00
|
|
|
clutter_actor_iter_init (&iter, actor);
|
2014-10-20 16:44:55 +00:00
|
|
|
|
2014-11-23 12:32:08 +00:00
|
|
|
while (clutter_actor_iter_next (&iter, &child))
|
2019-11-20 20:46:41 +00:00
|
|
|
clutter_actor_pick (child, pick_context);
|
2014-02-19 02:27:20 +00:00
|
|
|
}
|
|
|
|
|
2018-04-28 16:14:34 +00:00
|
|
|
static gboolean
|
|
|
|
meta_surface_actor_get_paint_volume (ClutterActor *actor,
|
|
|
|
ClutterPaintVolume *volume)
|
|
|
|
{
|
|
|
|
return clutter_paint_volume_set_from_allocation (volume, actor);
|
|
|
|
}
|
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
static void
|
|
|
|
meta_surface_actor_get_property (GObject *object,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (object);
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
|
|
|
case PROP_IS_OBSCURED:
|
|
|
|
g_value_set_boolean (value, priv->is_obscured);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-19 02:27:20 +00:00
|
|
|
static void
|
|
|
|
meta_surface_actor_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
MetaSurfaceActor *self = META_SURFACE_ACTOR (object);
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
g_clear_pointer (&priv->input_region, mtk_region_unref);
|
2019-08-26 17:14:00 +00:00
|
|
|
g_clear_object (&priv->texture);
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2019-01-29 21:53:50 +00:00
|
|
|
set_unobscured_region (self, NULL);
|
|
|
|
|
2014-02-19 02:27:20 +00:00
|
|
|
G_OBJECT_CLASS (meta_surface_actor_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
2013-10-13 11:47:53 +00:00
|
|
|
static void
|
|
|
|
meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
|
|
|
{
|
2014-02-19 02:27:20 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->dispose = meta_surface_actor_dispose;
|
2023-05-24 12:37:18 +00:00
|
|
|
object_class->get_property = meta_surface_actor_get_property;
|
|
|
|
|
2014-02-19 02:27:20 +00:00
|
|
|
actor_class->pick = meta_surface_actor_pick;
|
2018-04-28 16:14:34 +00:00
|
|
|
actor_class->get_paint_volume = meta_surface_actor_get_paint_volume;
|
2014-02-19 02:27:20 +00:00
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
obj_props[PROP_IS_OBSCURED] =
|
|
|
|
g_param_spec_boolean ("is-obscured",
|
|
|
|
"is obscured",
|
|
|
|
"If the surface actor is fully obscured",
|
|
|
|
TRUE,
|
|
|
|
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
|
|
|
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
signals[REPAINT_SCHEDULED] = g_signal_new ("repaint-scheduled",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
|
2014-07-31 09:05:34 +00:00
|
|
|
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
|
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
0,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
G_TYPE_NONE, 0);
|
2013-10-13 11:47:53 +00:00
|
|
|
}
|
|
|
|
|
2019-08-17 08:00:46 +00:00
|
|
|
gboolean
|
|
|
|
meta_surface_actor_is_opaque (MetaSurfaceActor *self)
|
|
|
|
{
|
|
|
|
return META_SURFACE_ACTOR_GET_CLASS (self)->is_opaque (self);
|
|
|
|
}
|
|
|
|
|
2013-11-21 21:25:20 +00:00
|
|
|
static void
|
2023-06-11 06:18:29 +00:00
|
|
|
subtract_opaque_region (MetaSurfaceActor *surface_actor,
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *region)
|
2013-11-21 21:25:20 +00:00
|
|
|
{
|
2018-12-26 15:41:26 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
2023-06-11 06:18:29 +00:00
|
|
|
uint8_t opacity = clutter_actor_get_paint_opacity (CLUTTER_ACTOR (surface_actor));
|
2018-12-26 15:41:26 +00:00
|
|
|
|
2023-06-11 06:18:29 +00:00
|
|
|
if (!region)
|
|
|
|
return;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
if (opacity == 0xff)
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *opaque_region;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
|
2020-02-23 15:37:50 +00:00
|
|
|
|
2020-09-30 23:38:16 +00:00
|
|
|
if (!opaque_region)
|
|
|
|
return;
|
2019-07-12 16:56:14 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
mtk_region_subtract (region, opaque_region);
|
2019-01-29 21:53:50 +00:00
|
|
|
}
|
2013-11-21 21:25:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-09-04 14:30:38 +00:00
|
|
|
meta_surface_actor_cull_redraw_clip (MetaCullable *cullable,
|
|
|
|
MtkRegion *clip_region)
|
2023-06-11 06:18:29 +00:00
|
|
|
{
|
|
|
|
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
|
|
|
|
|
|
|
|
set_clip_region (surface_actor, clip_region);
|
|
|
|
|
|
|
|
subtract_opaque_region (surface_actor, clip_region);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2023-09-04 14:30:38 +00:00
|
|
|
meta_surface_actor_cull_unobscured (MetaCullable *cullable,
|
|
|
|
MtkRegion *unobscured_region)
|
2013-11-21 21:25:20 +00:00
|
|
|
{
|
2018-12-26 15:41:26 +00:00
|
|
|
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
|
|
|
|
|
2023-06-11 06:18:29 +00:00
|
|
|
set_unobscured_region (surface_actor, unobscured_region);
|
|
|
|
|
|
|
|
subtract_opaque_region (surface_actor, unobscured_region);
|
2013-11-21 21:25:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cullable_iface_init (MetaCullableInterface *iface)
|
|
|
|
{
|
2023-06-11 06:18:29 +00:00
|
|
|
iface->cull_redraw_clip = meta_surface_actor_cull_redraw_clip;
|
|
|
|
iface->cull_unobscured = meta_surface_actor_cull_unobscured;
|
2013-11-21 21:25:20 +00:00
|
|
|
}
|
|
|
|
|
2014-07-31 09:05:34 +00:00
|
|
|
static void
|
|
|
|
texture_size_changed (MetaShapedTexture *texture,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
|
|
|
|
g_signal_emit (actor, signals[SIZE_CHANGED], 0);
|
|
|
|
}
|
|
|
|
|
2013-10-13 11:47:53 +00:00
|
|
|
static void
|
|
|
|
meta_surface_actor_init (MetaSurfaceActor *self)
|
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2013-10-13 11:47:53 +00:00
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
priv->is_obscured = TRUE;
|
2018-12-26 15:41:26 +00:00
|
|
|
priv->texture = meta_shaped_texture_new ();
|
2014-07-31 09:05:34 +00:00
|
|
|
g_signal_connect_object (priv->texture, "size-changed",
|
|
|
|
G_CALLBACK (texture_size_changed), self, 0);
|
2018-12-26 15:41:26 +00:00
|
|
|
clutter_actor_set_content (CLUTTER_ACTOR (self),
|
|
|
|
CLUTTER_CONTENT (priv->texture));
|
|
|
|
clutter_actor_set_request_mode (CLUTTER_ACTOR (self),
|
|
|
|
CLUTTER_REQUEST_CONTENT_SIZE);
|
2013-10-13 11:47:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MetaShapedTexture *
|
|
|
|
meta_surface_actor_get_texture (MetaSurfaceActor *self)
|
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->texture;
|
2013-10-13 11:47:53 +00:00
|
|
|
}
|
|
|
|
|
2020-04-24 21:21:26 +00:00
|
|
|
void
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
meta_surface_actor_update_area (MetaSurfaceActor *self,
|
2020-04-24 21:21:26 +00:00
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int width,
|
|
|
|
int height)
|
2013-12-06 16:57:40 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2019-01-29 21:53:50 +00:00
|
|
|
gboolean repaint_scheduled = FALSE;
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle clip;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
if (meta_shaped_texture_update_area (priv->texture, x, y, width, height, &clip))
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *unobscured_region;
|
2013-12-06 16:57:40 +00:00
|
|
|
|
2019-01-29 21:53:50 +00:00
|
|
|
unobscured_region = effective_unobscured_region (self);
|
|
|
|
|
|
|
|
if (unobscured_region)
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
g_autoptr (MtkRegion) intersection = NULL;
|
2019-01-29 21:53:50 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
if (mtk_region_is_empty (unobscured_region))
|
2019-01-29 21:53:50 +00:00
|
|
|
return;
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
intersection = mtk_region_copy (unobscured_region);
|
|
|
|
mtk_region_intersect_rectangle (intersection, &clip);
|
2019-01-29 21:53:50 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
if (!mtk_region_is_empty (intersection))
|
2019-01-29 21:53:50 +00:00
|
|
|
{
|
2023-04-17 11:27:18 +00:00
|
|
|
int i, n_rectangles;
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
n_rectangles = mtk_region_num_rectangles (intersection);
|
2023-04-17 11:27:18 +00:00
|
|
|
for (i = 0; i < n_rectangles; i++)
|
|
|
|
{
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle rect;
|
2023-04-17 11:27:18 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
rect = mtk_region_get_rectangle (intersection, i);
|
2023-04-17 11:27:18 +00:00
|
|
|
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &rect);
|
|
|
|
}
|
2019-01-29 21:53:50 +00:00
|
|
|
|
|
|
|
repaint_scheduled = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (self), &clip);
|
|
|
|
repaint_scheduled = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (repaint_scheduled)
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
g_signal_emit (self, signals[REPAINT_SCHEDULED], 0);
|
2013-12-06 16:57:40 +00:00
|
|
|
}
|
|
|
|
|
2013-10-13 11:47:53 +00:00
|
|
|
gboolean
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
meta_surface_actor_is_obscured (MetaSurfaceActor *self)
|
2013-10-13 11:47:53 +00:00
|
|
|
{
|
2023-05-24 12:37:18 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2018-10-31 10:47:17 +00:00
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
return priv->is_obscured;
|
|
|
|
}
|
2019-01-29 21:53:50 +00:00
|
|
|
|
2023-05-24 12:37:18 +00:00
|
|
|
gboolean
|
|
|
|
meta_surface_actor_is_effectively_obscured (MetaSurfaceActor *surface_actor)
|
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (surface_actor);
|
|
|
|
|
|
|
|
if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (surface_actor)))
|
2019-01-29 21:53:50 +00:00
|
|
|
return FALSE;
|
2023-05-24 12:37:18 +00:00
|
|
|
else
|
|
|
|
return priv->is_obscured;
|
2013-12-06 16:57:40 +00:00
|
|
|
}
|
|
|
|
|
2020-10-05 11:18:15 +00:00
|
|
|
gboolean
|
|
|
|
meta_surface_actor_is_obscured_on_stage_view (MetaSurfaceActor *self,
|
|
|
|
ClutterStageView *stage_view,
|
|
|
|
float *unobscurred_fraction)
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *unobscured_region;
|
2020-10-05 11:18:15 +00:00
|
|
|
|
|
|
|
unobscured_region = effective_unobscured_region (self);
|
|
|
|
|
|
|
|
if (unobscured_region)
|
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2023-04-19 11:43:50 +00:00
|
|
|
ClutterActor *stage = clutter_actor_get_stage (CLUTTER_ACTOR (self));
|
2023-09-04 14:30:38 +00:00
|
|
|
g_autoptr (MtkRegion) intersection_region = NULL;
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle stage_rect;
|
2023-04-19 11:43:50 +00:00
|
|
|
graphene_matrix_t transform;
|
|
|
|
graphene_rect_t actor_bounds;
|
2020-10-05 11:18:15 +00:00
|
|
|
float bounds_width, bounds_height;
|
|
|
|
float bounds_size;
|
|
|
|
int intersection_size = 0;
|
|
|
|
int n_rects, i;
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
if (mtk_region_is_empty (unobscured_region))
|
2020-10-05 11:18:15 +00:00
|
|
|
return TRUE;
|
|
|
|
|
2023-04-19 11:43:50 +00:00
|
|
|
clutter_actor_get_relative_transformation_matrix (CLUTTER_ACTOR (self),
|
|
|
|
stage,
|
|
|
|
&transform);
|
|
|
|
|
|
|
|
intersection_region = meta_region_apply_matrix_transform_expand (unobscured_region, &transform);
|
2020-10-05 11:18:15 +00:00
|
|
|
|
|
|
|
clutter_stage_view_get_layout (stage_view, &stage_rect);
|
2023-09-04 14:30:38 +00:00
|
|
|
mtk_region_intersect_rectangle (intersection_region,
|
|
|
|
&stage_rect);
|
2020-10-05 11:18:15 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
if (mtk_region_is_empty (intersection_region))
|
|
|
|
return TRUE;
|
2020-10-05 11:18:15 +00:00
|
|
|
else if (!unobscurred_fraction)
|
2023-09-04 14:30:38 +00:00
|
|
|
return FALSE;
|
2020-10-05 11:18:15 +00:00
|
|
|
|
|
|
|
clutter_content_get_preferred_size (CLUTTER_CONTENT (priv->texture),
|
|
|
|
&bounds_width,
|
|
|
|
&bounds_height);
|
2023-04-19 11:43:50 +00:00
|
|
|
graphene_rect_init (&actor_bounds, 0, 0, bounds_width, bounds_height);
|
|
|
|
graphene_matrix_transform_bounds (&transform, &actor_bounds, &actor_bounds);
|
|
|
|
graphene_rect_round_extents (&actor_bounds, &actor_bounds);
|
|
|
|
bounds_size = graphene_rect_get_area (&actor_bounds);
|
2020-10-05 11:18:15 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
n_rects = mtk_region_num_rectangles (intersection_region);
|
2020-10-05 11:18:15 +00:00
|
|
|
for (i = 0; i < n_rects; i++)
|
|
|
|
{
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle rect;
|
2020-10-05 11:18:15 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
rect = mtk_region_get_rectangle (intersection_region, i);
|
2021-12-19 22:42:57 +00:00
|
|
|
intersection_size += rect.width * rect.height;
|
2020-10-05 11:18:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_return_val_if_fail (bounds_size > 0, FALSE);
|
|
|
|
|
|
|
|
*unobscurred_fraction = CLAMP (intersection_size / bounds_size, 0, 1);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !clutter_actor_is_effectively_on_stage_view (CLUTTER_ACTOR (self),
|
|
|
|
stage_view);
|
|
|
|
}
|
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
void
|
|
|
|
meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *region)
|
2013-12-06 16:57:40 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
2013-12-06 16:57:40 +00:00
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
g_clear_pointer (&priv->input_region, mtk_region_unref);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
|
|
|
if (region)
|
2023-09-04 14:30:38 +00:00
|
|
|
priv->input_region = mtk_region_ref (region);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
else
|
|
|
|
priv->input_region = NULL;
|
2014-02-05 19:06:32 +00:00
|
|
|
}
|
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
void
|
|
|
|
meta_surface_actor_set_opaque_region (MetaSurfaceActor *self,
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *region)
|
2014-02-05 19:06:32 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
|
|
|
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
meta_shaped_texture_set_opaque_region (priv->texture, region);
|
2013-10-13 11:47:53 +00:00
|
|
|
}
|
|
|
|
|
2023-09-04 14:30:38 +00:00
|
|
|
MtkRegion *
|
2018-10-31 10:47:17 +00:00
|
|
|
meta_surface_actor_get_opaque_region (MetaSurfaceActor *self)
|
2016-03-21 20:43:50 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
|
|
|
|
2016-03-21 20:43:50 +00:00
|
|
|
return meta_shaped_texture_get_opaque_region (priv->texture);
|
|
|
|
}
|
|
|
|
|
2013-11-21 22:45:05 +00:00
|
|
|
void
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
meta_surface_actor_process_damage (MetaSurfaceActor *self,
|
2023-09-04 14:30:38 +00:00
|
|
|
int x,
|
|
|
|
int y,
|
|
|
|
int width,
|
|
|
|
int height)
|
2013-12-09 21:01:07 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2019-12-06 15:35:37 +00:00
|
|
|
if (meta_surface_actor_is_frozen (self))
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
{
|
|
|
|
/* The window is frozen due to an effect in progress: we ignore damage
|
|
|
|
* here on the off chance that this will stop the corresponding
|
|
|
|
* texture_from_pixmap from being update.
|
|
|
|
*
|
2016-06-17 15:45:20 +00:00
|
|
|
* pending_damage tracks any damage that happened while the window was
|
|
|
|
* frozen so that when can apply it when the window becomes unfrozen.
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
*
|
|
|
|
* It should be noted that this is an unreliable mechanism since it's
|
|
|
|
* quite likely that drivers will aim to provide a zero-copy
|
|
|
|
* implementation of the texture_from_pixmap extension and in those cases
|
|
|
|
* any drawing done to the window is always immediately reflected in the
|
|
|
|
* texture regardless of damage event handling.
|
|
|
|
*/
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle rect = { .x = x, .y = y, .width = width, .height = height };
|
2016-06-17 15:45:20 +00:00
|
|
|
|
|
|
|
if (!priv->pending_damage)
|
2023-09-04 14:30:38 +00:00
|
|
|
priv->pending_damage = mtk_region_create_rectangle (&rect);
|
2016-06-17 15:45:20 +00:00
|
|
|
else
|
2023-09-04 14:30:38 +00:00
|
|
|
mtk_region_union_rectangle (priv->pending_damage, &rect);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
META_SURFACE_ACTOR_GET_CLASS (self)->process_damage (self, x, y, width, height);
|
2013-12-09 21:01:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-02-24 21:00:12 +00:00
|
|
|
meta_surface_actor_set_frozen (MetaSurfaceActor *self,
|
|
|
|
gboolean frozen)
|
2013-12-09 21:01:07 +00:00
|
|
|
{
|
2018-10-31 10:47:17 +00:00
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2020-06-29 13:15:46 +00:00
|
|
|
if (priv->frozen == frozen)
|
|
|
|
return;
|
|
|
|
|
2014-02-24 21:00:12 +00:00
|
|
|
priv->frozen = frozen;
|
2013-12-06 19:19:32 +00:00
|
|
|
|
2016-06-17 15:45:20 +00:00
|
|
|
if (!frozen && priv->pending_damage)
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
int i, n_rects = mtk_region_num_rectangles (priv->pending_damage);
|
2023-07-19 14:59:04 +00:00
|
|
|
MtkRectangle rect;
|
2016-06-17 15:45:20 +00:00
|
|
|
|
2014-02-24 21:00:12 +00:00
|
|
|
/* Since we ignore damage events while a window is frozen for certain effects
|
2016-06-17 15:45:20 +00:00
|
|
|
* we need to apply the tracked damage now. */
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
|
2016-06-17 15:45:20 +00:00
|
|
|
for (i = 0; i < n_rects; i++)
|
|
|
|
{
|
2023-09-04 14:30:38 +00:00
|
|
|
rect = mtk_region_get_rectangle (priv->pending_damage, i);
|
2016-06-17 15:45:20 +00:00
|
|
|
meta_surface_actor_process_damage (self, rect.x, rect.y,
|
|
|
|
rect.width, rect.height);
|
|
|
|
}
|
2023-09-04 14:30:38 +00:00
|
|
|
g_clear_pointer (&priv->pending_damage, mtk_region_unref);
|
window-actor: Split into two subclasses of MetaSurfaceActor
The rendering logic before was somewhat complex. We had three independent
cases to take into account when doing rendering:
* X11 compositor. In this case, we're a traditional X11 compositor,
not a Wayland compositor. We use XCompositeNameWindowPixmap to get
the backing pixmap for the window, and deal with the COMPOSITE
extension messiness.
In this case, meta_is_wayland_compositor() is FALSE.
* Wayland clients. In this case, we're a Wayland compositor managing
Wayland surfaces. The rendering for this is fairly straightforward,
as Cogl handles most of the complexity with EGL and SHM buffers...
Wayland clients give us the input and opaque regions through
wl_surface.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND.
* XWayland clients. In this case, we're a Wayland compositor, like
above, and XWayland hands us Wayland surfaces. XWayland handles
the COMPOSITE extension messiness for us, and hands us a buffer
like any other Wayland client. We have to fetch the input and
opaque regions from the X11 window ourselves.
In this case, meta_is_wayland_compositor() is TRUE and
priv->window->client_type == META_WINDOW_CLIENT_TYPE_X11.
We now split the rendering logic into two subclasses, which are:
* MetaSurfaceActorX11, which handles the X11 compositor case, in that
it uses XCompositeNameWindowPixmap to get the backing pixmap, and
deal with all the COMPOSITE extension messiness.
* MetaSurfaceActorWayland, which handles the Wayland compositor case
for both native Wayland clients and XWayland clients. XWayland handles
COMPOSITE for us, and handles pushing a surface over through the
xf86-video-wayland DDX.
Frame sync is still in MetaWindowActor, as it needs to work for both the
X11 compositor and XWayland client cases. When Wayland's video display
protocol lands, this will need to be significantly overhauled, as it would
have to work for any wl_surface, including subsurfaces, so we would need
surface-level discretion.
https://bugzilla.gnome.org/show_bug.cgi?id=720631
2014-02-01 22:21:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-06 15:35:37 +00:00
|
|
|
gboolean
|
|
|
|
meta_surface_actor_is_frozen (MetaSurfaceActor *self)
|
|
|
|
{
|
|
|
|
MetaSurfaceActorPrivate *priv =
|
|
|
|
meta_surface_actor_get_instance_private (self);
|
|
|
|
|
|
|
|
return priv->frozen;
|
|
|
|
}
|