Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c70316f2 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] vivid: move PRINTSTR to separate functions



Commit 84cb7be4 broke vivid-tpg
(uninitialized variable p).

This patch takes a different approach: four different functions are
created, one for each PRINTSTR version.

In order to avoid the 'the frame size of 1308 bytes is larger than 1024
bytes' warning I had to mark those functions with 'noinline'. For
whatever reason gcc seems to inline this aggressively and it is doing
weird things with the stack.

I tried to read the assembly code, but I couldn't see what exactly it
was doing on the stack.

Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 64d57022
Loading
Loading
Loading
Loading
+81 −47
Original line number Original line Diff line number Diff line
@@ -1462,40 +1462,10 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
/* need this to do rgb24 rendering */
/* need this to do rgb24 rendering */
typedef struct { u16 __; u8 _; } __packed x24;
typedef struct { u16 __; u8 _; } __packed x24;


void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
#define PRINTSTR(PIXTYPE) do {	\
		  int y, int x, char *text)
{
	int line;
	unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
	unsigned div = step;
	unsigned first = 0;
	unsigned len = strlen(text);
	unsigned p;

	if (font8x16 == NULL || basep == NULL)
		return;

	/* Checks if it is possible to show string */
	if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
		return;

	if (len > (tpg->compose.width - x) / 8)
		len = (tpg->compose.width - x) / 8;
	if (tpg->vflip)
		y = tpg->compose.height - y - 16;
	if (tpg->hflip)
		x = tpg->compose.width - x - 8;
	y += tpg->compose.top;
	x += tpg->compose.left;
	if (tpg->field == V4L2_FIELD_BOTTOM)
		first = 1;
	else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
		div = 2;

	/* Print text */
#define PRINTSTR(PIXTYPE) for (p = 0; p < tpg->planes; p++) {	\
	unsigned vdiv = tpg->vdownsampling[p]; \
	unsigned vdiv = tpg->vdownsampling[p]; \
	unsigned hdiv = tpg->hdownsampling[p]; \
	unsigned hdiv = tpg->hdownsampling[p]; \
	int line;	\
	PIXTYPE fg;	\
	PIXTYPE fg;	\
	PIXTYPE bg;	\
	PIXTYPE bg;	\
	memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));	\
	memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));	\
@@ -1546,21 +1516,85 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
	}	\
	}	\
} while (0)
} while (0)


static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
			unsigned p, unsigned first, unsigned div, unsigned step,
			int y, int x, char *text, unsigned len)
{
	PRINTSTR(u8);
}

static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
			unsigned p, unsigned first, unsigned div, unsigned step,
			int y, int x, char *text, unsigned len)
{
	PRINTSTR(u16);
}

static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
			unsigned p, unsigned first, unsigned div, unsigned step,
			int y, int x, char *text, unsigned len)
{
	PRINTSTR(x24);
}

static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
			unsigned p, unsigned first, unsigned div, unsigned step,
			int y, int x, char *text, unsigned len)
{
	PRINTSTR(u32);
}

void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
		  int y, int x, char *text)
{
	unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
	unsigned div = step;
	unsigned first = 0;
	unsigned len = strlen(text);
	unsigned p;

	if (font8x16 == NULL || basep == NULL)
		return;

	/* Checks if it is possible to show string */
	if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
		return;

	if (len > (tpg->compose.width - x) / 8)
		len = (tpg->compose.width - x) / 8;
	if (tpg->vflip)
		y = tpg->compose.height - y - 16;
	if (tpg->hflip)
		x = tpg->compose.width - x - 8;
	y += tpg->compose.top;
	x += tpg->compose.left;
	if (tpg->field == V4L2_FIELD_BOTTOM)
		first = 1;
	else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
		div = 2;

	for (p = 0; p < tpg->planes; p++) {
		/* Print text */
		switch (tpg->twopixelsize[p]) {
		switch (tpg->twopixelsize[p]) {
		case 2:
		case 2:
		PRINTSTR(u8);
			tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
					text, len);
			break;
			break;
		case 4:
		case 4:
		PRINTSTR(u16);
			tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
					text, len);
			break;
			break;
		case 6:
		case 6:
		PRINTSTR(x24);
			tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
					text, len);
			break;
			break;
		case 8:
		case 8:
		PRINTSTR(u32);
			tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
					text, len);
			break;
			break;
		}
		}
	}
	}
}


void tpg_update_mv_step(struct tpg_data *tpg)
void tpg_update_mv_step(struct tpg_data *tpg)
{
{