diff --git a/src/compositor/clutter-utils.c b/src/compositor/clutter-utils.c index 6b2fb7328..fb74732ce 100644 --- a/src/compositor/clutter-utils.c +++ b/src/compositor/clutter-utils.c @@ -51,6 +51,12 @@ round_to_fixed (float x) return roundf (x * 256); } +/* Help macros to scale from OpenGL <-1,1> coordinates system to + * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c + */ +#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) +#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) + /* This helper function checks if (according to our fixed point precision) * the vertices @verts form a box of width @widthf and height @heightf * located at integral coordinates. These coordinates are returned @@ -118,3 +124,67 @@ meta_actor_is_untransformed (ClutterActor *actor, return meta_actor_vertices_are_untransformed (verts, widthf, heightf, x_origin, y_origin); } +/** + * meta_actor_painting_untransformed: + * @paint_width: the width of the painted area + * @paint_height: the height of the painted area + * @x_origin: if the transform is only an integer translation + * then the X coordinate of the location of the origin under the transformation + * from drawing space to screen pixel space is returned here. + * @y_origin: if the transform is only an integer translation + * then the X coordinate of the location of the origin under the transformation + * from drawing space to screen pixel space is returned here. + * + * Determines if the current painting transform is an integer translation. + * This can differ from the result of meta_actor_is_untransformed() when + * painting an actor if we're inside a inside a clone paint. @paint_width + * and @paint_height are used to determine the vertices of the rectangle + * we check to see if the painted area is "close enough" to the integer + * transform. + */ +gboolean +meta_actor_painting_untransformed (int paint_width, + int paint_height, + int *x_origin, + int *y_origin) +{ + CoglMatrix modelview, projection, modelview_projection; + ClutterVertex vertices[4]; + float viewport[4]; + int i; + + cogl_get_modelview_matrix (&modelview); + cogl_get_projection_matrix (&projection); + + cogl_matrix_multiply (&modelview_projection, + &projection, + &modelview); + + vertices[0].x = 0; + vertices[0].y = 0; + vertices[0].z = 0; + vertices[1].x = paint_width; + vertices[1].y = 0; + vertices[1].z = 0; + vertices[2].x = 0; + vertices[2].y = paint_height; + vertices[2].z = 0; + vertices[3].x = paint_width; + vertices[3].y = paint_height; + vertices[3].z = 0; + + cogl_get_viewport (viewport); + + for (i = 0; i < 4; i++) + { + float w = 1; + cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w); + vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w, + viewport[2], viewport[0]); + vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w, + viewport[3], viewport[1]); + } + + return meta_actor_vertices_are_untransformed (vertices, paint_width, paint_height, x_origin, y_origin); +} + diff --git a/src/compositor/clutter-utils.h b/src/compositor/clutter-utils.h index a6d76ce21..36a5925cf 100644 --- a/src/compositor/clutter-utils.h +++ b/src/compositor/clutter-utils.h @@ -31,4 +31,9 @@ gboolean meta_actor_is_untransformed (ClutterActor *actor, int *x_origin, int *y_origin); +gboolean meta_actor_painting_untransformed (int paint_width, + int paint_height, + int *x_origin, + int *y_origin); + #endif /* __META_CLUTTER_UTILS_H__ */ diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c index 4096e4871..cb4ade4a1 100644 --- a/src/compositor/meta-window-group.c +++ b/src/compositor/meta-window-group.c @@ -31,64 +31,6 @@ static void cullable_iface_init (MetaCullableInterface *iface); G_DEFINE_TYPE_WITH_CODE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_ACTOR, G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE, cullable_iface_init)); -/* Help macros to scale from OpenGL <-1,1> coordinates system to - * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c - */ -#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) -#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2)) - -/* Check if we're painting the MetaWindowGroup "untransformed". This can - * differ from the result of actor_is_untransformed(window_group) if we're - * inside a clone paint. The integer translation, if any, is returned. - */ -static gboolean -painting_untransformed (MetaWindowGroup *window_group, - int *x_origin, - int *y_origin) -{ - CoglMatrix modelview, projection, modelview_projection; - ClutterVertex vertices[4]; - int width, height; - float viewport[4]; - int i; - - cogl_get_modelview_matrix (&modelview); - cogl_get_projection_matrix (&projection); - - cogl_matrix_multiply (&modelview_projection, - &projection, - &modelview); - - meta_screen_get_size (window_group->screen, &width, &height); - - vertices[0].x = 0; - vertices[0].y = 0; - vertices[0].z = 0; - vertices[1].x = width; - vertices[1].y = 0; - vertices[1].z = 0; - vertices[2].x = 0; - vertices[2].y = height; - vertices[2].z = 0; - vertices[3].x = width; - vertices[3].y = height; - vertices[3].z = 0; - - cogl_get_viewport (viewport); - - for (i = 0; i < 4; i++) - { - float w = 1; - cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w); - vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w, - viewport[2], viewport[0]); - vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w, - viewport[3], viewport[1]); - } - - return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin); -} - static void meta_window_group_cull_out (MetaCullable *cullable, cairo_region_t *unobscured_region, @@ -119,10 +61,13 @@ meta_window_group_paint (ClutterActor *actor) int paint_x_offset, paint_y_offset; int paint_x_origin, paint_y_origin; int actor_x_origin, actor_y_origin; + int screen_width, screen_height; MetaWindowGroup *window_group = META_WINDOW_GROUP (actor); ClutterActor *stage = clutter_actor_get_stage (actor); + meta_screen_get_size (window_group->screen, &screen_width, &screen_height); + /* Normally we expect an actor to be drawn at it's position on the screen. * However, if we're inside the paint of a ClutterClone, that won't be the * case and we need to compensate. We look at the position of the window @@ -136,7 +81,7 @@ meta_window_group_paint (ClutterActor *actor) * painting currently, and never worry about how actors are positioned * on the stage. */ - if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) || + if (!meta_actor_painting_untransformed (screen_width, screen_height, &paint_x_origin, &paint_y_origin) || !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin)) { CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);