int daemon_update_render_nodes(struct razer_daemon *daemon)
{
	if(daemon->is_render_nodes_dirty)
		daemon_compute_render_nodes(daemon);
		//printf("daemon render_nodes to update:%d\n",daemon->render_nodes_num);
	int ret = 0;
	struct razer_fx_render_node *rn = NULL;
	for(int i = list_GetLen(daemon->render_nodes)-1;i>=0;i--)
	{
		rn = list_Get(daemon->render_nodes,i);
		ret = daemon_update_render_node(daemon,rn);
		if(!ret)
		{
			//TODO rewrite
			if(rn->next)
			{
				//exchange this render_node with the next one
				list_Set(daemon->render_nodes,i,rn->next);
				if(rn->move_frame_buffer_linkage_to_next)
				{
					if(rn->next->output_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->output_frame);
					if(rn->next->input_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->input_frame);
					if(rn->next->second_input_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->second_input_frame);
					rn->next->input_frame = rn->input_frame;
					rn->next->second_input_frame = rn->second_input_frame;
					rn->next->input_frame_linked_uid = rn->input_frame_linked_uid;
					rn->next->second_input_frame_linked_uid = rn->second_input_frame_linked_uid;
					//if(rn->output_frame_linked_uid!= -1)
				}
				rn->next->output_frame = rn->output_frame;
				rn->next->output_frame_linked_uid = rn->output_frame_linked_uid;


				rn->next->prev = rn;
				rn->next->start_ticks = 0;
				rn->start_ticks = 0;
				rn->running = 0;

			}
		}
	}
	if(!rn->next && !ret)
	{
		//root render_node effect returned 0
		//start next render_node in chain or default

	}
		//razer_clear_frame(daemon->render_node->input_frame);
		//daemon_update_render_node(daemon->render_node);
	razer_update_frame(daemon->chroma,daemon->frame_buffer);
	return(1);
}
int daemon_input_event_render_nodes(struct razer_daemon *daemon,struct razer_chroma_event *event)
{
	if(daemon->is_render_nodes_dirty)
		daemon_compute_render_nodes(daemon);
	int ret = 0;
	struct razer_fx_render_node *rn = NULL;
	for(int i = list_GetLen(daemon->render_nodes)-1;i>=0;i--)
	{
		rn = list_Get(daemon->render_nodes,i);
		ret = daemon_input_event_render_node(daemon,rn,event);
		if(!ret && rn->id != daemon->frame_buffer_linked_uid)
		{
			if(rn->next)
			{
				//exchange this render_node with the next one
				list_Set(daemon->render_nodes,i,rn->next);
				if(rn->move_frame_buffer_linkage_to_next)
				{
					if(rn->next->output_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->output_frame);
					if(rn->next->input_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->input_frame);
					if(rn->next->second_input_frame_linked_uid == -1)
						razer_free_rgb_frame(rn->next->second_input_frame);
					rn->next->input_frame = rn->input_frame;
					rn->next->second_input_frame = rn->second_input_frame;
					rn->next->output_frame = rn->output_frame;
					rn->next->input_frame_linked_uid = rn->input_frame_linked_uid;
					rn->next->second_input_frame_linked_uid = rn->second_input_frame_linked_uid;
					//if(rn->output_frame_linked_uid!= -1)
					rn->next->output_frame_linked_uid = rn->output_frame_linked_uid;
				}
				rn->next->prev = rn;
				rn->next->start_ticks = 0;
				rn->start_ticks = 0;
				rn->running = 0;

			}
		}
	}
	if(rn->next && !ret)
	{
		//printf("switching root render node from %d to %d\n",rn->id,rn->next->id);
		rn->start_ticks = 0;
		rn->running = 0;
		daemon_connect_frame_buffer(daemon,rn->next);
		//root render_node effect returned 0
		//start next render_node in chain or default

	}
	return(1);
}
void daemon_connect_second_input(struct razer_daemon *daemon,struct razer_fx_render_node *render_node,struct razer_fx_render_node *input_node)
{
	//if(render_node->input_frame_linked_uid != 0) //unlink old render node first
	//{
	//	struct razer_fx_render_node *old_rn = daemon_get_render_node(daemon,daemon->frame_buffer_linked_uid);
	//	old_rn->output_frame = daemon_create_rgb_frame();
	//	old_rn->output_frame_linked_uid = -1;
	//}
	if(render_node->second_input_frame_linked_uid == -1)
		razer_free_rgb_frame(render_node->second_input_frame);
	render_node->second_input_frame = input_node->output_frame;
	render_node->second_input_frame_linked_uid = input_node->id;
	daemon->is_render_nodes_dirty = 1;
}
void daemon_connect_frame_buffer(struct razer_daemon *daemon,struct razer_fx_render_node *render_node)
{
	if(daemon->frame_buffer_linked_uid != 0) //unlink old render node first
	{
		struct razer_fx_render_node *old_rn = daemon_get_render_node(daemon,daemon->frame_buffer_linked_uid);
		old_rn->output_frame = razer_create_rgb_frame();
		old_rn->output_frame_linked_uid = -1;
	}
	if(render_node->output_frame_linked_uid == -1)
		razer_free_rgb_frame(render_node->output_frame);
	render_node->output_frame = daemon->frame_buffer;
	daemon->frame_buffer_linked_uid = render_node->id;
	daemon->fps = render_node->effect->fps;
	daemon->is_render_nodes_dirty = 1;
}