diff --git a/ChangeLog b/ChangeLog index c2c033e2d..69be11049 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-06-04 Matthew Allum + + * clutter/clutter-element.c: + * clutter/clutter-group.c: + * clutter/clutter-group.h: + Work more on depth ( Z ) setting with sorting. + + * clutter/clutter-main.c: (clutter_redraw): + Experiment with glXWaitVideoSyncSGI. Currently disabled. + 2006-06-02 Matthew Allum * clutter/clutter-element.h: diff --git a/clutter/clutter-element.c b/clutter/clutter-element.c index 9e0014992..8f612a3f3 100644 --- a/clutter/clutter-element.c +++ b/clutter/clutter-element.c @@ -56,7 +56,7 @@ struct _ClutterElementPrivate gint z; /* to element box ? */ guint8 opacity; - ClutterElement *parent_element; + ClutterElement *parent_element; /* This should always be a group */ gchar *name; guint32 id; /* Unique ID */ }; @@ -291,7 +291,8 @@ clutter_element_paint (ClutterElement *self) (float)(-1.0 * self->priv->z) - self->priv->rxz); } - + if (self->priv->z) + glTranslatef ( 0.0, 0.0, (float)self->priv->z); if (klass->paint) (klass->paint) (self); @@ -937,9 +938,15 @@ static void depth_sorter_foreach (ClutterElement *element, gpointer user_data) { ClutterElement *element_to_sort = CLUTTER_ELEMENT(user_data); + gint z_copy; + + z_copy = element->priv->z; if (element_to_sort->priv->z > element->priv->z) - clutter_element_raise (element_to_sort, element); + { + clutter_element_raise (element_to_sort, element); + element->priv->z = z_copy; + } } /** @@ -953,20 +960,19 @@ void clutter_element_set_depth (ClutterElement *self, gint depth) { - /* Sets Z value. Note probably need to sort via stacking order - * so rendering correct with alpha values. - */ + /* Sets Z value.*/ self->priv->z = depth; if (self->priv->parent_element) { - /* Fix stacking ordering so rendering correct */ - - clutter_element_lower_bottom (self); - - clutter_group_foreach (CLUTTER_GROUP(self->priv->parent_element), - depth_sorter_foreach, - (gpointer)self); + /* We need to resort the group stacking order as to + * correctly render alpha values. + * + * FIXME: This is sub optimal. maybe queue the the sort + * before stacking + */ + clutter_group_sort_depth_order + (CLUTTER_GROUP(self->priv->parent_element)); } } diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 5fc3dbca4..fab082a9c 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -205,6 +205,7 @@ clutter_group_new (void) GList* clutter_group_get_children (ClutterGroup *self) { + /* FIXME: remane get_actors() */ g_return_val_if_fail (CLUTTER_IS_GROUP (self), NULL); return g_list_copy(self->priv->children); @@ -294,9 +295,7 @@ clutter_group_add (ClutterGroup *self, ClutterElement *element) /* below refs */ clutter_element_set_parent (element, CLUTTER_ELEMENT(self)); - /* FIXME: Force Sort any Z ordering, or set to 0 ? */ - if (clutter_element_get_depth (element) != 0) - clutter_element_set_depth (element, clutter_element_get_depth (element)); + clutter_group_sort_depth_order (self); } /** @@ -442,7 +441,7 @@ clutter_group_raise (ClutterGroup *self, ClutterElement *sibling) { ClutterGroupPrivate *priv; - gint pos; + gint pos; g_return_if_fail (element != sibling); @@ -453,9 +452,27 @@ clutter_group_raise (ClutterGroup *self, priv->children = g_list_remove (priv->children, element); if (sibling == NULL) - priv->children = g_list_append (priv->children, element); + { + GList *last_item; + /* Raise top */ + last_item = g_list_last (priv->children); + sibling = last_item->data; + priv->children = g_list_append (priv->children, element); + } else - priv->children = g_list_insert (priv->children, element, pos); + { + priv->children = g_list_insert (priv->children, element, pos); + } + + /* set Z ordering a value below, this will then call sort + * as values are equal ordering shouldn't change but Z + * values will be correct. + * FIXME: optimise + */ + if (clutter_element_get_depth(sibling) != clutter_element_get_depth(element)) + clutter_element_set_depth (element, + clutter_element_get_depth(sibling)); + } void @@ -475,7 +492,55 @@ clutter_group_lower (ClutterGroup *self, priv->children = g_list_remove (priv->children, element); if (sibling == NULL) - priv->children = g_list_prepend (priv->children, element); + { + GList *last_item; + /* Raise top */ + last_item = g_list_first (priv->children); + sibling = last_item->data; + + priv->children = g_list_prepend (priv->children, element); + } else priv->children = g_list_insert (priv->children, element, pos); + + /* See comment in group_raise for this */ + if (clutter_element_get_depth(sibling) != clutter_element_get_depth(element)) + clutter_element_set_depth (element, + clutter_element_get_depth(sibling)); +} + +static gint +sort_z_order (gconstpointer a, gconstpointer b) +{ + if (clutter_element_get_depth (CLUTTER_ELEMENT(a)) + == clutter_element_get_depth (CLUTTER_ELEMENT(b))) + return 0; + + if (clutter_element_get_depth (CLUTTER_ELEMENT(a)) + > clutter_element_get_depth (CLUTTER_ELEMENT(b))) + return 1; + + return -1; +} + +/** + * clutter_group_sort_z_order: + * @self: A #ClutterGroup + * + * Sorts a #ClutterGroup's children by there depth value. + * This function should not be used by applications. + **/ +void +clutter_group_sort_depth_order (ClutterGroup *self) +{ + ClutterGroupPrivate *priv; + + g_return_if_fail (CLUTTER_IS_GROUP(self)); + + priv = self->priv; + + priv->children = g_list_sort (priv->children, sort_z_order); + + if (CLUTTER_ELEMENT_IS_VISIBLE (CLUTTER_ELEMENT(self))) + clutter_element_queue_redraw (CLUTTER_ELEMENT(self)); } diff --git a/clutter/clutter-group.h b/clutter/clutter-group.h index 25dd7d632..4e6be150a 100644 --- a/clutter/clutter-group.h +++ b/clutter/clutter-group.h @@ -125,6 +125,9 @@ clutter_group_lower (ClutterGroup *self, ClutterElement *element, ClutterElement *sibling); +void +clutter_group_sort_depth_order (ClutterGroup *self); + G_END_DECLS #endif diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index 78c4ceee0..05131da3d 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -260,6 +260,14 @@ clutter_redraw () if (clutter_stage_get_xwindow (stage)) { +#if 0 + unsigned int retraceCount; + + // Wait for vertical retrace + // glXGetVideoSyncSGI(&retraceCount); + // glXWaitVideoSyncSGI(2, (retraceCount+1)%2, &retraceCount); + glXWaitVideoSyncSGI(1, 0, &retraceCount); +#endif glXSwapBuffers(ctx->xdpy, clutter_stage_get_xwindow (stage)); } else