forked from Minki/linux
[media] vivid: move PRINTSTR to separate functions
Commit 84cb7be43c
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: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
64d5702229
commit
c70316f2a1
@ -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)
|
unsigned vdiv = tpg->vdownsampling[p]; \
|
||||||
{
|
unsigned hdiv = tpg->hdownsampling[p]; \
|
||||||
int line;
|
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 hdiv = tpg->hdownsampling[p]; \
|
|
||||||
PIXTYPE fg; \
|
PIXTYPE fg; \
|
||||||
PIXTYPE bg; \
|
PIXTYPE bg; \
|
||||||
memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \
|
memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \
|
||||||
@ -1546,19 +1516,83 @@ void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
switch (tpg->twopixelsize[p]) {
|
static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
|
||||||
case 2:
|
unsigned p, unsigned first, unsigned div, unsigned step,
|
||||||
PRINTSTR(u8);
|
int y, int x, char *text, unsigned len)
|
||||||
break;
|
{
|
||||||
case 4:
|
PRINTSTR(u8);
|
||||||
PRINTSTR(u16);
|
}
|
||||||
break;
|
|
||||||
case 6:
|
static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
|
||||||
PRINTSTR(x24);
|
unsigned p, unsigned first, unsigned div, unsigned step,
|
||||||
break;
|
int y, int x, char *text, unsigned len)
|
||||||
case 8:
|
{
|
||||||
PRINTSTR(u32);
|
PRINTSTR(u16);
|
||||||
break;
|
}
|
||||||
|
|
||||||
|
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]) {
|
||||||
|
case 2:
|
||||||
|
tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
|
||||||
|
text, len);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
|
||||||
|
text, len);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
|
||||||
|
text, len);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
|
||||||
|
text, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user