summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-24 12:49:39 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-24 12:49:39 +0200
commitd868b3e8b3b5bae6a4db7bab640e340a9ec8f6c7 (patch)
tree374d7171f908bdfa5492908ef1b6b3ccc77faf93
parent618b53d4b49febefa56e8161bececa88d3ebc630 (diff)
Add alpha blending supportHEADmaster
For formats that include an alpha channel, the -a/--alpha command line argument can be used to specify an alpha value for the test pattern. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--fbdev.c119
1 files changed, 71 insertions, 48 deletions
diff --git a/fbdev.c b/fbdev.c
index a94751b..412d0e7 100644
--- a/fbdev.c
+++ b/fbdev.c
@@ -48,6 +48,7 @@ struct device {
struct fb_bitfield red;
struct fb_bitfield green;
struct fb_bitfield blue;
+ struct fb_bitfield alpha;
unsigned int fourcc;
};
@@ -577,10 +578,12 @@ static int fb_update_info(struct device *dev)
memset(&dev->red, 0, sizeof dev->red);
memset(&dev->green, 0, sizeof dev->green);
memset(&dev->blue, 0, sizeof dev->blue);
+ memset(&dev->alpha, 0, sizeof dev->alpha);
} else {
dev->red = var_info.red;
dev->green = var_info.green;
dev->blue = var_info.blue;
+ dev->alpha = var_info.transp;
}
return 0;
@@ -1132,37 +1135,44 @@ fb_fill_smpte_rgb24(struct device *dev, unsigned int xoffset,
}
}
+#define FB_MAKE_RGBA(dev, r, g, b, a) \
+ ((((r) >> (8 - (dev)->red.length)) << (dev)->red.offset) | \
+ (((g) >> (8 - (dev)->green.length)) << (dev)->green.offset) | \
+ (((b) >> (8 - (dev)->blue.length)) << (dev)->blue.offset) | \
+ (((a) >> (8 - (dev)->alpha.length)) << (dev)->alpha.offset))
+
static void
fb_fill_smpte_rgb32(struct device *dev, unsigned int xoffset,
- unsigned int yoffset, unsigned int xres, unsigned int yres)
+ unsigned int yoffset, unsigned int xres, unsigned int yres,
+ uint8_t alpha)
{
const uint32_t colors_top[] = {
- FB_MAKE_RGB(dev, 192, 192, 192), /* grey */
- FB_MAKE_RGB(dev, 192, 192, 0), /* yellow */
- FB_MAKE_RGB(dev, 0, 192, 192), /* cyan */
- FB_MAKE_RGB(dev, 0, 192, 0), /* green */
- FB_MAKE_RGB(dev, 192, 0, 192), /* magenta */
- FB_MAKE_RGB(dev, 192, 0, 0), /* red */
- FB_MAKE_RGB(dev, 0, 0, 192), /* blue */
+ FB_MAKE_RGBA(dev, 192, 192, 192, alpha), /* grey */
+ FB_MAKE_RGBA(dev, 192, 192, 0, alpha), /* yellow */
+ FB_MAKE_RGBA(dev, 0, 192, 192, alpha), /* cyan */
+ FB_MAKE_RGBA(dev, 0, 192, 0, alpha), /* green */
+ FB_MAKE_RGBA(dev, 192, 0, 192, alpha), /* magenta */
+ FB_MAKE_RGBA(dev, 192, 0, 0, alpha), /* red */
+ FB_MAKE_RGBA(dev, 0, 0, 192, alpha), /* blue */
};
const uint32_t colors_middle[] = {
- FB_MAKE_RGB(dev, 0, 0, 192), /* blue */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 192, 0, 192), /* magenta */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 0, 192, 192), /* cyan */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 192, 192, 192), /* grey */
+ FB_MAKE_RGBA(dev, 0, 0, 192, alpha), /* blue */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 192, 0, 192, alpha), /* magenta */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 0, 192, 192, alpha), /* cyan */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 192, 192, 192, alpha), /* grey */
};
const uint32_t colors_bottom[] = {
- FB_MAKE_RGB(dev, 0, 33, 76), /* in-phase */
- FB_MAKE_RGB(dev, 255, 255, 255), /* super white */
- FB_MAKE_RGB(dev, 50, 0, 106), /* quadrature */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 9, 9, 9), /* 3.5% */
- FB_MAKE_RGB(dev, 19, 19, 19), /* 7.5% */
- FB_MAKE_RGB(dev, 29, 29, 29), /* 11.5% */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
+ FB_MAKE_RGBA(dev, 0, 33, 76, alpha), /* in-phase */
+ FB_MAKE_RGBA(dev, 255, 255, 255, alpha), /* super white */
+ FB_MAKE_RGBA(dev, 50, 0, 106, alpha), /* quadrature */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 9, 9, 9, alpha), /* 3.5% */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* 7.5% */
+ FB_MAKE_RGBA(dev, 29, 29, 29, alpha), /* 11.5% */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
};
void *mem = dev->mem + dev->fix_info.line_length * yoffset
+ xoffset * dev->var_info.bits_per_pixel / 8;
@@ -1202,13 +1212,14 @@ fb_fill_smpte_rgb32(struct device *dev, unsigned int xoffset,
* @yoffset: Vertical offset, in pixels
* @xres: Horizontal size, in pixels
* @yres: Vertical size, in pixels
+ * @alpha: Transparency value (only for formats that support alpha values)
*
* Fill the display (when mode is FB_FILL_DISPLAY) or virtual frame buffer area
* (when mode is FB_FILL_VIRTUAL) with an SMPTE color bars pattern.
*/
static void
fb_fill_smpte(struct device *dev, unsigned int xoffset, unsigned int yoffset,
- unsigned int xres, unsigned int yres)
+ unsigned int xres, unsigned int yres, uint8_t alpha)
{
switch (dev->fourcc) {
case V4L2_PIX_FMT_NV12:
@@ -1236,7 +1247,7 @@ fb_fill_smpte(struct device *dev, unsigned int xoffset, unsigned int yoffset,
return fb_fill_smpte_rgb24(dev, xoffset, yoffset, xres, yres);
case V4L2_PIX_FMT_BGR32:
case V4L2_PIX_FMT_RGB32:
- return fb_fill_smpte_rgb32(dev, xoffset, yoffset, xres, yres);
+ return fb_fill_smpte_rgb32(dev, xoffset, yoffset, xres, yres, alpha);
}
}
@@ -1358,17 +1369,18 @@ fb_fill_lines_rgb24(struct device *dev, unsigned int xoffset,
static void
fb_fill_lines_rgb32(struct device *dev, unsigned int xoffset,
- unsigned int yoffset, unsigned int xres, unsigned int yres)
+ unsigned int yoffset, unsigned int xres, unsigned int yres,
+ uint8_t alpha)
{
const uint32_t colors[] = {
- FB_MAKE_RGB(dev, 192, 192, 0), /* yellow */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 0, 192, 0), /* green */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 192, 0, 0), /* red */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
- FB_MAKE_RGB(dev, 0, 0, 192), /* blue */
- FB_MAKE_RGB(dev, 19, 19, 19), /* black */
+ FB_MAKE_RGBA(dev, 192, 192, 0, alpha), /* yellow */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 0, 192, 0, alpha), /* green */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 192, 0, 0, alpha), /* red */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
+ FB_MAKE_RGBA(dev, 0, 0, 192, alpha), /* blue */
+ FB_MAKE_RGBA(dev, 19, 19, 19, alpha), /* black */
};
void *mem = dev->mem + dev->fix_info.line_length * yoffset
+ xoffset * dev->var_info.bits_per_pixel / 8;
@@ -1395,13 +1407,14 @@ fb_fill_lines_rgb32(struct device *dev, unsigned int xoffset,
* @yoffset: Vertical offset, in pixels
* @xres: Horizontal size, in pixels
* @yres: Vertical size, in pixels
+ * @alpha: Transparency value (only for formats that support alpha values)
*
* Fill the display (when mode is FB_FILL_DISPLAY) or virtual frame buffer area
* (when mode is FB_FILL_VIRTUAL) with a lines pattern.
*/
static void
fb_fill_lines(struct device *dev, unsigned int xoffset, unsigned int yoffset,
- unsigned int xres, unsigned int yres)
+ unsigned int xres, unsigned int yres, uint8_t alpha)
{
switch (dev->fourcc) {
case V4L2_PIX_FMT_NV12:
@@ -1429,7 +1442,7 @@ fb_fill_lines(struct device *dev, unsigned int xoffset, unsigned int yoffset,
return fb_fill_lines_rgb24(dev, xoffset, yoffset, xres, yres);
case V4L2_PIX_FMT_BGR32:
case V4L2_PIX_FMT_RGB32:
- return fb_fill_lines_rgb32(dev, xoffset, yoffset, xres, yres);
+ return fb_fill_lines_rgb32(dev, xoffset, yoffset, xres, yres, alpha);
}
}
@@ -1548,7 +1561,8 @@ fb_fill_gradient_rgb24(struct device *dev, unsigned int xoffset,
static void
fb_fill_gradient_rgb32(struct device *dev, unsigned int xoffset,
- unsigned int yoffset, unsigned int xres, unsigned int yres)
+ unsigned int yoffset, unsigned int xres, unsigned int yres,
+ uint8_t alpha)
{
void *mem = dev->mem + dev->fix_info.line_length * yoffset
+ xoffset * dev->var_info.bits_per_pixel / 8;
@@ -1557,17 +1571,17 @@ fb_fill_gradient_rgb32(struct device *dev, unsigned int xoffset,
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);
+ ((uint32_t *)mem)[x] = FB_MAKE_RGBA(dev, 255 * x / xres, 0, 0, alpha);
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);
+ ((uint32_t *)mem)[x] = FB_MAKE_RGBA(dev, 0, 255 * x / xres, 0, alpha);
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);
+ ((uint32_t *)mem)[x] = FB_MAKE_RGBA(dev, 0, 0, 255 * x / xres, alpha);
mem += dev->fix_info.line_length;
}
}
@@ -1579,13 +1593,14 @@ fb_fill_gradient_rgb32(struct device *dev, unsigned int xoffset,
* @yoffset: Vertical offset, in pixels
* @xres: Horizontal size, in pixels
* @yres: Vertical size, in pixels
+ * @alpha: Transparency value (only for formats that support alpha values)
*
* 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)
+ unsigned int xres, unsigned int yres, uint8_t alpha)
{
switch (dev->fourcc) {
case V4L2_PIX_FMT_NV12:
@@ -1613,7 +1628,7 @@ fb_fill_gradient(struct device *dev, unsigned int xoffset, unsigned int yoffset,
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);
+ return fb_fill_gradient_rgb32(dev, xoffset, yoffset, xres, yres, alpha);
}
}
@@ -1622,13 +1637,15 @@ fb_fill_gradient(struct device *dev, unsigned int xoffset, unsigned int yoffset,
* @dev: FB device
* @mode: Fill mode
* @pattern: Test pattern
+ * @alpha: Transparency value (only for formats that support alpha values)
*
* Fill the display (when mode is FB_FILL_DISPLAY) or virtual frame buffer area
* (when mode is FB_FILL_VIRTUAL) with the test pattern specified by the pattern
* parameter. Only RGB16, RGB24 and RGB32 on true color visuals are supported.
*/
static void
-fb_fill(struct device *dev, enum fb_fill_mode mode, enum fb_fill_pattern pattern)
+fb_fill(struct device *dev, enum fb_fill_mode mode,
+ enum fb_fill_pattern pattern, uint8_t alpha)
{
unsigned int xoffset, yoffset;
unsigned int xres, yres;
@@ -1674,15 +1691,15 @@ fb_fill(struct device *dev, enum fb_fill_mode mode, enum fb_fill_pattern pattern
switch (pattern) {
case FB_PATTERN_SMPTE:
printf("Filling frame buffer with SMPTE test pattern\n");
- return fb_fill_smpte(dev, xoffset, yoffset, xres, yres);
+ return fb_fill_smpte(dev, xoffset, yoffset, xres, yres, alpha);
case FB_PATTERN_LINES:
printf("Filling frame buffer with lines test pattern\n");
- return fb_fill_lines(dev, xoffset, yoffset, xres, yres);
+ return fb_fill_lines(dev, xoffset, yoffset, xres, yres, alpha);
case FB_PATTERN_GRADIENT:
printf("Filling frame buffer with gradient test pattern\n");
- return fb_fill_gradient(dev, xoffset, yoffset, xres, yres);
+ return fb_fill_gradient(dev, xoffset, yoffset, xres, yres, alpha);
default:
printf("Error: unsupported test pattern %u.\n", pattern);
@@ -1700,6 +1717,7 @@ static void usage(const char *argv0)
printf("Usage: %s [options] device\n", argv0);
printf("Supported options:\n");
+ printf("-a, --alpha value Transparency value for test patterns\n");
printf("-b, --blank mode Set blanking mode\n");
printf("-f, --fill[=mode] Fill the frame buffer with a test pattern\n");
printf("-F, --format fourcc Set the frame buffer format\n");
@@ -1730,6 +1748,7 @@ static void usage(const char *argv0)
}
static struct option opts[] = {
+ {"alpha", 1, 0, 'a'},
{"blank", 1, 0, 'b'},
{"fill", 2, 0, 'f'},
{"format", 1, 0, 'F'},
@@ -1836,6 +1855,7 @@ int main(int argc, char *argv[])
enum fb_fill_mode fill_mode = FB_FILL_NONE;
enum fb_fill_pattern fill_pattern = FB_PATTERN_SMPTE;
+ uint8_t alpha = 255;
bool do_format = false;
unsigned int fourcc = 0;
@@ -1856,9 +1876,12 @@ int main(int argc, char *argv[])
int c;
opterr = 0;
- while ((c = getopt_long(argc, argv, "b:f::F:hp:P:r:v:w::", opts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "a:b:f::F:hp:P:r:v:w::", opts, NULL)) != -1) {
switch (c) {
+ case 'a':
+ alpha = atoi(optarg);
+ break;
case 'b':
do_blank = true;
if (fb_blank_parse(optarg, &blank) < 0) {
@@ -1959,7 +1982,7 @@ int main(int argc, char *argv[])
fb_set_resolution(&dev, xres, yres, xres_virtual, yres_virtual);
if (fill_mode != FB_FILL_NONE)
- fb_fill(&dev, fill_mode, fill_pattern);
+ fb_fill(&dev, fill_mode, fill_pattern, alpha);
if (do_pan)
fb_pan(&dev, pan_x, pan_y);