Ejemplo n.º 1
0
Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg)
{
	SMIL_Timing_RTI *rti;
	u32 active_count = 0, i = 0;
	s32 ret;
	if (!sg) return 0;

	sg->update_smil_timing = 0;
	while((rti = (SMIL_Timing_RTI *)gf_list_enum(sg->smil_timed_elements, &i))) {
		//scene_time = rti->timed_elt->sgprivate->scenegraph->GetSceneTime(rti->timed_elt->sgprivate->scenegraph->userpriv);
		ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt));
		if (ret == -1) {
			/* special case for discard element */
			i--;
		} else if (ret == -2) {
			/* special return value, -2 means that the tested timed element is waiting to begin
			   Assuming that the timed elements are sorted by begin order, 
			   the next ones don't need to be checked */
			break;
		} else {
			active_count += ret;
		}
	}

	/*in case an anim triggers another one previously inactivated...
	TODO FIXME: it would be much better to stack anim as active/inactive*/
	while (sg->update_smil_timing) {
		sg->update_smil_timing = 0;
		i = 0;
		while((rti = (SMIL_Timing_RTI *)gf_list_enum(sg->smil_timed_elements, &i))) {
			/*this means the anim has been, modified, re-evaluate it*/
			if (rti->scene_time==-1) {
				ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt) );
				if (ret == -1) {
					/* special case for discard element */
					i--;
				} else if (ret == -2) {
					/* special return value, -2 means that the tested timed element is waiting to begin
					   Assuming that the timed elements are sorted by begin order, 
					   the next ones don't need to be checked */
					break;
				} else {
					active_count += ret;
				}
			}
		}
	}
	return (active_count>0);
}
Ejemplo n.º 2
0
/* This function notifies the scene time to all the timed elements from the list in the given scene graph.
   It returns the number of active timed elements. If no timed element is active, this means that from the timing
   point of view, the scene has not changed and no rendering refresh is needed, even if the time has changed.
   It uses an additional list of modified timed elements to insure that no timing 
   element was modified by the begin/end/repeat of another timed element.
*/
Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg)
{
	SMIL_Timing_RTI *rti;
	u32 active_count, i;
	s32 ret;
	Bool do_loop;
	if (!sg) return 0;

	active_count = 0;

	/*
		Note: whenever a timed element is active, we trigger a gf_node_dirty_parent_graph so that the parent graph 
		is aware that some modifications may happen in the subtree. This is needed for cases where the subtree
		is in an offscreen surface, to force retraversing of the subtree and thus apply the animation. 

	*/
	
	/* notify the new scene time to the register timed elements 
	   this might modify other timed elements or the element itself 
	   in which case it will be added to the list of modified elements */
	i = 0;
	do_loop = 1;
	while(do_loop && (rti = (SMIL_Timing_RTI *)gf_list_enum(sg->smil_timed_elements, &i))) {
		ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt) );
		switch (ret) {
		case -1:
			/* special case for discard element
			   when a discard element is executed, it automatically removes itself from the list of timed element 
			   in the scene graph, we need to fix the index i. */
			i--;
			break;
		case -2:
			/* special return value, -2 means that the tested timed element is waiting to begin
			   Assuming that the timed elements are sorted by begin order, 
			   the next ones don't need to be checked */
			do_loop = 0;
			break;
		case -3:
			/* special case for animation elements which do not need to be notified anymore, 
			   but which require a tree traversal */
			i--;
			active_count ++;
			gf_node_dirty_parent_graph(rti->timed_elt);
			break;
		case 1:
			active_count++;
			gf_node_dirty_parent_graph(rti->timed_elt);
			break;
		case 0:
		default:
			break;
		}
	}

	/* notify the timed elements which have been modified either since the previous frame (updates, scripts) or 
	   because of the start/end/repeat of the previous notifications */
	while (gf_list_count(sg->modified_smil_timed_elements)) {
		/* first remove the modified smil timed element */
		rti = gf_list_get(sg->modified_smil_timed_elements, 0);
		gf_list_rem(sg->modified_smil_timed_elements, 0);

		/* then remove it in the list of non modified (if it was there) */
		gf_list_del_item(sg->smil_timed_elements, rti);

		/* then insert it at its right position (in the sorted list of timed elements) */
		gf_smil_timing_add_to_sg(sg, rti);

		/* finally again notify this timed element */
		rti->force_reevaluation = 1;
		ret = gf_smil_timing_notify_time(rti, gf_node_get_scene_time((GF_Node*)rti->timed_elt) );
		switch (ret) {
		case -1:
			break;
		case -2:
			break;
		case -3:
			active_count++;
			gf_node_dirty_parent_graph(rti->timed_elt);
			break;
		case 1:
			active_count++;
			gf_node_dirty_parent_graph(rti->timed_elt);
			break;
		case 0:
		default:
			break;
		}

	}
	return (active_count>0);
}