Compare commits

...

15 Commits

Author SHA1 Message Date
Georges Basile Stavracas Neto
4a69e70000 Introduce ClutterBlitNode
It is not possible to express a blit operation using paint
nodes as of now. This is a requirement for GNOME Shell, e.g.,
to implement its blur effect.

Add a new ClutterBlitNode node that takes two framebuffers as
input, and blits source into dest according to added rectangles.

Because this paint node uses the rectangles in a different way
compared to all the other nodes, add an auxiliary method to
ensure all blit operations are valid.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
bc81f17d5f clutter/paint-nodes: Add serialization to layer node
It's useful to know which framebuffer the layer node is holding,
so serialize that too.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
3b64f56c5f clutter/paint-nodes: Push and pop framebuffer even without ops
ClutterLayerNode currently skips pushing and popping its framebuffer
to the paint context when no rectangles are added to it. However,
it's still useful to do that, since we might want to render child
nodes to the offscreen and reuse the pipeline in a later node.

Make ClutterLayerNode push and pop its framebuffer even without
rectangles.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
31dc74dfd3 clutter/paint-nodes: Add new ClutterLayerNode API
ClutterLayerNode is the "offscreen framebuffer" node, that paints
it's child nodes in a separate framebuffer, and then copies that
framebuffer to the parent one.

It'll be useful to hand ClutterLayerNode which framebuffer to use,
as this is a requirement for porting e.g. ClutterOffscreenEffect
and subclasses.

Add a new clutter_layer_node_new_with_framebuffer() API.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
26a225f675 clutter/paint-nodes: Don't skip pipeline node constructor
ClutterPipelineNode will be used by GNOME Shell in the future.
Fortunately for us, CoglPipeline is already usable from GJS,
so we don't need to skip the constructor for the pipeline node.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
0caca4fc49 clutter/paint-nodes: Add opacity overriding to ClutterActorNode
Some effects, such as ShellBlurEffect and ClutterOffscreenEffect, need
to make sure the actor is painted fully opaque. With ClutterActorNode,
however, that is currently not possible.

Add a new 'opacity' parameter to clutter_actor_node_new(). It follows
the opacity override heuristic, where -1 means disable, and anything
else is clamped to [0, 255].

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
5d11104a0a clutter/offscreen-effect: Simplify paint
Simply chain up to get the pre and post paint methods,
instead of reimplementing ClutterEffect.paint()

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
5186f0e3ef clutter/offscreen-effect: Clear framebuffer on pre_paint
Move the framebuffer cleanup to ClutterOffscreenEffect.pre_paint().
This will allow us to properly chain up ClutterOffscreenEffect.paint()
and not reimplement exactly what ClutterEffect does by default.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
61d247f399 clutter/effect: Add paint_node vfunc
Introduce a new paint_node vfunc that, if implemented, allows
the effect to add nodes to a transient paint node that is
immediately painted. This is a transitional step until we
have fully delegated paint node rendering.

The most basic implementation of a ClutterEffect.paint_node
vfunc, and also the default implementation, is with an actor
node, as follows:

```
static void
foo_bar_paint_node (ClutterEffect           *effect,
                    ClutterPaintNode        *node,
                    ClutterPaintContext     *paint_context,
                    ClutterEffectPaintFlags  flags)
{
  g_autoptr (ClutterPaintNode) actor_node = NULL;

  actor_node = clutter_actor_node_new (effect->actor);
  clutter_paint_node_add_child (node, actor_node);
}
```

This example gives the exact same behavior of simply calling
clutter_actor_continue_paint(). In the future, the paint node
itself will be a parameter of clutter_actor_continue_paint()
and we'll be able to simplify it event more.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
19bf3751eb Introduce ClutterEffectNode
ClutterEffectNode is a private ClutterPaintNode implementation
that does effectively nothing, but helps organizing the paint
node tree. It also helps debugging, since it can output the
effect class and name to the JSON debugging routines.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
963df6f61c clutter/effect: Don't expose pre and post paint helpers
They're not used outside ClutterEffect.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:17 +00:00
Georges Basile Stavracas Neto
a510339970 clutter/paint-node: Walk up paint node tree to find framebuffer
The idea of having a paint node tree is that we don't really need
to retrieve the framebuffer from ClutterPaintContext. For example,
ClutterLayerNode draws into an offscreen framebuffer; if any child
of a layer node needs to retrieve a framebuffer to draw, the layer
node's offscreen framebuffer should be used.

However, clutter_paint_node_get_framebuffer() goes straight to the
root node of the tree, skipping any potential paint nodes with a
custom framebuffer.

Modify clutter_paint_node_get_framebuffer() to walk up the paint
node tree until a node with a custom framebuffer appears. In many
cases, this will end up either in dummy or layer node's custom
framebuffer implementations.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1340
2020-08-14 16:04:16 +00:00
Florentina Mușat
11ca27c6ff Update Romanian translation 2020-08-14 12:48:16 +00:00
Jian-Hong Pan
bd6bab113b monitor-manager: Set switch config when create monitors config
It is linear config manager created when ensuring configuration.
However, the switch config is not set as LINEAR, but left as UNKNOWN.
This leads switch mode OSD always shows "Join Displays" icon, rather
than the next icon which is "External Only" after connect an external
display and press Super+P once at first time since mutter starts.

This patch moves switch config setting into
meta_monitor_config_manager_create_linear() (and the sibling functions)
to well prepare the monitors config and avoid missing settings.

This is a regression introduced by 149e4d6934.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1362
2020-08-13 20:11:15 +00:00
Christian Rauch
125f0b0351 wayland: prevent resizing of fixed-size window
Clients can set minimum and maximum to identical values to indicate a
fixed-size window. A compositor can ignore these requests and thus a client
has to ensure these limits.
To support clients that do not ensure these size limits by themselves and
to skip unnecessary function calls, we will prevent resizing requests by
the client if a fixed-size has been requested.

https://gitlab.gnome.org/GNOME/mutter/-/issues/1331
2020-08-13 19:54:32 +01:00
12 changed files with 566 additions and 130 deletions

View File

@@ -3746,7 +3746,7 @@ clutter_actor_paint (ClutterActor *self,
if (!CLUTTER_ACTOR_IS_MAPPED (self))
return;
actor_node = clutter_actor_node_new (self);
actor_node = clutter_actor_node_new (self, -1);
root_node = clutter_paint_node_ref (actor_node);
if (priv->has_clip)

View File

@@ -5,10 +5,6 @@
G_BEGIN_DECLS
gboolean _clutter_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context);
void _clutter_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context);
gboolean _clutter_effect_modify_paint_volume (ClutterEffect *effect,
ClutterPaintVolume *volume);
gboolean _clutter_effect_has_custom_paint_volume (ClutterEffect *effect);

View File

@@ -169,6 +169,8 @@
#include "clutter-effect-private.h"
#include "clutter-enum-types.h"
#include "clutter-marshal.h"
#include "clutter-paint-node-private.h"
#include "clutter-paint-nodes.h"
#include "clutter-private.h"
#include "clutter-actor-private.h"
@@ -196,26 +198,46 @@ clutter_effect_real_modify_paint_volume (ClutterEffect *effect,
return TRUE;
}
static void
clutter_effect_real_paint_node (ClutterEffect *effect,
ClutterPaintNode *node,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags)
{
ClutterPaintNode *actor_node;
ClutterActor *actor;
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
actor_node = clutter_actor_node_new (actor, -1);
clutter_paint_node_add_child (node, actor_node);
clutter_paint_node_unref (actor_node);
}
static void
clutter_effect_real_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags)
{
ClutterActorMeta *actor_meta = CLUTTER_ACTOR_META (effect);
ClutterActor *actor;
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
ClutterPaintNode *node;
gboolean pre_paint_succeeded;
/* The default implementation provides a compatibility wrapper for
effects that haven't migrated to use the 'paint' virtual yet. This
just calls the old pre and post virtuals before chaining on */
pre_paint_succeeded = _clutter_effect_pre_paint (effect, paint_context);
pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
actor = clutter_actor_meta_get_actor (actor_meta);
clutter_actor_continue_paint (actor, paint_context);
node = clutter_effect_node_new (effect);
effect_class->paint_node (effect, node, paint_context, flags);
clutter_paint_node_paint (node, paint_context);
if (pre_paint_succeeded)
_clutter_effect_post_paint (effect, paint_context);
effect_class->post_paint (effect, paint_context);
clutter_paint_node_unref (node);
}
static void
@@ -255,6 +277,7 @@ clutter_effect_class_init (ClutterEffectClass *klass)
klass->post_paint = clutter_effect_real_post_paint;
klass->modify_paint_volume = clutter_effect_real_modify_paint_volume;
klass->paint = clutter_effect_real_paint;
klass->paint_node = clutter_effect_real_paint_node;
klass->pick = clutter_effect_real_pick;
}
@@ -263,24 +286,6 @@ clutter_effect_init (ClutterEffect *self)
{
}
gboolean
_clutter_effect_pre_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{
g_return_val_if_fail (CLUTTER_IS_EFFECT (effect), FALSE);
return CLUTTER_EFFECT_GET_CLASS (effect)->pre_paint (effect, paint_context);
}
void
_clutter_effect_post_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context)
{
g_return_if_fail (CLUTTER_IS_EFFECT (effect));
CLUTTER_EFFECT_GET_CLASS (effect)->post_paint (effect, paint_context);
}
void
_clutter_effect_paint (ClutterEffect *effect,
ClutterPaintContext *paint_context,

View File

@@ -87,6 +87,10 @@ struct _ClutterEffectClass
void (* paint) (ClutterEffect *effect,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags);
void (* paint_node) (ClutterEffect *effect,
ClutterPaintNode *node,
ClutterPaintContext *paint_context,
ClutterEffectPaintFlags flags);
void (* pick) (ClutterEffect *effect,
ClutterPickContext *pick_context);

View File

@@ -272,10 +272,10 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
local_offset = GRAPHENE_POINT3D_INIT (0.0f, 0.0f, 0.0f);
if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
return FALSE;
goto disable_effect;
if (priv->actor == NULL)
return FALSE;
goto disable_effect;
stage = _clutter_actor_get_stage_internal (priv->actor);
clutter_actor_get_size (stage, &stage_width, &stage_height);
@@ -320,7 +320,7 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
/* First assert that the framebuffer is the right size... */
if (!update_fbo (effect, target_width, target_height, resource_scale))
return FALSE;
goto disable_effect;
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_get_modelview_matrix (framebuffer, &old_modelview);
@@ -387,6 +387,10 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
clutter_actor_set_opacity_override (priv->actor, 0xff);
return TRUE;
disable_effect:
cogl_clear_object (&priv->offscreen);
return FALSE;
}
static void
@@ -505,17 +509,10 @@ clutter_offscreen_effect_paint (ClutterEffect *effect,
*/
if (priv->offscreen == NULL || (flags & CLUTTER_EFFECT_PAINT_ACTOR_DIRTY))
{
ClutterEffectClass *effect_class = CLUTTER_EFFECT_GET_CLASS (effect);
gboolean pre_paint_succeeded;
ClutterEffectClass *parent_class =
CLUTTER_EFFECT_CLASS (clutter_offscreen_effect_parent_class);
pre_paint_succeeded = effect_class->pre_paint (effect, paint_context);
clutter_actor_continue_paint (priv->actor, paint_context);
if (pre_paint_succeeded)
effect_class->post_paint (effect, paint_context);
else
g_clear_pointer (&priv->offscreen, cogl_object_unref);
parent_class->paint (effect, paint_context, flags);
}
else
clutter_offscreen_effect_paint_texture (self, paint_context);

View File

@@ -141,6 +141,26 @@ ClutterPaintNode * clutter_paint_node_get_last_child (Clutter
G_GNUC_INTERNAL
ClutterPaintNode * clutter_paint_node_get_parent (ClutterPaintNode *node);
#define CLUTTER_TYPE_EFFECT_NODE (clutter_effect_node_get_type ())
#define CLUTTER_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_EFFECT_NODE, ClutterEffectNode))
#define CLUTTER_IS_EFFECT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_EFFECT_NODE))
/**
* ClutterEffectNode:
*
* The #ClutterEffectNode structure is an opaque
* type whose members cannot be directly accessed.
*/
typedef struct _ClutterEffectNode ClutterEffectNode;
typedef struct _ClutterEffectNode ClutterEffectNodeClass;
CLUTTER_EXPORT
GType clutter_effect_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_effect_node_new (ClutterEffect *actor);
G_END_DECLS
#endif /* __CLUTTER_PAINT_NODE_PRIVATE_H__ */

View File

@@ -1149,24 +1149,14 @@ _clutter_paint_node_create (GType gtype)
return (gpointer) g_type_create_instance (gtype);
}
static ClutterPaintNode *
clutter_paint_node_get_root (ClutterPaintNode *node)
{
ClutterPaintNode *iter;
iter = node;
while (iter != NULL && iter->parent != NULL)
iter = iter->parent;
return iter;
}
/**
* clutter_paint_node_get_framebuffer:
* @node: a #ClutterPaintNode
*
* Retrieves the #CoglFramebuffer that @node will draw
* into, if it the root node has a custom framebuffer set.
* into. If @node doesn't specify a custom framebuffer,
* the first parent node with a custom framebuffer will
* be used.
*
* Returns: (transfer none): a #CoglFramebuffer or %NULL if no custom one is
* set.
@@ -1174,12 +1164,19 @@ clutter_paint_node_get_root (ClutterPaintNode *node)
CoglFramebuffer *
clutter_paint_node_get_framebuffer (ClutterPaintNode *node)
{
ClutterPaintNode *root = clutter_paint_node_get_root (node);
ClutterPaintNodeClass *klass;
ClutterPaintNode *iter;
klass = CLUTTER_PAINT_NODE_GET_CLASS (root);
if (klass->get_framebuffer != NULL)
return klass->get_framebuffer (root);
else
return NULL;
iter = node;
while (iter != NULL && iter->parent != NULL)
{
klass = CLUTTER_PAINT_NODE_GET_CLASS (iter);
if (klass->get_framebuffer != NULL)
return klass->get_framebuffer (iter);
iter = iter->parent;
}
return NULL;
}

View File

@@ -551,7 +551,7 @@ clutter_pipeline_node_init (ClutterPipelineNode *self)
}
/**
* clutter_pipeline_node_new: (skip)
* clutter_pipeline_node_new:
* @pipeline: (allow-none): a Cogl pipeline state object, or %NULL
*
* Creates a new #ClutterPaintNode that will use the @pipeline to
@@ -1115,6 +1115,8 @@ struct _ClutterActorNode
ClutterPaintNode parent_instance;
ClutterActor *actor;
int opacity_override;
int saved_opacity_override;
};
struct _ClutterActorNodeClass
@@ -1130,6 +1132,14 @@ clutter_actor_node_pre_draw (ClutterPaintNode *node,
{
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
if (actor_node->opacity_override != -1)
{
actor_node->saved_opacity_override =
clutter_actor_get_opacity_override (actor_node->actor);
clutter_actor_set_opacity_override (actor_node->actor,
actor_node->opacity_override);
}
CLUTTER_SET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT);
return TRUE;
@@ -1151,6 +1161,12 @@ clutter_actor_node_post_draw (ClutterPaintNode *node,
ClutterActorNode *actor_node = CLUTTER_ACTOR_NODE (node);
CLUTTER_UNSET_PRIVATE_FLAGS (actor_node->actor, CLUTTER_IN_PAINT);
if (actor_node->opacity_override != -1)
{
clutter_actor_set_opacity_override (actor_node->actor,
actor_node->saved_opacity_override);
}
}
static JsonNode *
@@ -1192,6 +1208,7 @@ clutter_actor_node_init (ClutterActorNode *self)
/*
* clutter_actor_node_new:
* @actor: the actor to paint
* @opacity: opacity to draw the actor with, or -1 to use the actor's opacity
*
* Creates a new #ClutterActorNode.
*
@@ -1203,7 +1220,8 @@ clutter_actor_node_init (ClutterActorNode *self)
* Use clutter_paint_node_unref() when done.
*/
ClutterPaintNode *
clutter_actor_node_new (ClutterActor *actor)
clutter_actor_node_new (ClutterActor *actor,
int opacity)
{
ClutterActorNode *res;
@@ -1211,11 +1229,96 @@ clutter_actor_node_new (ClutterActor *actor)
res = _clutter_paint_node_create (CLUTTER_TYPE_ACTOR_NODE);
res->actor = actor;
res->opacity_override = CLAMP (opacity, -1, 255);
return (ClutterPaintNode *) res;
}
/*
* ClutterEffectNode
*/
struct _ClutterEffectNode
{
ClutterPaintNode parent_instance;
ClutterEffect *effect;
};
struct _ClutterEffectNodeClass
{
ClutterPaintNodeClass parent_class;
};
G_DEFINE_TYPE (ClutterEffectNode, clutter_effect_node, CLUTTER_TYPE_PAINT_NODE)
static JsonNode *
clutter_effect_node_serialize (ClutterPaintNode *node)
{
ClutterEffectNode *effect_node = CLUTTER_EFFECT_NODE (node);
ClutterActorMeta *effect_meta = CLUTTER_ACTOR_META (effect_node->effect);
g_autoptr (JsonBuilder) builder = NULL;
g_autoptr (GString) string = NULL;
const char *meta_name;
meta_name = clutter_actor_meta_get_name (effect_meta);
string = g_string_new (NULL);
g_string_append (string, G_OBJECT_TYPE_NAME (effect_node->effect));
g_string_append (string, " (");
if (meta_name)
g_string_append_printf (string, "\"%s\"", meta_name);
else
g_string_append (string, "unnamed");
g_string_append (string, ")");
builder = json_builder_new ();
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "effect");
json_builder_add_string_value (builder, string->str);
json_builder_end_object (builder);
return json_builder_get_root (builder);
}
static void
clutter_effect_node_class_init (ClutterEffectNodeClass *klass)
{
ClutterPaintNodeClass *node_class;
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
node_class->serialize = clutter_effect_node_serialize;
}
static void
clutter_effect_node_init (ClutterEffectNode *self)
{
}
/*
* clutter_effect_node_new:
* @actor: the actor to paint
*
* Creates a new #ClutterEffectNode.
*
* Return value: (transfer full): the newly created #ClutterEffectNode.
* Use clutter_paint_node_unref() when done.
*/
ClutterPaintNode *
clutter_effect_node_new (ClutterEffect *effect)
{
ClutterEffectNode *res;
g_assert (effect != NULL);
res = _clutter_paint_node_create (CLUTTER_TYPE_EFFECT_NODE);
res->effect = effect;
return (ClutterPaintNode *) res;
}
/*
* ClutterLayerNode
*/
@@ -1235,6 +1338,7 @@ struct _ClutterLayerNode
CoglFramebuffer *offscreen;
guint8 opacity;
gboolean update_modelview;
};
struct _ClutterLayerNodeClass
@@ -1249,8 +1353,6 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterLayerNode *lnode = (ClutterLayerNode *) node;
CoglFramebuffer *framebuffer;
CoglMatrix matrix;
/* if we were unable to create an offscreen buffer for this node, then
* we simply ignore it
@@ -1258,29 +1360,30 @@ clutter_layer_node_pre_draw (ClutterPaintNode *node,
if (lnode->offscreen == NULL)
return FALSE;
/* if no geometry was submitted for this node then we simply ignore it */
if (node->operations == NULL)
return FALSE;
if (lnode->update_modelview)
{
CoglFramebuffer *framebuffer;
CoglMatrix matrix;
/* copy the same modelview from the current framebuffer to the one we
* are going to use
*/
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
/* copy the same modelview from the current framebuffer to the one we
* are going to use
*/
framebuffer = clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_get_modelview_matrix (framebuffer, &matrix);
cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
cogl_framebuffer_set_viewport (lnode->offscreen,
lnode->viewport.x,
lnode->viewport.y,
lnode->viewport.width,
lnode->viewport.height);
cogl_framebuffer_set_projection_matrix (lnode->offscreen,
&lnode->projection);
}
clutter_paint_context_push_framebuffer (paint_context, lnode->offscreen);
cogl_framebuffer_set_modelview_matrix (lnode->offscreen, &matrix);
cogl_framebuffer_set_viewport (lnode->offscreen,
lnode->viewport.x,
lnode->viewport.y,
lnode->viewport.width,
lnode->viewport.height);
cogl_framebuffer_set_projection_matrix (lnode->offscreen,
&lnode->projection);
/* clear out the target framebuffer */
cogl_framebuffer_clear4f (lnode->offscreen,
COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH,
@@ -1307,6 +1410,10 @@ clutter_layer_node_post_draw (ClutterPaintNode *node,
cogl_framebuffer_pop_matrix (lnode->offscreen);
clutter_paint_context_pop_framebuffer (paint_context);
/* if no geometry was submitted for this node then we simply ignore it */
if (node->operations == NULL)
return;
fb = clutter_paint_context_get_framebuffer (paint_context);
for (i = 0; i < node->operations->len; i++)
@@ -1367,6 +1474,25 @@ clutter_layer_node_finalize (ClutterPaintNode *node)
CLUTTER_PAINT_NODE_CLASS (clutter_layer_node_parent_class)->finalize (node);
}
static JsonNode *
clutter_layer_node_serialize (ClutterPaintNode *node)
{
ClutterLayerNode *layer_node = CLUTTER_LAYER_NODE (node);
g_autoptr (JsonBuilder) builder = NULL;
g_autofree char *framebuffer_ptr = NULL;
builder = json_builder_new ();
framebuffer_ptr = g_strdup_printf ("%p", layer_node->offscreen);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "framebuffer");
json_builder_add_string_value (builder, framebuffer_ptr);
json_builder_end_object (builder);
return json_builder_get_root (builder);
}
static void
clutter_layer_node_class_init (ClutterLayerNodeClass *klass)
{
@@ -1376,6 +1502,7 @@ clutter_layer_node_class_init (ClutterLayerNodeClass *klass)
node_class->pre_draw = clutter_layer_node_pre_draw;
node_class->post_draw = clutter_layer_node_post_draw;
node_class->finalize = clutter_layer_node_finalize;
node_class->serialize = clutter_layer_node_serialize;
}
static void
@@ -1418,6 +1545,7 @@ clutter_layer_node_new (const CoglMatrix *projection,
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
res->update_modelview = TRUE;
res->projection = *projection;
res->viewport = *viewport;
res->fbo_width = width;
@@ -1458,3 +1586,233 @@ out:
return (ClutterPaintNode *) res;
}
/**
* clutter_layer_node_new_with_framebuffer:
* @framebuffer: a #CoglFramebuffer
* @pipeline: a #CoglPipeline
* @opacity: the opacity to be used when drawing the layer
*
* Creates a new #ClutterLayerNode with @framebuffer and
* @pipeline. @framebuffer will then be painted using the
* given @opacity.
*
* When using this constructor, the caller is responsible
* for setting up the framebuffer's modelview and projection
* matrices.
*
* Return value: (transfer full)(nullable): the newly created #ClutterLayerNode.
* Use clutter_paint_node_unref() when done.
*/
ClutterPaintNode *
clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
guint8 opacity)
{
ClutterLayerNode *res;
CoglColor color;
g_return_val_if_fail (cogl_is_framebuffer (framebuffer), NULL);
res = _clutter_paint_node_create (CLUTTER_TYPE_LAYER_NODE);
res->update_modelview = FALSE;
res->offscreen = cogl_object_ref (framebuffer);
res->pipeline = cogl_pipeline_copy (pipeline);
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_pipeline_set_color (res->pipeline, &color);
return (ClutterPaintNode *) res;
}
/*
* ClutterBlitNode
*/
struct _ClutterBlitNode
{
ClutterPaintNode parent_instance;
CoglFramebuffer *src;
CoglFramebuffer *dst;
};
G_DEFINE_TYPE (ClutterBlitNode, clutter_blit_node, CLUTTER_TYPE_PAINT_NODE)
static gboolean
clutter_blit_node_pre_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
return TRUE;
}
static void
clutter_blit_node_draw (ClutterPaintNode *node,
ClutterPaintContext *paint_context)
{
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
g_autoptr (GError) error = NULL;
guint i;
if (node->operations == NULL)
return;
for (i = 0; i < node->operations->len; i++)
{
const ClutterPaintOperation *op;
float op_width, op_height;
op = &g_array_index (node->operations, ClutterPaintOperation, i);
switch (op->opcode)
{
case PAINT_OP_INVALID:
break;
case PAINT_OP_TEX_RECT:
op_width = op->op.texrect[6] - op->op.texrect[4];
op_height = op->op.texrect[7] - op->op.texrect[5];
cogl_blit_framebuffer (blit_node->src,
blit_node->dst,
op->op.texrect[0],
op->op.texrect[1],
op->op.texrect[4],
op->op.texrect[5],
op_width,
op_height,
&error);
if (error)
{
g_warning ("Error blitting framebuffers: %s", error->message);
return;
}
break;
case PAINT_OP_MULTITEX_RECT:
case PAINT_OP_PRIMITIVE:
break;
}
}
}
static void
clutter_blit_node_finalize (ClutterPaintNode *node)
{
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
cogl_clear_object (&blit_node->src);
cogl_clear_object (&blit_node->dst);
CLUTTER_PAINT_NODE_CLASS (clutter_blit_node_parent_class)->finalize (node);
}
static JsonNode *
clutter_blit_node_serialize (ClutterPaintNode *node)
{
ClutterBlitNode *blit_node = CLUTTER_BLIT_NODE (node);
g_autoptr (JsonBuilder) builder = NULL;
g_autofree char *src_ptr = NULL;
g_autofree char *dst_ptr = NULL;
builder = json_builder_new ();
src_ptr = g_strdup_printf ("%p", blit_node->src);
dst_ptr = g_strdup_printf ("%p", blit_node->dst);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "source");
json_builder_add_string_value (builder, src_ptr);
json_builder_end_object (builder);
json_builder_begin_object (builder);
json_builder_set_member_name (builder, "dst");
json_builder_add_string_value (builder, dst_ptr);
json_builder_end_object (builder);
return json_builder_get_root (builder);
}
static void
clutter_blit_node_class_init (ClutterTransformNodeClass *klass)
{
ClutterPaintNodeClass *node_class;
node_class = CLUTTER_PAINT_NODE_CLASS (klass);
node_class->pre_draw = clutter_blit_node_pre_draw;
node_class->draw = clutter_blit_node_draw;
node_class->finalize = clutter_blit_node_finalize;
node_class->serialize = clutter_blit_node_serialize;
}
static void
clutter_blit_node_init (ClutterBlitNode *self)
{
}
/**
* clutter_blit_node_new:
* @src: the source #CoglFramebuffer
* @dst: the destination #CoglFramebuffer
*
* Creates a new #ClutterBlitNode that blits @src into @dst.
*
* You must only add rectangles using clutter_blit_node_add_blit_rectangle().
*
* Return value: (transfer full): the newly created #ClutterBlitNode.
* Use clutter_paint_node_unref() when done.
*/
ClutterPaintNode *
clutter_blit_node_new (CoglFramebuffer *src,
CoglFramebuffer *dst)
{
ClutterBlitNode *res;
g_return_val_if_fail (cogl_is_framebuffer (src), NULL);
g_return_val_if_fail (cogl_is_framebuffer (dst), NULL);
res = _clutter_paint_node_create (CLUTTER_TYPE_BLIT_NODE);
res->src = cogl_object_ref (src);
res->dst = cogl_object_ref (dst);
return (ClutterPaintNode *) res;
}
/**
* clutter_blit_node_add_blit_rectangle:
* @blit_node: a #ClutterBlitNode
* @src_x: Source x position
* @src_y: Source y position
* @dst_x: Destination x position
* @dst_y: Destination y position
* @width: Width of region to copy
* @height: Height of region to copy
*
* Adds a new blit rectangle to the stack of rectangles. All the
* constraints of cogl_blit_framebuffer() apply here.
*/
void
clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height)
{
g_return_if_fail (CLUTTER_IS_BLIT_NODE (blit_node));
clutter_paint_node_add_texture_rectangle (CLUTTER_PAINT_NODE (blit_node),
&(ClutterActorBox) {
.x1 = src_x,
.y1 = src_y,
.x2 = src_x + width,
.y2 = src_y + height,
},
dst_x,
dst_y,
dst_x + width,
dst_y + height);
}

View File

@@ -160,7 +160,8 @@ CLUTTER_EXPORT
GType clutter_actor_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor);
ClutterPaintNode * clutter_actor_node_new (ClutterActor *actor,
int opacity);
#define CLUTTER_TYPE_ROOT_NODE (clutter_root_node_get_type ())
#define CLUTTER_ROOT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_ROOT_NODE, ClutterRootNode))
@@ -208,6 +209,11 @@ ClutterPaintNode * clutter_layer_node_new (const CoglMatrix
float height,
guint8 opacity);
CLUTTER_EXPORT
ClutterPaintNode * clutter_layer_node_new_with_framebuffer (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
guint8 opacity);
#define CLUTTER_TYPE_TRANSFORM_NODE (clutter_transform_node_get_type ())
#define CLUTTER_TRANSFORM_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_TRANSFORM_NODE, ClutterTransformNode))
@@ -230,6 +236,36 @@ GType clutter_transform_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_transform_node_new (const CoglMatrix *projection);
#define CLUTTER_TYPE_BLIT_NODE (clutter_blit_node_get_type ())
#define CLUTTER_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_BLIT_NODE, ClutterBlitNode))
#define CLUTTER_IS_BLIT_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_BLIT_NODE))
/*
* ClutterBlitNode:
*
* The #ClutterLayerNode structure is an opaque
* type whose members cannot be directly accessed.
*/
typedef struct _ClutterBlitNode ClutterBlitNode;
typedef struct _ClutterPaintNodeClass ClutterBlitNodeClass;
CLUTTER_EXPORT
GType clutter_blit_node_get_type (void) G_GNUC_CONST;
CLUTTER_EXPORT
ClutterPaintNode * clutter_blit_node_new (CoglFramebuffer *src,
CoglFramebuffer *dst);
CLUTTER_EXPORT
void clutter_blit_node_add_blit_rectangle (ClutterBlitNode *blit_node,
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height);
G_END_DECLS
#endif /* __CLUTTER_PAINT_NODES_H__ */

View File

@@ -9,9 +9,9 @@ msgid ""
msgstr ""
"Project-Id-Version: metacity.HEAD.ro\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n"
"POT-Creation-Date: 2020-02-23 17:41+0000\n"
"PO-Revision-Date: 2020-03-19 11:58+0100\n"
"Last-Translator: Daniel Șerbănescu <daniel [at] serbanescu [dot] dk>\n"
"POT-Creation-Date: 2020-08-04 08:31+0000\n"
"PO-Revision-Date: 2020-08-14 15:47+0300\n"
"Last-Translator: Florentina Mușat <florentina.musat.28@gmail.com>\n"
"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists."
"sourceforge.net>\n"
"Language: ro\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n==0 || (n!=1 && n%100>=1 && n"
"%100<=19) ? 1 : 2);\n"
"X-Generator: Poedit 2.3\n"
"X-Generator: Poedit 2.4\n"
"X-Project-Style: gnome\n"
"X-Poedit-SourceCharset: UTF-8\n"
@@ -527,7 +527,7 @@ msgid ""
"which can receive keyboard focus under normal circumstances. For a X11 grab "
"to be taken into account under Wayland, the client must also either send a "
"specific X11 ClientMessage to the root window or be among the applications "
"white-listed in key “xwayland-grab-access-rules”."
"allowed in key “xwayland-grab-access-rules”."
msgstr ""
"Permite ca toate evenimentele de tastatură să fie rutate la ferestrele de "
"„redirecționare suprascriere” X11 cu o blocare când se rulează Xwayland. "
@@ -551,9 +551,9 @@ msgid ""
"not allowed to issue X11 keyboard grabs under Xwayland. The resource name or "
"resource class of a given X11 window can be obtained using the command "
"“xprop WM_CLASS”. Wildcards “*” and jokers “?” in the values are supported. "
"Values starting with “!” are blacklisted, which has precedence over the "
"whitelist, to revoke applications from the default system list. The default "
"system list includes the following applications: "
"Values starting with “!” are denied, which has precedence over the list of "
"values allowed, to revoke applications from the default system list. The "
"default system list includes the following applications: "
"“@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Users can break an existing grab by "
"using the specific keyboard shortcut defined by the keybinding key “restore-"
"shortcuts”."
@@ -562,18 +562,17 @@ msgstr ""
"sau nepermise să emită capturi de tastatură X11 în Xwayland. Numele resursei "
"sau clasa resursei a unei ferestre X11 date pot fi obținute utilizând "
"comanda „xprop WM_CLASS*. Metacaracterele „*” și jokerii „?” în valori sunt "
"suportați. Valorile care încep cu „!” sunt adăugate în lista de interziceri, "
"care are prioritate peste lista de permisiuni, pentru a revoca aplicații din "
"lista de sistem implicită. Lista de sistem implicită include următoarele "
"aplicații: „@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Utilizatorii pot să "
"întrerupă o captură existentă prin utilizarea scurtăturii de tastatură "
"specifice definite de tasta de stabilire a combinațiilor de taste „restore-"
"shortcuts”."
"suportați. Valorile care încep cu „!” sunt respinse, care are prioritate "
"peste lista de valori permise, pentru a revoca aplicații din lista de sistem "
"implicită. Lista de sistem implicită include următoarele aplicații: "
"„@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@” Utilizatorii pot să întrerupă o "
"captură existentă prin utilizarea scurtăturii de tastatură specifice "
"definite de tasta de stabilire a combinațiilor de taste „restore-shortcuts”."
#. TRANSLATORS: This string refers to a button that switches between
#. * different modes.
#.
#: src/backends/meta-input-settings.c:2567
#: src/backends/meta-input-settings.c:2698
#, c-format
msgid "Mode Switch (Group %d)"
msgstr "Comutator de mod (grupul %d)"
@@ -581,34 +580,34 @@ msgstr "Comutator de mod (grupul %d)"
#. TRANSLATORS: This string refers to an action, cycles drawing tablets'
#. * mapping through the available outputs.
#.
#: src/backends/meta-input-settings.c:2590
#: src/backends/meta-input-settings.c:2721
msgid "Switch monitor"
msgstr "Comută monitorul"
#: src/backends/meta-input-settings.c:2592
#: src/backends/meta-input-settings.c:2723
msgid "Show on-screen help"
msgstr "Arată ajutorul virtual"
#: src/backends/meta-monitor.c:223
#: src/backends/meta-monitor.c:235
msgid "Built-in display"
msgstr "Afișaj integrat"
#: src/backends/meta-monitor.c:252
#: src/backends/meta-monitor.c:264
msgid "Unknown"
msgstr "Necunoscut"
#: src/backends/meta-monitor.c:254
#: src/backends/meta-monitor.c:266
msgid "Unknown Display"
msgstr "Afișaj necunoscut"
#: src/backends/meta-monitor.c:262
#: src/backends/meta-monitor.c:274
#, c-format
msgctxt ""
"This is a monitor vendor name, followed by a size in inches, like 'Dell 15\"'"
msgid "%s %s"
msgstr "%s %s"
#: src/backends/meta-monitor.c:270
#: src/backends/meta-monitor.c:282
#, c-format
msgctxt ""
"This is a monitor vendor name followed by product/model name where size in "
@@ -623,7 +622,7 @@ msgstr "Compunător"
#. This probably means that a non-WM compositor like xcompmgr is running;
#. * we have no way to get it to exit
#: src/compositor/compositor.c:533
#: src/compositor/compositor.c:516
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display “%s”."
@@ -734,7 +733,7 @@ msgstr "Modul Mutter de utilizat"
msgid "Workspace %d"
msgstr "Spațiu de lucru %d"
#: src/core/util.c:122
#: src/core/util.c:119
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter a fost compilat fără suport pentru modul detaliat\n"
@@ -780,7 +779,7 @@ msgstr ""
"Aceste ferestre nu suportă „salvează configurarea curentă” și vor trebui "
"repornite manual următoarea dată când vă veți autentifica."
#: src/x11/window-props.c:569
#: src/x11/window-props.c:548
#, c-format
msgid "%s (on %s)"
msgstr "%s (pe %s)"

View File

@@ -750,6 +750,7 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
int x;
GList *monitors;
GList *l;
MetaMonitorsConfig *monitors_config;
primary_monitor = find_primary_monitor (monitor_manager);
if (!primary_monitor)
@@ -793,10 +794,15 @@ meta_monitor_config_manager_create_linear (MetaMonitorConfigManager *config_mana
x += logical_monitor_config->layout.width;
}
return meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
monitors_config = meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
if (monitors_config)
meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_ALL_LINEAR);
return monitors_config;
}
MetaMonitorsConfig *
@@ -1078,6 +1084,7 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager)
GList *modes;
GList *monitors;
GList *l;
MetaMonitorsConfig *monitors_config;
monitors = meta_monitor_manager_get_monitors (monitor_manager);
monitor = monitors->data;
@@ -1170,10 +1177,15 @@ create_for_switch_config_all_mirror (MetaMonitorConfigManager *config_manager)
logical_monitor_configs = g_list_append (NULL, logical_monitor_config);
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
return meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
monitors_config = meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
if (monitors_config)
meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_ALL_MIRROR);
return monitors_config;
}
static MetaMonitorsConfig *
@@ -1185,6 +1197,7 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager)
MetaLogicalMonitorLayoutMode layout_mode;
GList *monitors;
GList *l;
MetaMonitorsConfig *monitors_config;
layout_mode = meta_monitor_manager_get_default_layout_mode (monitor_manager);
@@ -1212,10 +1225,15 @@ create_for_switch_config_external (MetaMonitorConfigManager *config_manager)
x += logical_monitor_config->layout.width;
}
return meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
monitors_config = meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
if (monitors_config)
meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_EXTERNAL);
return monitors_config;
}
static MetaMonitorsConfig *
@@ -1226,6 +1244,7 @@ create_for_switch_config_builtin (MetaMonitorConfigManager *config_manager)
GList *logical_monitor_configs;
MetaLogicalMonitorConfig *primary_logical_monitor_config;
MetaMonitor *monitor;
MetaMonitorsConfig *monitors_config;
monitor = meta_monitor_manager_get_laptop_panel (monitor_manager);
if (!monitor)
@@ -1243,10 +1262,15 @@ create_for_switch_config_builtin (MetaMonitorConfigManager *config_manager)
logical_monitor_configs = g_list_append (NULL,
primary_logical_monitor_config);
return meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
monitors_config = meta_monitors_config_new (monitor_manager,
logical_monitor_configs,
layout_mode,
META_MONITORS_CONFIG_FLAG_NONE);
if (monitors_config)
meta_monitors_config_set_switch_config (monitors_config, META_MONITOR_SWITCH_CONFIG_BUILTIN);
return monitors_config;
}
MetaMonitorsConfig *
@@ -1279,9 +1303,6 @@ meta_monitor_config_manager_create_for_switch_config (MetaMonitorConfigManager
return NULL;
}
if (config)
meta_monitors_config_set_switch_config (config, config_type);
return config;
}

View File

@@ -351,6 +351,9 @@ xdg_toplevel_resize (struct wl_client *client,
if (!window)
return;
if (!window->has_resize_func)
return;
if (!meta_wayland_seat_get_grab_info (seat, surface, serial, TRUE, &x, &y))
return;