Пример #1
0
bool
TaskClampSW::run(RunParams&) const
{
	RectInt r = target_rect;
	if (!r.valid())
	{
		VectorInt offset = get_offset();
		RectInt ra = sub_task()->target_rect + r.get_min() + get_offset();
		if (ra.valid())
		{
			etl::set_intersect(ra, ra, r);
			if (ra.valid())
			{
				LockWrite ldst(this);
				if (!ldst) return false;
				LockRead lsrc(sub_task());
				if (!lsrc) return false;

				const synfig::Surface &a = lsrc->get_surface();
				synfig::Surface &c = ldst->get_surface();

				for(int y = ra.miny; y < ra.maxy; ++y)
				{
					const Color *ca = &a[y - r.miny + offset[1]][ra.minx - r.minx + offset[0]];
					Color *cc = &c[y][ra.minx];
					for(int x = ra.minx; x < ra.maxx; ++x, ++ca, ++cc)
						clamp_pixel(*cc, *ca);
				}
			}
		}
	}

	return true;
}
Пример #2
0
bool
TaskBlendSW::run(RunParams & /* params */) const
{
	const synfig::Surface &a =
		SurfaceSW::Handle::cast_dynamic( sub_task_a()->target_surface )->get_surface();
	const synfig::Surface &b =
		SurfaceSW::Handle::cast_dynamic( sub_task_b()->target_surface )->get_surface();
	synfig::Surface &c =
		SurfaceSW::Handle::cast_dynamic( target_surface )->get_surface();

	//debug::DebugSurface::save_to_file(a, "TaskBlendSW__run__a");
	//debug::DebugSurface::save_to_file(b, "TaskBlendSW__run__b");

	RectInt r = get_target_rect();
	if (r.valid())
	{
		RectInt ra = sub_task_a()->get_target_rect() + r.get_min() + offset_a;
		if (ra.valid())
		{
			etl::set_intersect(ra, ra, r);
			if (ra.valid() && &a != &c)
			{
				synfig::Surface::pen p = c.get_pen(ra.minx, ra.maxx);
				const_cast<synfig::Surface*>(&a)->blit_to(
					p,
					ra.minx - r.minx - offset_a[0],
					ra.miny - r.miny - offset_a[1],
					ra.maxx - ra.minx,
					ra.maxy - ra.miny );
			}
		}

		RectInt fill[] = { ra, RectInt::zero(), RectInt::zero(), RectInt::zero() };
		RectInt rb = sub_task_b()->get_target_rect() + r.get_min() + offset_b;
		if (rb.valid())
		{
			etl::set_intersect(rb, rb, r);
			if (rb.valid())
			{
				synfig::Surface::alpha_pen ap(c.get_pen(rb.minx, rb.miny));
				ap.set_blend_method(blend_method);
				ap.set_alpha(amount);
				const_cast<synfig::Surface*>(&b)->blit_to(
					ap,
					rb.minx - r.minx - offset_b[0],
					rb.miny - r.miny - offset_b[1],
					rb.maxx - rb.minx,
					rb.maxy - rb.miny );

				if (ra.valid())
				{
					// mark unfilled regions
					fill[0] = fill[1] = fill[2] = fill[3] = ra;
					fill[0].maxx = fill[2].minx = fill[3].minx = std::max(ra.minx, std::min(ra.maxx, rb.minx));
					fill[1].minx = fill[2].maxx = fill[3].maxx = std::max(ra.minx, std::min(ra.maxx, rb.maxx));
					fill[2].maxy = std::max(ra.miny, std::min(ra.maxy, rb.miny));
					fill[3].miny = std::max(ra.miny, std::min(ra.maxy, rb.maxy));
				}
			}
		}

		if (Color::is_straight(blend_method))
		{
			for(int i = 0; i < 4; ++i)
			{
				if (fill[i].valid())
				{
					synfig::Surface::alpha_pen ap(
						c.get_pen(fill[i].minx, fill[i].miny) );
					ap.set_blend_method(blend_method);
					ap.set_alpha(amount);
					c.fill( Color(0, 0, 0, 0), ap,
							fill[i].maxx - fill[i].minx,
							fill[i].maxy - fill[i].miny );
				}
			}
		}
	}

	//debug::DebugSurface::save_to_file(c, "TaskBlendSW__run__c");

	return true;
}
Пример #3
0
bool
synfig::Target_Tile::render_frame_(Context context,ProgressCallback *cb)
{
	const RendDesc &rend_desc(desc);

	etl::clock total_time;
	etl::clock::value_type work_time(0);
	etl::clock::value_type find_tile_time(0);
	etl::clock::value_type add_tile_time(0);
	total_time.reset();

	// If the quality is set to zero, then we
	// use the parametric scanline-renderer.
	if(get_quality()==0)
	{
		Surface surface;

		RendDesc tile_desc;
		RectInt rect;
		int i = 0;
		etl::clock tile_timer;
		tile_timer.reset();
		while(next_tile(rect))
		{
			find_tile_time+=tile_timer();

			SuperCallback super(cb,i,i+1,10000);
			if(!super.amount_complete(0,1000))
				return false;
			++i;

			// Perform clipping on the tile
			if(clipping_)
				etl::set_intersect(rect, rect, RectInt(0, 0, rend_desc.get_w(), rend_desc.get_h()));

			tile_desc=rend_desc;
			tile_desc.set_subwindow(rect.minx, rect.miny, rect.maxx - rect.minx, rect.maxy - rect. miny);
			if(!parametric_render(context, surface, tile_desc,&super))
			{
				// For some reason, the parametric renderer failed.
				if(cb)cb->error(_("Parametric Renderer Failure"));
				return false;
			}
			else
			{
				if(!surface)
				{
					if(cb)cb->error(_("Bad surface"));
					return false;
				}
				switch(get_alpha_mode())
				{
					case TARGET_ALPHA_MODE_FILL:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
							surface[0][i]=Color::blend(surface[0][i],desc.get_bg_color(),1.0f);
						break;
					case TARGET_ALPHA_MODE_EXTRACT:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
						{
							float a=surface[0][i].get_a();
							surface[0][i] = Color(a,a,a,a);
						}
						break;
					case TARGET_ALPHA_MODE_REDUCE:
						for(int i=0;i<surface.get_w()*surface.get_h();i++)
							surface[0][i].set_a(1.0f);
						break;
					default:
						break;
				}

				// Add the tile to the target
				if(!add_tile(surface, rect.minx, rect.miny))
				{
					if(cb)cb->error(_("add_tile():Unable to put surface on target"));
					return false;
				}
			}
			tile_timer.reset();
		}
		SuperCallback super(cb,i,10000,10000);
	}
	else // If quality is set otherwise, then we use the accelerated renderer
	{
		etl::clock tile_timer;
		tile_timer.reset();

		// Gather tiles
		std::vector<RectInt> tiles;
		RectInt rect;
		while(next_tile(rect)) {
			if (clipping_)
				if (rect.minx >= rend_desc.get_w() || rect.miny >= rend_desc.get_h())
					continue;
			tiles.push_back(rect);
		}
		find_tile_time += tile_timer();

		// Render tiles
		for(std::vector<RectInt>::iterator i = tiles.begin(); i != tiles.end(); ++i)
		{
			// Progress callback
			int index = i - tiles.begin();
			int count = (int)tiles.size();
			SuperCallback super(cb, (count-index)*1000, (count-index+1)*1000, count*1000);
			if(!super.amount_complete(0,1000))
				return false;

			// Render tile
			tile_timer.reset();

			rect = *i;
			if (clipping_)
				etl::set_intersect(rect, rect, RectInt(0, 0, rend_desc.get_w(), rend_desc.get_h()));

			if (!rect.valid())
				continue;

			RendDesc tile_desc=rend_desc;
			tile_desc.set_subwindow(rect.minx, rect.miny, rect.maxx - rect.minx, rect.maxy - rect.miny);

			async_render_tile(rect, context, tile_desc, &super);
		}
	}

	if (!wait_render_tiles(cb))
		return false;

	if(cb && !cb->amount_complete(10000,10000))
		return false;

#ifdef SYNFIG_DISPLAY_EFFICIENCY
	synfig::info(">>>>>> Render Time: %fsec, Find Tile Time: %fsec, Add Tile Time: %fsec, Total Time: %fsec",work_time,find_tile_time,add_tile_time,total_time());
	synfig::info(">>>>>> FRAME EFFICIENCY: %f%%",(100.0f*work_time/total_time()));
#endif
	return true;
}