Compare commits
5 Commits
citadel
...
gbsneto/co
Author | SHA1 | Date | |
---|---|---|---|
|
dd39d7a060 | ||
|
e1c272e3d7 | ||
|
41ece851d6 | ||
|
d5262f0f4d | ||
|
fd99a56fd6 |
@ -38,6 +38,7 @@
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-actor-private.h"
|
||||
#include "clutter-content-private.h"
|
||||
|
||||
#include "clutter-debug.h"
|
||||
@ -91,6 +92,11 @@ clutter_content_real_invalidate (ClutterContent *content)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_invalidate_size (ClutterContent *content)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_real_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
@ -108,6 +114,7 @@ clutter_content_default_init (ClutterContentInterface *iface)
|
||||
iface->attached = clutter_content_real_attached;
|
||||
iface->detached = clutter_content_real_detached;
|
||||
iface->invalidate = clutter_content_real_invalidate;
|
||||
iface->invalidate_size = clutter_content_real_invalidate_size;
|
||||
|
||||
/**
|
||||
* ClutterContent::attached:
|
||||
@ -188,6 +195,45 @@ clutter_content_invalidate (ClutterContent *content)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_content_invalidate_size:
|
||||
* @content: a #ClutterContent
|
||||
*
|
||||
* Signals that @content's size changed. Attached actors with request mode
|
||||
* set to %CLUTTER_REQUEST_CONTENT_SIZE will have a relayout queued.
|
||||
*
|
||||
* Attached actors with other request modes are not redrawn. To redraw them
|
||||
* too, use clutter_content_invalidate().
|
||||
*/
|
||||
void
|
||||
clutter_content_invalidate_size (ClutterContent *content)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
GHashTable *actors;
|
||||
GHashTableIter iter;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CONTENT (content));
|
||||
|
||||
CLUTTER_CONTENT_GET_IFACE (content)->invalidate_size (content);
|
||||
|
||||
actors = g_object_get_qdata (G_OBJECT (content), quark_content_actors);
|
||||
if (actors == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init (&iter, actors);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &actor, NULL))
|
||||
{
|
||||
ClutterRequestMode request_mode;
|
||||
|
||||
g_assert (actor != NULL);
|
||||
|
||||
request_mode = clutter_actor_get_request_mode (actor);
|
||||
|
||||
if (request_mode == CLUTTER_REQUEST_CONTENT_SIZE)
|
||||
_clutter_actor_queue_only_relayout (actor);
|
||||
}
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* _clutter_content_attached:
|
||||
* @content: a #ClutterContent
|
||||
|
@ -86,6 +86,8 @@ struct _ClutterContentIface
|
||||
ClutterActor *actor);
|
||||
|
||||
void (* invalidate) (ClutterContent *content);
|
||||
|
||||
void (* invalidate_size) (ClutterContent *content);
|
||||
};
|
||||
|
||||
CLUTTER_EXPORT
|
||||
@ -98,6 +100,9 @@ gboolean clutter_content_get_preferred_size (ClutterContent *content
|
||||
CLUTTER_EXPORT
|
||||
void clutter_content_invalidate (ClutterContent *content);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_content_invalidate_size (ClutterContent *content);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_CONTENT_H__ */
|
||||
|
@ -53,6 +53,8 @@
|
||||
struct _ClutterImagePrivate
|
||||
{
|
||||
CoglTexture *texture;
|
||||
gint width;
|
||||
gint height;
|
||||
};
|
||||
|
||||
static void clutter_content_iface_init (ClutterContentIface *iface);
|
||||
@ -68,6 +70,27 @@ clutter_image_error_quark (void)
|
||||
return g_quark_from_static_string ("clutter-image-error-quark");
|
||||
}
|
||||
|
||||
static void
|
||||
update_image_size (ClutterImage *self)
|
||||
{
|
||||
gint width, height;
|
||||
|
||||
if (self->priv->texture == NULL)
|
||||
return;
|
||||
|
||||
width = cogl_texture_get_width (self->priv->texture);
|
||||
height = cogl_texture_get_height (self->priv->texture);
|
||||
|
||||
if (self->priv->width == width &&
|
||||
self->priv->height == height)
|
||||
return;
|
||||
|
||||
self->priv->width = width;
|
||||
self->priv->height = height;
|
||||
|
||||
clutter_content_invalidate_size (CLUTTER_CONTENT (self));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_image_finalize (GObject *gobject)
|
||||
{
|
||||
@ -238,6 +261,7 @@ clutter_image_set_data (ClutterImage *image,
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (image));
|
||||
update_image_size (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -306,6 +330,7 @@ clutter_image_set_bytes (ClutterImage *image,
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (image));
|
||||
update_image_size (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -399,6 +424,7 @@ clutter_image_set_area (ClutterImage *image,
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (image));
|
||||
update_image_size (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ struct _ClutterPaintNodeClass
|
||||
typedef enum {
|
||||
PAINT_OP_INVALID = 0,
|
||||
PAINT_OP_TEX_RECT,
|
||||
PAINT_OP_MULTITEX_RECT,
|
||||
PAINT_OP_PATH,
|
||||
PAINT_OP_PRIMITIVE
|
||||
} PaintOpCode;
|
||||
@ -85,6 +86,8 @@ struct _ClutterPaintOperation
|
||||
{
|
||||
PaintOpCode opcode;
|
||||
|
||||
GArray *multitex_coords;
|
||||
|
||||
union {
|
||||
float texrect[8];
|
||||
|
||||
@ -142,30 +145,6 @@ ClutterPaintNode * clutter_paint_node_get_parent (Clutter
|
||||
G_GNUC_INTERNAL
|
||||
CoglFramebuffer * clutter_paint_node_get_framebuffer (ClutterPaintNode *node);
|
||||
|
||||
#define CLUTTER_TYPE_LAYER_NODE (_clutter_layer_node_get_type ())
|
||||
#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode))
|
||||
#define CLUTTER_IS_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYER_NODE))
|
||||
|
||||
/*
|
||||
* ClutterLayerNode:
|
||||
*
|
||||
* The #ClutterLayerNode structure is an opaque
|
||||
* type whose members cannot be directly accessed.
|
||||
*
|
||||
* Since: 1.10
|
||||
*/
|
||||
typedef struct _ClutterLayerNode ClutterLayerNode;
|
||||
typedef struct _ClutterLayerNodeClass ClutterLayerNodeClass;
|
||||
|
||||
GType _clutter_layer_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterPaintNode * _clutter_layer_node_new (const CoglMatrix *projection,
|
||||
const cairo_rectangle_t *viewport,
|
||||
float width,
|
||||
float height,
|
||||
guint8 opacity);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_PAINT_NODE_PRIVATE_H__ */
|
||||
|
@ -761,6 +761,11 @@ clutter_paint_operation_clear (ClutterPaintOperation *op)
|
||||
case PAINT_OP_TEX_RECT:
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
if (op->multitex_coords != NULL)
|
||||
g_array_unref (op->multitex_coords);
|
||||
break;
|
||||
|
||||
case PAINT_OP_PATH:
|
||||
if (op->op.path != NULL)
|
||||
cogl_object_unref (op->op.path);
|
||||
@ -794,6 +799,27 @@ clutter_paint_op_init_tex_rect (ClutterPaintOperation *op,
|
||||
op->op.texrect[7] = y_2;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_paint_op_init_multitex_rect (ClutterPaintOperation *op,
|
||||
const ClutterActorBox *rect,
|
||||
const float *tex_coords,
|
||||
unsigned int tex_coords_len)
|
||||
{
|
||||
clutter_paint_operation_clear (op);
|
||||
|
||||
op->opcode = PAINT_OP_MULTITEX_RECT;
|
||||
op->multitex_coords = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (float),
|
||||
tex_coords_len);
|
||||
|
||||
g_array_append_vals (op->multitex_coords, tex_coords, tex_coords_len);
|
||||
|
||||
op->op.texrect[0] = rect->x1;
|
||||
op->op.texrect[1] = rect->y1;
|
||||
op->op.texrect[2] = rect->x2;
|
||||
op->op.texrect[3] = rect->y2;
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_paint_op_init_path (ClutterPaintOperation *op,
|
||||
CoglPath *path)
|
||||
@ -881,6 +907,33 @@ clutter_paint_node_add_texture_rectangle (ClutterPaintNode *node,
|
||||
g_array_append_val (node->operations, operation);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* clutter_paint_node_add_multitexture_rectangle:
|
||||
* @node: a #ClutterPaintNode
|
||||
* @rect: a #ClutterActorBox
|
||||
* @text_coords: array of multitexture values
|
||||
* @text_coords_len: number of items of @text_coords
|
||||
*
|
||||
* Adds a rectangle region to the @node, with multitexture coordinates.
|
||||
*/
|
||||
void
|
||||
clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node,
|
||||
const ClutterActorBox *rect,
|
||||
const float *text_coords,
|
||||
unsigned int text_coords_len)
|
||||
{
|
||||
ClutterPaintOperation operation = PAINT_OP_INIT;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_PAINT_NODE (node));
|
||||
g_return_if_fail (rect != NULL);
|
||||
|
||||
clutter_paint_node_maybe_init_operations (node);
|
||||
|
||||
clutter_paint_op_init_multitex_rect (&operation, rect, text_coords, text_coords_len);
|
||||
g_array_append_val (node->operations, operation);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_paint_node_add_path: (skip)
|
||||
* @node: a #ClutterPaintNode
|
||||
@ -1006,7 +1059,7 @@ clutter_paint_node_to_json (ClutterPaintNode *node)
|
||||
|
||||
if (node->operations != NULL)
|
||||
{
|
||||
guint i;
|
||||
guint i, j;
|
||||
|
||||
for (i = 0; i < node->operations->len; i++)
|
||||
{
|
||||
@ -1031,6 +1084,19 @@ clutter_paint_node_to_json (ClutterPaintNode *node)
|
||||
json_builder_end_array (builder);
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
json_builder_set_member_name (builder, "texrect");
|
||||
json_builder_begin_array (builder);
|
||||
|
||||
for (j = 0; i < op->multitex_coords->len; j++)
|
||||
{
|
||||
float coord = g_array_index (op->multitex_coords, float, j);
|
||||
json_builder_add_double_value (builder, coord);
|
||||
}
|
||||
|
||||
json_builder_end_array (builder);
|
||||
break;
|
||||
|
||||
case PAINT_OP_PATH:
|
||||
json_builder_set_member_name (builder, "path");
|
||||
json_builder_add_int_value (builder, (gint64) op->op.path);
|
||||
|
@ -67,6 +67,12 @@ void clutter_paint_node_add_texture_rectangle (Clutter
|
||||
float x_2,
|
||||
float y_2);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_paint_node_add_multitexture_rectangle (ClutterPaintNode *node,
|
||||
const ClutterActorBox *rect,
|
||||
const float *text_coords,
|
||||
unsigned int text_coords_len);
|
||||
|
||||
CLUTTER_EXPORT
|
||||
void clutter_paint_node_add_path (ClutterPaintNode *node,
|
||||
CoglPath *path);
|
||||
|
@ -431,6 +431,17 @@ clutter_pipeline_node_draw (ClutterPaintNode *node)
|
||||
op->op.texrect[7]);
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
cogl_framebuffer_draw_multitextured_rectangle (cogl_get_draw_framebuffer (),
|
||||
pnode->pipeline,
|
||||
op->op.texrect[0],
|
||||
op->op.texrect[1],
|
||||
op->op.texrect[2],
|
||||
op->op.texrect[3],
|
||||
(float*) op->multitex_coords->data,
|
||||
op->multitex_coords->len);
|
||||
break;
|
||||
|
||||
case PAINT_OP_PATH:
|
||||
cogl_path_fill (op->op.path);
|
||||
break;
|
||||
@ -827,6 +838,7 @@ clutter_text_node_draw (ClutterPaintNode *node)
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
case PAINT_OP_PATH:
|
||||
case PAINT_OP_PRIMITIVE:
|
||||
case PAINT_OP_INVALID:
|
||||
@ -992,6 +1004,7 @@ clutter_clip_node_pre_draw (ClutterPaintNode *node)
|
||||
retval = TRUE;
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
case PAINT_OP_PRIMITIVE:
|
||||
case PAINT_OP_INVALID:
|
||||
break;
|
||||
@ -1025,6 +1038,7 @@ clutter_clip_node_post_draw (ClutterPaintNode *node)
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
case PAINT_OP_PRIMITIVE:
|
||||
case PAINT_OP_INVALID:
|
||||
break;
|
||||
@ -1065,11 +1079,9 @@ clutter_clip_node_new (void)
|
||||
}
|
||||
|
||||
/*
|
||||
* ClutterLayerNode (private)
|
||||
* ClutterLayerNode
|
||||
*/
|
||||
|
||||
#define clutter_layer_node_get_type _clutter_layer_node_get_type
|
||||
|
||||
struct _ClutterLayerNode
|
||||
{
|
||||
ClutterPaintNode parent_instance;
|
||||
@ -1180,6 +1192,17 @@ clutter_layer_node_post_draw (ClutterPaintNode *node)
|
||||
cogl_pop_source ();
|
||||
break;
|
||||
|
||||
case PAINT_OP_MULTITEX_RECT:
|
||||
cogl_framebuffer_draw_multitextured_rectangle (cogl_get_draw_framebuffer (),
|
||||
lnode->state,
|
||||
op->op.texrect[0],
|
||||
op->op.texrect[1],
|
||||
op->op.texrect[2],
|
||||
op->op.texrect[3],
|
||||
(float*) op->multitex_coords->data,
|
||||
op->multitex_coords->len);
|
||||
break;
|
||||
|
||||
case PAINT_OP_PATH:
|
||||
cogl_push_source (lnode->state);
|
||||
cogl_path_fill (op->op.path);
|
||||
@ -1244,11 +1267,11 @@ clutter_layer_node_init (ClutterLayerNode *self)
|
||||
* Since: 1.10
|
||||
*/
|
||||
ClutterPaintNode *
|
||||
_clutter_layer_node_new (const CoglMatrix *projection,
|
||||
const cairo_rectangle_t *viewport,
|
||||
float width,
|
||||
float height,
|
||||
guint8 opacity)
|
||||
clutter_layer_node_new (const CoglMatrix *projection,
|
||||
const cairo_rectangle_t *viewport,
|
||||
float width,
|
||||
float height,
|
||||
guint8 opacity)
|
||||
{
|
||||
ClutterLayerNode *res;
|
||||
CoglColor color;
|
||||
|
@ -143,6 +143,29 @@ CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_text_node_new (PangoLayout *layout,
|
||||
const ClutterColor *color);
|
||||
|
||||
#define CLUTTER_TYPE_LAYER_NODE (clutter_layer_node_get_type ())
|
||||
#define CLUTTER_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_LAYER_NODE, ClutterLayerNode))
|
||||
#define CLUTTER_IS_LAYER_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_LAYER_NODE))
|
||||
|
||||
/*
|
||||
* ClutterLayerNode:
|
||||
*
|
||||
* The #ClutterLayerNode structure is an opaque
|
||||
* type whose members cannot be directly accessed.
|
||||
*/
|
||||
typedef struct _ClutterLayerNode ClutterLayerNode;
|
||||
typedef struct _ClutterLayerNodeClass ClutterLayerNodeClass;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
GType clutter_layer_node_get_type (void) G_GNUC_CONST;
|
||||
|
||||
CLUTTER_EXPORT
|
||||
ClutterPaintNode * clutter_layer_node_new (const CoglMatrix *projection,
|
||||
const cairo_rectangle_t *viewport,
|
||||
float width,
|
||||
float height,
|
||||
guint8 opacity);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_PAINT_NODES_H__ */
|
||||
|
@ -44,5 +44,13 @@ gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
|
||||
cairo_region_t * meta_shaped_texture_get_opaque_region (MetaShapedTexture *stex);
|
||||
void meta_shaped_texture_set_transform (MetaShapedTexture *stex,
|
||||
MetaMonitorTransform transform);
|
||||
void meta_shaped_texture_cull_out (MetaShapedTexture *stex,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region,
|
||||
uint8_t opacity);
|
||||
void meta_shaped_texture_reset_culling (MetaShapedTexture *stex);
|
||||
void meta_shaped_texture_set_scale (MetaShapedTexture *stex,
|
||||
double scale);
|
||||
double meta_shaped_texture_get_scale (MetaShapedTexture *stex);
|
||||
|
||||
#endif
|
||||
|
@ -57,21 +57,7 @@
|
||||
|
||||
static void meta_shaped_texture_dispose (GObject *object);
|
||||
|
||||
static void meta_shaped_texture_paint (ClutterActor *actor);
|
||||
|
||||
static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p);
|
||||
|
||||
static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p);
|
||||
|
||||
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
|
||||
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
static void clutter_content_iface_init (ClutterContentIface *iface);
|
||||
|
||||
enum {
|
||||
SIZE_CHANGED,
|
||||
@ -83,7 +69,7 @@ static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaShapedTexture
|
||||
{
|
||||
ClutterActor parent;
|
||||
GObject parent;
|
||||
|
||||
MetaTextureTower *paint_tower;
|
||||
|
||||
@ -116,25 +102,21 @@ struct _MetaShapedTexture
|
||||
guint remipmap_timeout_id;
|
||||
gint64 earliest_remipmap;
|
||||
|
||||
double scale;
|
||||
|
||||
guint create_mipmaps : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init));
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_CONTENT, clutter_content_iface_init));
|
||||
|
||||
static void
|
||||
meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
|
||||
|
||||
gobject_class->dispose = meta_shaped_texture_dispose;
|
||||
|
||||
actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
|
||||
actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
|
||||
actor_class->paint = meta_shaped_texture_paint;
|
||||
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
|
||||
|
||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
@ -154,16 +136,12 @@ meta_shaped_texture_init (MetaShapedTexture *stex)
|
||||
{
|
||||
stex->paint_tower = meta_texture_tower_new ();
|
||||
|
||||
stex->scale = 1.0;
|
||||
stex->texture = NULL;
|
||||
stex->mask_texture = NULL;
|
||||
stex->create_mipmaps = TRUE;
|
||||
stex->is_y_inverted = TRUE;
|
||||
stex->transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
|
||||
g_signal_connect (stex,
|
||||
"notify::scale-x",
|
||||
G_CALLBACK (invalidate_size),
|
||||
stex);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -207,7 +185,7 @@ update_size (MetaShapedTexture *stex)
|
||||
stex->dst_width = dst_width;
|
||||
stex->dst_height = dst_height;
|
||||
meta_shaped_texture_set_mask_texture (stex, NULL);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
|
||||
clutter_content_invalidate_size (CLUTTER_CONTENT (stex));
|
||||
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
}
|
||||
@ -436,6 +414,40 @@ paint_clipped_rectangle (CoglFramebuffer *fb,
|
||||
&coords[0], 8);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_clipped_rectangle_node (ClutterPaintNode *root_node,
|
||||
CoglPipeline *pipeline,
|
||||
cairo_rectangle_int_t *rect,
|
||||
ClutterActorBox *alloc)
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) node = NULL;
|
||||
float coords[8];
|
||||
|
||||
coords[0] = rect->x / (alloc->x2 - alloc->x1);
|
||||
coords[1] = rect->y / (alloc->y2 - alloc->y1);
|
||||
coords[2] = (rect->x + rect->width) / (alloc->x2 - alloc->x1);
|
||||
coords[3] = (rect->y + rect->height) / (alloc->y2 - alloc->y1);
|
||||
|
||||
coords[4] = coords[0];
|
||||
coords[5] = coords[1];
|
||||
coords[6] = coords[2];
|
||||
coords[7] = coords[3];
|
||||
|
||||
node = clutter_pipeline_node_new (pipeline);
|
||||
clutter_paint_node_set_name (node, "MetaShapedTexture (clipped)");
|
||||
clutter_paint_node_add_child (root_node, node);
|
||||
|
||||
clutter_paint_node_add_multitexture_rectangle (node,
|
||||
&(ClutterActorBox)
|
||||
{
|
||||
.x1 = rect->x,
|
||||
.x2 = rect->x + rect->width,
|
||||
.y1 = rect->y,
|
||||
.y2 = rect->y + rect->height,
|
||||
},
|
||||
coords, 8);
|
||||
}
|
||||
|
||||
static void
|
||||
set_cogl_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *cogl_tex)
|
||||
@ -476,6 +488,8 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
|
||||
if (stex->create_mipmaps)
|
||||
meta_texture_tower_set_base_texture (stex->paint_tower, cogl_tex);
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (stex));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -486,12 +500,31 @@ texture_is_idle_and_not_mipmapped (gpointer user_data)
|
||||
if ((g_get_monotonic_time () - stex->earliest_remipmap) < 0)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (stex));
|
||||
stex->remipmap_timeout_id = 0;
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *stex)
|
||||
{
|
||||
/*
|
||||
ClutterActor *actor;
|
||||
|
||||
actor = CLUTTER_ACTOR (stex);
|
||||
do
|
||||
{
|
||||
if (clutter_actor_has_mapped_clones (actor))
|
||||
return NULL;
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
while (actor != NULL);
|
||||
*/
|
||||
|
||||
return stex->unobscured_region;
|
||||
}
|
||||
|
||||
static void
|
||||
do_paint (MetaShapedTexture *stex,
|
||||
CoglFramebuffer *fb,
|
||||
@ -696,21 +729,262 @@ do_paint (MetaShapedTexture *stex,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_paint (ClutterActor *actor)
|
||||
{
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (actor);
|
||||
CoglTexture *paint_tex;
|
||||
CoglFramebuffer *fb;
|
||||
do_paint_content (MetaShapedTexture *stex,
|
||||
ClutterPaintNode *root_node,
|
||||
CoglTexture *paint_tex,
|
||||
ClutterActorBox *alloc,
|
||||
double tex_scale,
|
||||
guchar opacity)
|
||||
|
||||
if (!stex->texture)
|
||||
{
|
||||
int dst_width, dst_height;
|
||||
cairo_rectangle_int_t tex_rect;
|
||||
gboolean use_opaque_region;
|
||||
cairo_region_t *clip_tex_region;
|
||||
cairo_region_t *opaque_tex_region;
|
||||
cairo_region_t *blended_tex_region;
|
||||
CoglContext *ctx;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
ensure_size_valid (stex);
|
||||
|
||||
dst_width = stex->dst_width;
|
||||
dst_height = stex->dst_height;
|
||||
|
||||
if (dst_width == 0 || dst_height == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
tex_rect = (cairo_rectangle_int_t) { 0, 0, dst_width, dst_height };
|
||||
|
||||
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
||||
* improves performance, especially with software rendering.
|
||||
*/
|
||||
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
|
||||
/* FIXME: evil cogl_get_draw_framebuffer() */
|
||||
if (meta_actor_painting_untransformed (cogl_get_draw_framebuffer (),
|
||||
dst_width, dst_height,
|
||||
NULL, NULL))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
if (stex->opaque_region && opacity == 255)
|
||||
{
|
||||
opaque_tex_region =
|
||||
meta_region_scale_double (stex->opaque_region,
|
||||
1.0 / tex_scale,
|
||||
META_ROUNDING_STRATEGY_SHRINK);
|
||||
use_opaque_region = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
opaque_tex_region = NULL;
|
||||
use_opaque_region = FALSE;
|
||||
}
|
||||
|
||||
if (stex->clip_region)
|
||||
{
|
||||
clip_tex_region =
|
||||
meta_region_scale_double (stex->clip_region,
|
||||
1.0 / tex_scale,
|
||||
META_ROUNDING_STRATEGY_GROW);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_tex_region = NULL;
|
||||
}
|
||||
|
||||
if (use_opaque_region)
|
||||
{
|
||||
if (clip_tex_region)
|
||||
blended_tex_region = cairo_region_copy (clip_tex_region);
|
||||
else
|
||||
blended_tex_region = cairo_region_create_rectangle (&tex_rect);
|
||||
|
||||
cairo_region_subtract (blended_tex_region, opaque_tex_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clip_tex_region)
|
||||
blended_tex_region = cairo_region_reference (clip_tex_region);
|
||||
else
|
||||
blended_tex_region = NULL;
|
||||
}
|
||||
|
||||
/* Limit to how many separate rectangles we'll draw; beyond this just
|
||||
* fall back and draw the whole thing */
|
||||
#define MAX_RECTS 16
|
||||
|
||||
if (blended_tex_region)
|
||||
{
|
||||
int n_rects = cairo_region_num_rectangles (blended_tex_region);
|
||||
if (n_rects > MAX_RECTS)
|
||||
{
|
||||
/* Fall back to taking the fully blended path. */
|
||||
use_opaque_region = FALSE;
|
||||
|
||||
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
/* First, paint the unblended parts, which are part of the opaque region. */
|
||||
if (use_opaque_region)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
int n_rects;
|
||||
int i;
|
||||
|
||||
if (clip_tex_region)
|
||||
{
|
||||
region = cairo_region_copy (clip_tex_region);
|
||||
cairo_region_intersect (region, opaque_tex_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
region = cairo_region_reference (opaque_tex_region);
|
||||
}
|
||||
|
||||
if (!cairo_region_is_empty (region))
|
||||
{
|
||||
CoglPipeline *opaque_pipeline;
|
||||
|
||||
opaque_pipeline = get_unblended_pipeline (stex, ctx);
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
paint_clipped_rectangle_node (root_node, opaque_pipeline, &rect, alloc);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
/* Now, go ahead and paint the blended parts. */
|
||||
|
||||
/* We have three cases:
|
||||
* 1) blended_tex_region has rectangles - paint the rectangles.
|
||||
* 2) blended_tex_region is empty - don't paint anything
|
||||
* 3) blended_tex_region is NULL - paint fully-blended.
|
||||
*
|
||||
* 1) and 3) are the times where we have to paint stuff. This tests
|
||||
* for 1) and 3).
|
||||
*/
|
||||
if (!blended_tex_region || !cairo_region_is_empty (blended_tex_region))
|
||||
{
|
||||
CoglPipeline *blended_pipeline;
|
||||
|
||||
if (stex->mask_texture == NULL)
|
||||
{
|
||||
blended_pipeline = get_unmasked_pipeline (stex, ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
blended_pipeline = get_masked_pipeline (stex, ctx);
|
||||
cogl_pipeline_set_layer_texture (blended_pipeline, 1, stex->mask_texture);
|
||||
cogl_pipeline_set_layer_filters (blended_pipeline, 1, filter, filter);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (blended_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (blended_pipeline, 0, filter, filter);
|
||||
|
||||
CoglColor color;
|
||||
cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
|
||||
cogl_pipeline_set_color (blended_pipeline, &color);
|
||||
|
||||
if (blended_tex_region)
|
||||
{
|
||||
/* 1) blended_tex_region is not empty. Paint the rectangles. */
|
||||
int i;
|
||||
int n_rects = cairo_region_num_rectangles (blended_tex_region);
|
||||
|
||||
for (i = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_region_get_rectangle (blended_tex_region, i, &rect);
|
||||
|
||||
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
|
||||
continue;
|
||||
|
||||
paint_clipped_rectangle_node (root_node, blended_pipeline, &rect, alloc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(ClutterPaintNode) node = NULL;
|
||||
|
||||
node = clutter_pipeline_node_new (blended_pipeline);
|
||||
clutter_paint_node_set_name (node, "MetaShapedTexture (unclipped)");
|
||||
clutter_paint_node_add_child (root_node, node);
|
||||
|
||||
/* 3) blended_tex_region is NULL. Do a full paint. */
|
||||
clutter_paint_node_add_rectangle (node, alloc);
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_pointer (&clip_tex_region, cairo_region_destroy);
|
||||
g_clear_pointer (&opaque_tex_region, cairo_region_destroy);
|
||||
g_clear_pointer (&blended_tex_region, cairo_region_destroy);
|
||||
}
|
||||
|
||||
static CoglTexture *
|
||||
select_texture_for_paint (MetaShapedTexture *stex)
|
||||
{
|
||||
CoglTexture *texture = NULL;
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
|
||||
if (stex->create_mipmaps && stex->last_invalidation)
|
||||
{
|
||||
gint64 age = now - stex->last_invalidation;
|
||||
|
||||
if (age >= MIN_MIPMAP_AGE_USEC ||
|
||||
stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
||||
texture = meta_texture_tower_get_paint_texture (stex->paint_tower);
|
||||
}
|
||||
|
||||
if (texture == NULL)
|
||||
{
|
||||
texture = COGL_TEXTURE (stex->texture);
|
||||
|
||||
if (texture == NULL)
|
||||
return NULL;
|
||||
|
||||
if (stex->create_mipmaps)
|
||||
{
|
||||
/* Minus 1000 to ensure we don't fail the age test in timeout */
|
||||
stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
|
||||
|
||||
if (!stex->remipmap_timeout_id)
|
||||
stex->remipmap_timeout_id =
|
||||
g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
|
||||
texture_is_idle_and_not_mipmapped,
|
||||
stex);
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_paint_content (ClutterContent *content,
|
||||
ClutterActor *actor,
|
||||
ClutterPaintNode *root_node)
|
||||
{
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
|
||||
ClutterActorBox alloc;
|
||||
CoglTexture *paint_tex = NULL;
|
||||
double tex_scale;
|
||||
guchar opacity;
|
||||
|
||||
if (stex->clip_region && cairo_region_is_empty (stex->clip_region))
|
||||
return;
|
||||
|
||||
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
|
||||
clutter_actor_realize (CLUTTER_ACTOR (stex));
|
||||
|
||||
/* The GL EXT_texture_from_pixmap extension does allow for it to be
|
||||
* used together with SGIS_generate_mipmap, however this is very
|
||||
* rarely supported. Also, even when it is supported there
|
||||
@ -726,100 +1000,40 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
* Setting the texture quality to high without SGIS_generate_mipmap
|
||||
* support for TFP textures will result in fallbacks to XGetImage.
|
||||
*/
|
||||
if (stex->create_mipmaps)
|
||||
{
|
||||
int64_t now = g_get_monotonic_time ();
|
||||
int64_t age = now - stex->last_invalidation;
|
||||
|
||||
if (age >= MIN_MIPMAP_AGE_USEC ||
|
||||
stex->fast_updates < MIN_FAST_UPDATES_BEFORE_UNMIPMAP)
|
||||
{
|
||||
paint_tex = meta_texture_tower_get_paint_texture (stex->paint_tower);
|
||||
if (!paint_tex)
|
||||
paint_tex = stex->texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
paint_tex = stex->texture;
|
||||
|
||||
/* Minus 1000 to ensure we don't fail the age test in timeout */
|
||||
stex->earliest_remipmap = now + MIN_MIPMAP_AGE_USEC - 1000;
|
||||
|
||||
if (!stex->remipmap_timeout_id)
|
||||
stex->remipmap_timeout_id =
|
||||
g_timeout_add (MIN_MIPMAP_AGE_USEC / 1000,
|
||||
texture_is_idle_and_not_mipmapped,
|
||||
stex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
paint_tex = COGL_TEXTURE (stex->texture);
|
||||
}
|
||||
|
||||
if (cogl_texture_get_width (paint_tex) == 0 ||
|
||||
cogl_texture_get_height (paint_tex) == 0)
|
||||
paint_tex = select_texture_for_paint (stex);
|
||||
if (!paint_tex)
|
||||
return;
|
||||
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
do_paint (META_SHAPED_TEXTURE (actor), fb, paint_tex, stex->clip_region);
|
||||
}
|
||||
clutter_actor_get_scale (actor, &tex_scale, NULL);
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
clutter_actor_get_content_box (actor, &alloc);
|
||||
|
||||
static void
|
||||
meta_shaped_texture_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (self);
|
||||
|
||||
ensure_size_valid (stex);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = stex->dst_width;
|
||||
if (natural_width_p)
|
||||
*natural_width_p = stex->dst_width;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (self);
|
||||
|
||||
ensure_size_valid (stex);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = stex->dst_height;
|
||||
if (natural_height_p)
|
||||
*natural_height_p = stex->dst_height;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *stex)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
|
||||
/* Fail if we have any mapped clones. */
|
||||
actor = CLUTTER_ACTOR (stex);
|
||||
do
|
||||
{
|
||||
if (clutter_actor_has_mapped_clones (actor))
|
||||
return NULL;
|
||||
actor = clutter_actor_get_parent (actor);
|
||||
}
|
||||
while (actor != NULL);
|
||||
|
||||
return stex->unobscured_region;
|
||||
do_paint_content (stex, root_node, paint_tex, &alloc, tex_scale, opacity);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
meta_shaped_texture_get_preferred_size (ClutterContent *content,
|
||||
float *width,
|
||||
float *height)
|
||||
{
|
||||
return clutter_paint_volume_set_from_allocation (volume, actor);
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (content);
|
||||
|
||||
ensure_size_valid (stex);
|
||||
|
||||
if (width)
|
||||
*width = stex->dst_width * stex->scale;
|
||||
|
||||
if (height)
|
||||
*height = stex->dst_height * stex->scale;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_content_iface_init (ClutterContentIface *iface)
|
||||
{
|
||||
iface->paint_content = meta_shaped_texture_paint_content;
|
||||
iface->get_preferred_size = meta_shaped_texture_get_preferred_size;
|
||||
}
|
||||
|
||||
void
|
||||
@ -853,7 +1067,7 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
cogl_object_ref (stex->mask_texture);
|
||||
}
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (stex));
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -944,7 +1158,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
{
|
||||
cairo_rectangle_int_t damage_rect;
|
||||
cairo_region_get_extents (intersection, &damage_rect);
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (stex));
|
||||
//clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
|
||||
cairo_region_destroy (intersection);
|
||||
return TRUE;
|
||||
}
|
||||
@ -954,7 +1169,8 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (stex));
|
||||
//clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -1230,7 +1446,7 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
|
||||
|
||||
transformed_clip = alloca (sizeof (cairo_rectangle_int_t));
|
||||
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &tex_scale, NULL);
|
||||
tex_scale = stex->scale;
|
||||
meta_rectangle_scale_double (clip, 1.0 / tex_scale,
|
||||
META_ROUNDING_STRATEGY_GROW,
|
||||
transformed_clip);
|
||||
@ -1318,17 +1534,47 @@ meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
|
||||
invalidate_size (stex);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
ClutterActor *
|
||||
meta_shaped_texture_new (void)
|
||||
{
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (cullable);
|
||||
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_set_scale (MetaShapedTexture *stex,
|
||||
double scale)
|
||||
{
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
if (scale == stex->scale)
|
||||
return;
|
||||
|
||||
stex->scale = scale;
|
||||
|
||||
invalidate_size (stex);
|
||||
clutter_content_invalidate_size (CLUTTER_CONTENT (stex));
|
||||
}
|
||||
|
||||
double
|
||||
meta_shaped_texture_get_scale (MetaShapedTexture *stex)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), 0.0);
|
||||
|
||||
return stex->scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_shaped_texture_cull_out (MetaShapedTexture *stex,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region,
|
||||
uint8_t opacity)
|
||||
{
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
set_unobscured_region (stex, unobscured_region);
|
||||
set_clip_region (stex, clip_region);
|
||||
|
||||
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (stex)) == 0xff)
|
||||
if (opacity == 0xff)
|
||||
{
|
||||
if (stex->opaque_region)
|
||||
{
|
||||
@ -1340,22 +1586,10 @@ meta_shaped_texture_cull_out (MetaCullable *cullable,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_shaped_texture_reset_culling (MetaCullable *cullable)
|
||||
void
|
||||
meta_shaped_texture_reset_culling (MetaShapedTexture *stex)
|
||||
{
|
||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (cullable);
|
||||
set_clip_region (self, NULL);
|
||||
}
|
||||
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
|
||||
|
||||
static void
|
||||
cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = meta_shaped_texture_cull_out;
|
||||
iface->reset_culling = meta_shaped_texture_reset_culling;
|
||||
}
|
||||
|
||||
ClutterActor *
|
||||
meta_shaped_texture_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
|
||||
set_clip_region (stex, NULL);
|
||||
}
|
||||
|
@ -110,54 +110,6 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
return surface->window;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_width (ClutterActor *actor,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaShapedTexture *stex;
|
||||
double scale;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &scale, NULL);
|
||||
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex),
|
||||
for_height,
|
||||
min_width_p,
|
||||
natural_width_p);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p *= scale;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_height (ClutterActor *actor,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaShapedTexture *stex;
|
||||
double scale;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), NULL, &scale);
|
||||
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex),
|
||||
for_width,
|
||||
min_height_p,
|
||||
natural_height_p);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p *= scale;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_paint (ClutterActor *actor)
|
||||
{
|
||||
@ -203,8 +155,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
|
||||
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
|
||||
actor_class->paint = meta_surface_actor_wayland_paint;
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
|
||||
|
@ -158,13 +158,22 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
|
||||
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (surface_actor);
|
||||
uint8_t opacity = clutter_actor_get_opacity (CLUTTER_ACTOR (cullable));
|
||||
|
||||
meta_shaped_texture_cull_out (priv->texture, unobscured_region, clip_region, opacity);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
meta_cullable_reset_culling_children (cullable);
|
||||
MetaSurfaceActor *surface_actor = META_SURFACE_ACTOR (cullable);
|
||||
MetaSurfaceActorPrivate *priv =
|
||||
meta_surface_actor_get_instance_private (surface_actor);
|
||||
|
||||
meta_shaped_texture_reset_culling (priv->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -191,7 +200,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
|
||||
g_signal_connect_object (priv->texture, "size-changed",
|
||||
G_CALLBACK (texture_size_changed), self, 0);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
|
||||
clutter_actor_set_content (CLUTTER_ACTOR (self), CLUTTER_CONTENT (priv->texture));
|
||||
clutter_actor_set_request_mode (CLUTTER_ACTOR (self), CLUTTER_REQUEST_CONTENT_SIZE);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
|
@ -829,14 +829,14 @@ meta_window_actor_get_meta_window (MetaWindowActor *self)
|
||||
*
|
||||
* Return value: (transfer none): the #ClutterActor for the contents
|
||||
*/
|
||||
ClutterActor *
|
||||
MetaShapedTexture *
|
||||
meta_window_actor_get_texture (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv =
|
||||
meta_window_actor_get_instance_private (self);
|
||||
|
||||
if (priv->surface)
|
||||
return CLUTTER_ACTOR (meta_surface_actor_get_texture (priv->surface));
|
||||
return meta_surface_actor_get_texture (priv->surface);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -1875,19 +1875,19 @@ meta_window_actor_get_frame_bounds (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaShapedTexture *stex;
|
||||
MetaRectangle buffer_rect;
|
||||
MetaRectangle frame_rect;
|
||||
double scale_x, scale_y;
|
||||
double scale;
|
||||
|
||||
stex = meta_surface_actor_get_texture (priv->surface);
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &scale_x, &scale_y);
|
||||
scale = meta_shaped_texture_get_scale (stex);
|
||||
|
||||
window = priv->window;
|
||||
meta_window_get_buffer_rect (window, &buffer_rect);
|
||||
meta_window_get_frame_rect (window, &frame_rect);
|
||||
|
||||
bounds->x = (int) floor ((frame_rect.x - buffer_rect.x) / scale_x);
|
||||
bounds->y = (int) floor ((frame_rect.y - buffer_rect.y) / scale_y);
|
||||
bounds->width = (int) ceil (frame_rect.width / scale_x);
|
||||
bounds->height = (int) ceil (frame_rect.height / scale_y);
|
||||
bounds->x = (int) floor ((frame_rect.x - buffer_rect.x) / scale);
|
||||
bounds->y = (int) floor ((frame_rect.y - buffer_rect.y) / scale);
|
||||
bounds->width = (int) ceil (frame_rect.width / scale);
|
||||
bounds->height = (int) ceil (frame_rect.height / scale);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "clutter/clutter.h"
|
||||
#include "meta/compositor.h"
|
||||
#include "meta/meta-shaped-texture.h"
|
||||
|
||||
#define META_TYPE_WINDOW_ACTOR (meta_window_actor_get_type ())
|
||||
|
||||
@ -43,7 +44,7 @@ META_EXPORT
|
||||
MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self);
|
||||
|
||||
META_EXPORT
|
||||
ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self);
|
||||
MetaShapedTexture *meta_window_actor_get_texture (MetaWindowActor *self);
|
||||
|
||||
META_EXPORT
|
||||
void meta_window_actor_sync_visibility (MetaWindowActor *self);
|
||||
|
@ -163,7 +163,7 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
||||
stex = meta_surface_actor_get_texture (surface_actor);
|
||||
|
||||
actor_scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), actor_scale, actor_scale);
|
||||
meta_shaped_texture_set_scale (stex, actor_scale);
|
||||
|
||||
/* Wayland surface coordinate space -> stage coordinate space */
|
||||
geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface);
|
||||
|
@ -1123,7 +1123,7 @@ meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data
|
||||
|
||||
surface_actor = meta_wayland_surface_get_actor (surface);
|
||||
|
||||
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
|
||||
clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface_actor),
|
||||
seat->pointer->grab_x,
|
||||
seat->pointer->grab_y,
|
||||
&surface_pos.x, &surface_pos.y);
|
||||
|
@ -1514,7 +1514,7 @@ meta_wayland_surface_get_relative_coordinates (MetaWaylandSurface *surface,
|
||||
else
|
||||
{
|
||||
ClutterActor *actor =
|
||||
CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
|
||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
||||
|
||||
clutter_actor_transform_stage_point (actor, abs_x, abs_y, sx, sy);
|
||||
*sx /= surface->scale;
|
||||
@ -1530,7 +1530,7 @@ meta_wayland_surface_get_absolute_coordinates (MetaWaylandSurface *surface,
|
||||
float *y)
|
||||
{
|
||||
ClutterActor *actor =
|
||||
CLUTTER_ACTOR (meta_surface_actor_get_texture (meta_wayland_surface_get_actor (surface)));
|
||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
||||
ClutterVertex sv = {
|
||||
.x = sx * surface->scale,
|
||||
.y = sy * surface->scale,
|
||||
|
@ -640,7 +640,7 @@ meta_wayland_tablet_tool_get_relative_coordinates (MetaWaylandTabletTool *tool,
|
||||
surface_actor = meta_wayland_surface_get_actor (surface);
|
||||
|
||||
clutter_event_get_coords (event, &xf, &yf);
|
||||
clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface_actor)),
|
||||
clutter_actor_transform_stage_point (CLUTTER_ACTOR (surface_actor),
|
||||
xf, yf, &xf, &yf);
|
||||
|
||||
*sx = wl_fixed_from_double (xf) / surface->scale;
|
||||
|
Loading…
x
Reference in New Issue
Block a user