summaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/vivid/vivid-tpg.c
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2015-03-07 14:06:43 -0300
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 20:39:07 -0300
commit5d7c539e194af598a8f8d8f616ce97581f3d079a (patch)
treeeb5a1eef4ff5adf1f98e48278763812de3e1af25 /drivers/media/platform/vivid/vivid-tpg.c
parentba01f673e031ade4f60583ab1ac4f06dd260a972 (diff)
downloadlinux-5d7c539e194af598a8f8d8f616ce97581f3d079a.tar.gz
linux-5d7c539e194af598a8f8d8f616ce97581f3d079a.tar.bz2
linux-5d7c539e194af598a8f8d8f616ce97581f3d079a.zip
[media] vivid-tpg: precalculate downsampled lines
When dealing with vertical downsampling two successive lines have to be averaged. In the case of the test pattern generator that only happens if the two lines are using different patterns. So precalculate the average between two pattern lines: one of pattern P and one of pattern P + 1. That way there is no need to do any on-the-fly downsampling: it's all done in the precalculate phase. This patch also implements horizontal downsampling in the precalculate phase. The only thing that needs to be done is to half the width since the actual downsampling happens when two pixels at a time are generated. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/platform/vivid/vivid-tpg.c')
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c
index fa50a1f8a6c1..f99756dff3f2 100644
--- a/drivers/media/platform/vivid/vivid-tpg.c
+++ b/drivers/media/platform/vivid/vivid-tpg.c
@@ -128,6 +128,11 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
if (!tpg->lines[pat][plane])
return -ENOMEM;
+ if (plane == 0)
+ continue;
+ tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
+ if (!tpg->downsampled_lines[pat][plane])
+ return -ENOMEM;
}
}
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -155,6 +160,10 @@ void tpg_free(struct tpg_data *tpg)
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
vfree(tpg->lines[pat][plane]);
tpg->lines[pat][plane] = NULL;
+ if (plane == 0)
+ continue;
+ vfree(tpg->downsampled_lines[pat][plane]);
+ tpg->downsampled_lines[pat][plane] = NULL;
}
for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
vfree(tpg->contrast_line[plane]);
@@ -1029,12 +1038,39 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
for (p = 0; p < tpg->planes; p++) {
unsigned twopixsize = tpg->twopixelsize[p];
- u8 *pos = tpg->lines[pat][p] + x * twopixsize / 2;
+ unsigned hdiv = tpg->hdownsampling[p];
+ u8 *pos = tpg->lines[pat][p] +
+ (x / hdiv) * twopixsize / 2;
+
+ memcpy(pos, pix[p], twopixsize / hdiv);
+ }
+ }
+ }
+
+ if (tpg->vdownsampling[tpg->planes - 1] > 1) {
+ unsigned pat_lines = tpg_get_pat_lines(tpg);
+
+ for (pat = 0; pat < pat_lines; pat++) {
+ unsigned next_pat = (pat + 1) % pat_lines;
+
+ for (p = 1; p < tpg->planes; p++) {
+ unsigned twopixsize = tpg->twopixelsize[p];
+ unsigned hdiv = tpg->hdownsampling[p];
- memcpy(pos, pix[p], twopixsize);
+ for (x = 0; x < tpg->scaled_width * 2; x += 2) {
+ unsigned offset = (x / hdiv) * twopixsize / 2;
+ u8 *pos1 = tpg->lines[pat][p] + offset;
+ u8 *pos2 = tpg->lines[next_pat][p] + offset;
+ u8 *dest = tpg->downsampled_lines[pat][p] + offset;
+ unsigned i;
+
+ for (i = 0; i < twopixsize / hdiv; i++, dest++, pos1++, pos2++)
+ *dest = ((u16)*pos1 + (u16)*pos2) / 2;
+ }
}
}
}
+
for (x = 0; x < tpg->scaled_width; x += 2) {
u8 pix[TPG_MAX_PLANES][8];