예제 #1
0
void
OptimizerSplit::run(const RunParams &params) const
{
	if (!params.list) return;
	const int min_area = 256*256;
	for(Task::List::iterator i = params.list->begin(); i != params.list->end(); ++i)
	{
		if (TaskInterfaceSplit *split = i->type_pointer<TaskInterfaceSplit>())
		if (split->is_splittable())
		{
			RectInt r = (*i)->target_rect;
			int w = r.maxx - r.minx;
			int h = r.maxy - r.miny;
			int t = std::min(h/10, w*h/min_area);
			if (t >= 2)
			{
				int hh = h/t;
				int y = r.miny;
				for(int j = 1; j < t; ++j, y += hh)
				{
					Task::Handle task = (*i)->clone();
					task->trunc_target_rect( RectInt(r.minx, y, r.maxx, y + hh) );
					i = params.list->insert(i, task);
					++i;
				}
				*i = (*i)->clone();
				(*i)->trunc_target_rect( RectInt(r.minx, y, r.maxx, r.maxy) );
				apply(params);
			}
		}
	}
}
void
OptimizerSurfaceCreate::insert_task(
	std::set<Surface::Handle> &created_surfaces,
	const RunParams& params,
	Task::List::iterator &i,
	const Task::Handle &task ) const
{
	if ( task
	  && task->valid_target()
	  && !task->target_surface->is_created()
	  && !created_surfaces.count(task->target_surface) )
	{
		created_surfaces.insert(task->target_surface);
		TaskSurfaceCreate::Handle surface_create = new TaskSurfaceCreate();
		surface_create->target_surface = task->target_surface;

		VectorInt size = task->target_surface->get_size();
		RectInt rect = task->get_target_rect();
		Vector lt = task->get_source_rect_lt();
		Vector rb = task->get_source_rect_rb();
		Vector k( (rb[0] - lt[0])/(rect.maxx - rect.minx),
				  (rb[1] - lt[1])/(rect.maxy - rect.miny) );
		Vector nlt( lt[0] - k[0]*rect.minx,
				    lt[1] - k[1]*rect.miny);
		Vector nrb( lt[0] + k[0]*(size[0] - rect.minx),
				    lt[1] + k[1]*(size[1] - rect.miny) );
		surface_create->init_target_rect(RectInt(VectorInt::zero(), size), nlt, nrb);
		assert( surface_create->check() );
		i = params.list.insert(i, surface_create);
		++i;
		apply(params);
	}
}
예제 #3
0
void
OptimizerBlendZero::apply_zero(const RunParams &params, const TaskBlend::Handle &blend, const Task::Handle &task) const
{
	if (!task || !task->valid_target())
	{
		Task::Handle empty = new TaskSurfaceEmpty();
		empty->target_surface = params.ref_task->target_surface;
		apply(params, empty);
		return;
	}

	if (task->target_surface == blend->target_surface)
	{
		apply(params, task);
		return;
	}

	apply(params, task->clone());
	params.ref_task->target_surface = blend->target_surface;
	params.ref_task->move_target_rect(
		  blend->get_target_offset()
		- task->get_target_offset()
		+ (task == blend->sub_task_a() ? blend->offset_a : blend->offset_b) );
	assert( params.ref_task->check() );
}
예제 #4
0
void
TaskLayer::set_coords_sub_tasks()
{
	if (!sub_task())
		return;
	if (!is_valid_coords() || !layer)
		{ sub_task()->set_coords_zero(); return; }

	VectorInt size = target_rect.get_size();

	RendDesc desc;
	desc.set_wh(size[0], size[1]);
	desc.set_tl(source_rect.get_min());
	desc.set_br(source_rect.get_max());

	std::vector<RendDesc> descs;
	layer->get_sub_renddesc(desc, descs);
	sort(descs.begin(), descs.end(), renddesc_less);

	Task::Handle task = sub_task();
	sub_tasks.clear();

	for(std::vector<RendDesc>::const_iterator i = descs.begin(); i != descs.end(); ++i)
	{
		if (i->get_w() <= 0 || i->get_h() <= 0)
			continue;

		Point lt = i->get_tl(), rb = i->get_br();
		Rect rect(lt, rb);
		if (!rect.is_valid())
			continue;

		Matrix matrix;
		if (approximate_less(rb[0], lt[0]))
			{ matrix.m00 = -1.0; matrix.m20 = rb[0] - lt[0]; }
		if (approximate_less(rb[1], lt[1]))
			{ matrix.m11 = -1.0; matrix.m20 = rb[1] - lt[1]; }
		matrix = i->get_transformation_matrix() * matrix;
		if (!matrix.is_invertible())
			continue;

		Task::Handle t = task->clone();
		if (!matrix.is_identity()) {
			TaskTransformationAffine::Handle ta = new TaskTransformationAffine();
			ta->transformation->matrix = matrix;
			ta->sub_task() = t;
			t = ta;
		}

		sub_tasks.push_back(t);
		t->set_coords(rect, VectorInt(i->get_w(), i->get_h()));
	}
}