Blame synfig-core/src/synfig/rendering/common/optimizer/optimizertransformation.cpp

78db8b
/* === S Y N F I G ========================================================= */
78db8b
/*!	\file synfig/rendering/common/optimizer/optimizertransformation.cpp
78db8b
**	\brief OptimizerTransformation
78db8b
**
78db8b
**	$Id$
78db8b
**
78db8b
**	\legal
81df8d
**	......... ... 2015-2018 Ivan Mahonin
78db8b
**
78db8b
**	This package is free software; you can redistribute it and/or
78db8b
**	modify it under the terms of the GNU General Public License as
78db8b
**	published by the Free Software Foundation; either version 2 of
78db8b
**	the License, or (at your option) any later version.
78db8b
**
78db8b
**	This package is distributed in the hope that it will be useful,
78db8b
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
78db8b
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
78db8b
**	General Public License for more details.
78db8b
**	\endlegal
78db8b
*/
78db8b
/* ========================================================================= */
78db8b
78db8b
/* === H E A D E R S ======================================================= */
78db8b
78db8b
#ifdef USING_PCH
78db8b
#	include "pch.h"
78db8b
#else
78db8b
#ifdef HAVE_CONFIG_H
78db8b
#	include <config.h></config.h>
78db8b
#endif
78db8b
78db8b
#include "optimizertransformation.h"
78db8b
5b889e
#include "../task/tasktransformation.h"
81df8d
#include "../../primitive/transformationaffine.h"
5b889e
78db8b
#endif
78db8b
78db8b
using namespace synfig;
78db8b
using namespace rendering;
78db8b
78db8b
/* === M A C R O S ========================================================= */
78db8b
78db8b
/* === G L O B A L S ======================================================= */
78db8b
78db8b
/* === P R O C E D U R E S ================================================= */
78db8b
78db8b
/* === M E T H O D S ======================================================= */
78db8b
81df8d
81df8d
OptimizerTransformation::OptimizerTransformation()
943a07
{
81df8d
	category_id = CATEGORY_ID_BEGIN;
81df8d
	mode = MODE_REPEAT_LAST | MODE_RECURSIVE;
81df8d
	for_task = true;
943a07
}
943a07
81df8d
943a07
void
81df8d
OptimizerTransformation::run(const RunParams& params) const
943a07
{
81df8d
	TaskTransformation::Handle transformation = TaskTransformation::Handle::cast_dynamic(params.ref_task);
81df8d
	if (!transformation || !transformation->is_simple()) return;
81df8d
81df8d
	// transformation of none in none
81df8d
	Task::Handle sub_task = transformation->sub_task();
61ff9b
	if (!sub_task || !transformation->get_transformation())
dda72a
		{ apply(params, Task::Handle()); return; }
81df8d
81df8d
	// transformation of solid is solid
81df8d
	if (TaskInterfaceConstant *constant = sub_task.type_pointer<taskinterfaceconstant>())</taskinterfaceconstant>
943a07
	{
81df8d
		if (constant->is_constant())
81df8d
		{
81df8d
			sub_task = sub_task->clone();
81df8d
			sub_task->assign_target(*transformation);
81df8d
			apply(params, sub_task);
81df8d
			return;
81df8d
		}
943a07
	}
61ff9b
	
61ff9b
	// merge into sub-task
81df8d
	if (TaskInterfaceTransformation *interface = sub_task.type_pointer<taskinterfacetransformation>())</taskinterfacetransformation>
5b889e
	{
81df8d
		if ( interface->get_transformation()
81df8d
		  && interface->get_transformation()->can_merge_outer( transformation->get_transformation() ) )
943a07
		{
81df8d
			sub_task = sub_task->clone();
81df8d
			sub_task->assign_target(*transformation);
81df8d
81df8d
			interface = sub_task.type_pointer<taskinterfacetransformation>();</taskinterfacetransformation>
81df8d
			assert( interface
81df8d
			     && interface->get_transformation()->can_merge_outer( transformation->get_transformation()) );
81df8d
			interface->get_transformation()->merge_outer( transformation->get_transformation() );
81df8d
81df8d
			apply(params, sub_task);
e76351
			return;
943a07
		}
81df8d
	}
943a07
61ff9b
	// merge sub-task into current task
61ff9b
	if (TaskTransformation::Handle sub_transformation = TaskTransformation::Handle::cast_dynamic(sub_task))
61ff9b
	{
61ff9b
		if ( sub_transformation->is_simple()
61ff9b
		  && sub_transformation->sub_task()
61ff9b
		  && !sub_transformation->target_surface // exclude tasks with prerendered source
61ff9b
		  && transformation->get_transformation()->can_merge_inner(sub_transformation->get_transformation()) )
61ff9b
		{
61ff9b
			transformation = TaskTransformation::Handle::cast_dynamic(transformation->clone());
61ff9b
			// recheck ability to merge after clone
61ff9b
			assert( transformation->get_transformation()->can_merge_inner( transformation->get_transformation()) );
61ff9b
			transformation->get_transformation()->merge_inner( sub_transformation->get_transformation() );
61ff9b
			transformation->sub_task() = sub_transformation->sub_task();
61ff9b
			apply(params, transformation);
61ff9b
			return;
61ff9b
		}
61ff9b
	}
61ff9b
	
81df8d
	// fall deeper in tree to make a chance to merge with others (for affine only)
81df8d
	if ( transformation->get_transformation().type_is<transformationaffine>() )</transformationaffine>
81df8d
	{
81df8d
		if ( sub_task.type_is<taskinterfacetransformationpass>() )</taskinterfacetransformationpass>
943a07
		{
81df8d
			sub_task = sub_task->clone();
81df8d
			sub_task->assign_target(*transformation);
81df8d
			for(Task::List::iterator i = sub_task->sub_tasks.begin(); i != sub_task->sub_tasks.end(); ++i)
81df8d
				if (*i) {
81df8d
					Task::Handle t = transformation->clone();
81df8d
					t->assign_target(**i);
81df8d
					t->sub_task(0) = *i;
81df8d
					*i = t;
943a07
				}
81df8d
			apply(params, sub_task);
81df8d
			return;
943a07
		}
5b889e
	}
78db8b
}
78db8b
81df8d
78db8b
/* === E N T R Y P O I N T ================================================= */