From 618b53d4b49febefa56e8161bececa88d3ebc630 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 21 Apr 2012 00:37:09 +0200 Subject: Add gradient test pattern --- fbdev.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 201 insertions(+), 3 deletions(-) diff --git a/fbdev.c b/fbdev.c index 10e7612..a94751b 100644 --- a/fbdev.c +++ b/fbdev.c @@ -61,6 +61,7 @@ enum fb_fill_mode { enum fb_fill_pattern { FB_PATTERN_SMPTE = 0, FB_PATTERN_LINES = 1, + FB_PATTERN_GRADIENT = 2, }; /* ----------------------------------------------------------------------------- @@ -872,10 +873,17 @@ enum fb_yuv_order { FB_YUV_YCrCb, }; +#define FB_MAKE_YUV_601_Y(r, g, b) \ + ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16) +#define FB_MAKE_YUV_601_U(r, g, b) \ + (((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128) +#define FB_MAKE_YUV_601_V(r, g, b) \ + (((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128) + #define FB_MAKE_YUV_601(dev, r, g, b) \ - { .y = (( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16, \ - .u = ((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128, \ - .v = ((112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128 } + { .y = FB_MAKE_YUV_601_Y(r, g, b), \ + .u = FB_MAKE_YUV_601_U(r, g, b), \ + .v = FB_MAKE_YUV_601_V(r, g, b) } static void fb_fill_smpte_nv(struct device *dev, unsigned int xoffset, unsigned int yoffset, @@ -1425,6 +1433,190 @@ fb_fill_lines(struct device *dev, unsigned int xoffset, unsigned int yoffset, } } +static void +fb_fill_gradient_nv(struct device *dev, unsigned int xoffset, unsigned int yoffset, + unsigned int xres, unsigned int yres, + unsigned int xsub, unsigned int ysub, + enum fb_yuv_order order) +{ + uint8_t *y_mem = dev->mem + dev->fix_info.line_length * yoffset + + xoffset; + uint8_t *c_mem = dev->mem + + dev->fix_info.line_length * dev->var_info.yres_virtual + + dev->fix_info.line_length * yoffset / ysub + + xoffset * 2 / xsub; + unsigned int u = order != FB_YUV_YCbCr; + unsigned int v = order == FB_YUV_YCbCr; + unsigned int x; + unsigned int y; + + /* Luma */ + for (y = 0; y < yres / 3; ++y) { + for (x = 0; x < xres; ++x) + y_mem[x] = FB_MAKE_YUV_601_Y(255 * x / xres, 0, 0); + y_mem += dev->fix_info.line_length; + } + for (; y < yres * 2 / 3; ++y) { + for (x = 0; x < xres; ++x) + y_mem[x] = FB_MAKE_YUV_601_Y(0, 255 * x / xres, 0); + y_mem += dev->fix_info.line_length; + } + for (; y < yres; ++y) { + for (x = 0; x < xres; ++x) + y_mem[x] = FB_MAKE_YUV_601_Y(0, 0, 255 * x / xres); + y_mem += dev->fix_info.line_length; + } + + /* Chroma */ + for (y = 0; y < yres / 3; y += ysub) { + for (x = 0; x < xres; x += xsub) { + c_mem[2/xsub*x+u] = FB_MAKE_YUV_601_U(255 * x / xres, 0, 0); + c_mem[2/xsub*x+v] = FB_MAKE_YUV_601_V(255 * x / xres, 0, 0); + } + c_mem += dev->fix_info.line_length * 2 / xsub; + } + for (; y < yres * 2 / 3; y += ysub) { + for (x = 0; x < xres; x += xsub) { + c_mem[2/xsub*x+u] = FB_MAKE_YUV_601_U(0, 255 * x / xres, 0); + c_mem[2/xsub*x+v] = FB_MAKE_YUV_601_V(0, 255 * x / xres, 0); + } + c_mem += dev->fix_info.line_length * 2 / xsub; + } + for (; y < yres; y += ysub) { + for (x = 0; x < xres; x += xsub) { + c_mem[2/xsub*x+u] = FB_MAKE_YUV_601_U(0, 0, 255 * x / xres); + c_mem[2/xsub*x+v] = FB_MAKE_YUV_601_V(0, 0, 255 * x / xres); + } + c_mem += dev->fix_info.line_length * 2 / xsub; + } +} + +static void +fb_fill_gradient_rgb16(struct device *dev, unsigned int xoffset, + unsigned int yoffset, unsigned int xres, unsigned int yres) +{ + void *mem = dev->mem + dev->fix_info.line_length * yoffset + + xoffset * dev->var_info.bits_per_pixel / 8; + unsigned int x; + unsigned int y; + + for (y = 0; y < yres / 3; ++y) { + for (x = 0; x < xres; ++x) + ((uint16_t *)mem)[x] = FB_MAKE_RGB(dev, 255 * x / xres, 0, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres * 2 / 3; ++y) { + for (x = 0; x < xres; ++x) + ((uint16_t *)mem)[x] = FB_MAKE_RGB(dev, 0, 255 * x / xres, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres; ++y) { + for (x = 0; x < xres; ++x) + ((uint16_t *)mem)[x] = FB_MAKE_RGB(dev, 0, 0, 255 * x / xres); + mem += dev->fix_info.line_length; + } +} + +static void +fb_fill_gradient_rgb24(struct device *dev, unsigned int xoffset, + unsigned int yoffset, unsigned int xres, unsigned int yres) +{ + void *mem = dev->mem + dev->fix_info.line_length * yoffset + + xoffset * dev->var_info.bits_per_pixel / 8; + unsigned int x; + unsigned int y; + + for (y = 0; y < yres / 3; ++y) { + for (x = 0; x < xres; ++x) + ((struct fb_color24 *)mem)[x].value = + FB_MAKE_RGB(dev, 255 * x / xres, 0, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres * 2 / 3; ++y) { + for (x = 0; x < xres; ++x) + ((struct fb_color24 *)mem)[x].value = + FB_MAKE_RGB(dev, 0, 255 * x / xres, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres; ++y) { + for (x = 0; x < xres; ++x) + ((struct fb_color24 *)mem)[x].value = + FB_MAKE_RGB(dev, 0, 0, 255 * x / xres); + mem += dev->fix_info.line_length; + } +} + +static void +fb_fill_gradient_rgb32(struct device *dev, unsigned int xoffset, + unsigned int yoffset, unsigned int xres, unsigned int yres) +{ + void *mem = dev->mem + dev->fix_info.line_length * yoffset + + xoffset * dev->var_info.bits_per_pixel / 8; + unsigned int x; + unsigned int y; + + for (y = 0; y < yres / 3; ++y) { + for (x = 0; x < xres; ++x) + ((uint32_t *)mem)[x] = FB_MAKE_RGB(dev, 255 * x / xres, 0, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres * 2 / 3; ++y) { + for (x = 0; x < xres; ++x) + ((uint32_t *)mem)[x] = FB_MAKE_RGB(dev, 0, 255 * x / xres, 0); + mem += dev->fix_info.line_length; + } + for (; y < yres; ++y) { + for (x = 0; x < xres; ++x) + ((uint32_t *)mem)[x] = FB_MAKE_RGB(dev, 0, 0, 255 * x / xres); + mem += dev->fix_info.line_length; + } +} + +/* + * fb_fill_gradient - Fill the frame buffer with a gradient test pattern + * @dev: FB device + * @xoffset: Horizontal offset, in pixels + * @yoffset: Vertical offset, in pixels + * @xres: Horizontal size, in pixels + * @yres: Vertical size, in pixels + * + * Fill the display (when mode is FB_FILL_DISPLAY) or virtual frame buffer area + * (when mode is FB_FILL_VIRTUAL) with a gradient pattern. + */ +static void +fb_fill_gradient(struct device *dev, unsigned int xoffset, unsigned int yoffset, + unsigned int xres, unsigned int yres) +{ + switch (dev->fourcc) { + case V4L2_PIX_FMT_NV12: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 2, 2, FB_YUV_YCbCr); + case V4L2_PIX_FMT_NV21: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 2, 2, FB_YUV_YCrCb); + case V4L2_PIX_FMT_NV16: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 2, 1, FB_YUV_YCbCr); + case V4L2_PIX_FMT_NV61: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 2, 1, FB_YUV_YCrCb); + case V4L2_PIX_FMT_NV24: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 1, 1, FB_YUV_YCbCr); + case V4L2_PIX_FMT_NV42: + return fb_fill_gradient_nv(dev, xoffset, yoffset, xres, yres, + 1, 1, FB_YUV_YCrCb); + case V4L2_PIX_FMT_RGB565: + return fb_fill_gradient_rgb16(dev, xoffset, yoffset, xres, yres); + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + return fb_fill_gradient_rgb24(dev, xoffset, yoffset, xres, yres); + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + return fb_fill_gradient_rgb32(dev, xoffset, yoffset, xres, yres); + } +} + /* * fb_fill - Fill the frame buffer with a test pattern * @dev: FB device @@ -1488,6 +1680,10 @@ fb_fill(struct device *dev, enum fb_fill_mode mode, enum fb_fill_pattern pattern printf("Filling frame buffer with lines test pattern\n"); return fb_fill_lines(dev, xoffset, yoffset, xres, yres); + case FB_PATTERN_GRADIENT: + printf("Filling frame buffer with gradient test pattern\n"); + return fb_fill_gradient(dev, xoffset, yoffset, xres, yres); + default: printf("Error: unsupported test pattern %u.\n", pattern); break; @@ -1708,6 +1904,8 @@ int main(int argc, char *argv[]) fill_pattern = FB_PATTERN_SMPTE; else if (strcmp(optarg, "lines") == 0) fill_pattern = FB_PATTERN_LINES; + else if (strcmp(optarg, "gradient") == 0) + fill_pattern = FB_PATTERN_GRADIENT; else { printf("Invalid test pattern `%s'\n", optarg); printf("Run %s -h for help.\n", argv[0]); -- cgit v1.2.3