Exemplo n.º 1
0
ResizeContext Resize::get_context(Alloc &alloc, PixelType type) const
{
	ResizeContext ctx{};

	if (!m_skip_h && !m_skip_v) {
		double xscale = (double)m_dst_width / (double)m_src_width;
		double yscale = (double)m_dst_height / (double)m_src_height;
		bool h_first = resize_h_first(xscale, yscale);

		ctx.impl1 = h_first ? m_impl_h.get() : m_impl_v.get();
		ctx.impl2 = h_first ? m_impl_v.get() : m_impl_h.get();

		ctx.tmp_width = h_first ? m_dst_width : m_src_width;
		ctx.tmp_height = h_first ? m_src_height : m_dst_height;

		ctx.in_buffering1 = std::min(ctx.impl1->input_buffering(type), m_src_height);
		ctx.in_buffering2 = std::min(ctx.impl2->input_buffering(type), ctx.tmp_height);

		ctx.out_buffering1 = ctx.impl1->output_buffering(type);
		ctx.out_buffering2 = ctx.impl2->output_buffering(type);

		ctx.src_border_buf = alloc_line_buffer(alloc, ctx.in_buffering1, m_src_width, type);
		ctx.dst_border_buf = alloc_line_buffer(alloc, ctx.out_buffering2, m_dst_width, type);
		ctx.tmp_buf = alloc_line_buffer(alloc, ctx.out_buffering1 + ctx.in_buffering2 - 1, ctx.tmp_width, type);

		ctx.tmp_data = alloc.allocate(std::max(ctx.impl1->tmp_size(type, ctx.tmp_width), ctx.impl2->tmp_size(type, m_dst_width)));
	} else if (!(m_skip_h && m_skip_v)) {
		ctx.impl1 = m_impl_h ? m_impl_h.get() : m_impl_v.get();

		ctx.in_buffering1 = std::min(ctx.impl1->input_buffering(type), m_src_height);
		ctx.out_buffering1 = ctx.impl1->output_buffering(type);

		ctx.src_border_buf = alloc_line_buffer(alloc, ctx.in_buffering1, m_src_width, type);
		ctx.dst_border_buf = alloc_line_buffer(alloc, ctx.out_buffering1, m_dst_width, type);
		ctx.tmp_data = alloc.allocate(ctx.impl1->tmp_size(type, m_dst_width));
	}

	return ctx;
}
Exemplo n.º 2
0
Arquivo: tty.c Projeto: jessewt/tundra
void
tty_emit(int job_id, int is_stderr, int sort_key, const char *data, int len)
{
	line_buffer *buf = NULL;

	td_mutex_lock_or_die(&linelock);

	while (len > 0)
	{
		/* Wait for a line buffer to become available, or for the tty to become free. */
		for (;;)
		{
			/* If we already have the tty, or we can get it: break */
			if (-1 == printing_job || job_id == printing_job)
				break;

			/* If we can allocate a buffer: break */

			if (NULL != (buf = alloc_line_buffer()))
				break;

			/* Otherwise wait */
			pthread_cond_wait(&can_print, &linelock);
		}

		if (-1 == printing_job)
		{
			/* Let this job own the output channel */
			TTY_PRINTF(("job %d is taking the tty\n", job_id));
			printing_job = job_id;

			flush_output_queue(job_id);
		}
		else if (job_id != printing_job)
		{
			assert(buf);
		}

		if (!buf)
		{
			/* This thread owns the TTY, so just print. We don't need to keep the
			 * mutex locked as this job will not finsh and reset the currently
			 * printing job until later. Releasing the mutex now means other
			 * threads can come in and buffer their data. */

			td_mutex_unlock_or_die(&linelock);

			TTY_PRINTF(("copying %d bytes of data from job_id %d, stderr=%d, sort_key %d\n",
						len, job_id, is_stderr, sort_key));

			write(is_stderr ? STDERR_FILENO : STDOUT_FILENO, data, strlen(data));
			return; /* finish the loop immediately */
		}
		else
		{
			/* We can't print this data as we don't own the TTY so we buffer it. */
			TTY_PRINTF(("buffering %d bytes of data from job_id %d, stderr=%d, sort_key %d\n",
						len, job_id, is_stderr, sort_key));

			/* PERF: Could release mutex around this memcpy, not sure if it's a win. */
			buf->job_id = job_id;
			buf->sort_key = sort_key;
			buf->len = len > LINEBUF_SIZE - 1 ? LINEBUF_SIZE - 1 : len;
			buf->is_stderr = is_stderr;
			memcpy(buf->data, data, buf->len);
			buf->data[buf->len] = '\0';

			len -= buf->len;
			data += buf->len;

			/* Queue this line for output */
			queued_linebufs[queued_linebuf_count++] = buf;
		}
	}

	td_mutex_unlock_or_die(&linelock);

	return;
}