add 24bpp support
Now that cirrusdrmfb is enabled in QEMU /dev/fb0 exists
and ply-image runs and fails. Cirrus VGA has 24bpp pixels and
ply-image so far only supported 16bpp and 32bpp. This commit
adds support for 24bpp framebuffers. It also adds cirrus
device to KMS list.
BUG=chromium:289439
TEST=run smoke test
Change-Id: I0115021a17ce39c29316d453ab52a705084268e8
Signed-off-by: Dominik Behr <dbehr@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/169016
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
diff --git a/src/ply-frame-buffer.c b/src/ply-frame-buffer.c
index 5be9fff..6fbb163 100644
--- a/src/ply-frame-buffer.c
+++ b/src/ply-frame-buffer.c
@@ -524,42 +524,64 @@
* 3) In all other cases we copy line by line.
*/
if (buffer->bytes_per_pixel != sizeof(*data)) {
- uint16_t *src_16 = 0, *src_16_end;
int line;
- /* Handle the 16 bpp case (specifically RGB 565 case) */
- if (buffer->bytes_per_pixel != 2)
- return false;
+ if (buffer->bytes_per_pixel == 2) {
+ uint16_t *src_16 = 0, *src_16_end;
- /* Allocate temporary row pixel data storage for 16 bpp displays */
- src_16 = (uint16_t *) malloc(width * sizeof(*src_16));
+ /* Allocate temporary row pixel data storage for 16 bpp displays */
+ src_16 = (uint16_t *) malloc(width * sizeof(*src_16));
- if (!src_16)
- return false;
+ if (!src_16)
+ return false;
- src_16_end = src_16 + width;
+ src_16_end = src_16 + width;
- for (line = 0; line < lines; line++) {
- const uint32_t *src_32_temp;
- uint16_t *src_16_temp;
+ for (line = 0; line < lines; line++) {
+ const uint32_t *src_32_temp;
+ uint16_t *src_16_temp;
- for (src_32_temp = src, src_16_temp = src_16;
- src_16_temp != src_16_end;
- src_16_temp++) {
- uint32_t src_32_value = *src_32_temp++;
- *src_16_temp = (uint16_t)(
- ((src_32_value & 0x00F80000) >> 8) |
- ((src_32_value & 0x0000FC00) >> 5) |
- ((src_32_value & 0x000000F8) >> 3)
- );
+ for (src_32_temp = src, src_16_temp = src_16;
+ src_16_temp != src_16_end;
+ src_16_temp++) {
+ uint32_t src_32_value = *src_32_temp++;
+ *src_16_temp = (uint16_t)(
+ ((src_32_value & 0x00F80000) >> 8) |
+ ((src_32_value & 0x0000FC00) >> 5) |
+ ((src_32_value & 0x000000F8) >> 3)
+ );
+ }
+ memcpy(dst, src_16, width * buffer->bytes_per_pixel);
+
+ dst += buffer->row_stride * buffer->bytes_per_pixel;
+ src += area->width;
}
- memcpy(dst, src_16, width * buffer->bytes_per_pixel);
- dst += buffer->row_stride * buffer->bytes_per_pixel;
- src += area->width;
+ free(src_16);
+ } else if (buffer->bytes_per_pixel == 3) {
+ uint8_t *src_8 = (uint8_t *) malloc(width * sizeof(uint8_t) * 3);
+
+ if (!src_8)
+ return false;
+
+ for (line = 0; line < lines; line++) {
+ int col;
+ uint8_t *s = src_8;
+ for (col = 0; col < width; col++) {
+ *s++ = (uint8_t)(src[col] & 0xFF); // blue
+ *s++ = (uint8_t)((src[col] >> 8) & 0xFF); // green
+ *s++ = (uint8_t)((src[col] >> 16) & 0xFF); // red
+ }
+
+ memcpy(dst, src_8, width * buffer->bytes_per_pixel);
+
+ dst += buffer->row_stride * buffer->bytes_per_pixel;
+ src += area->width;
+ }
+ free(src_8);
+ } else {
+ return false;
}
-
- free(src_16);
} else if (width == area->width && width == buffer->row_stride) {
memcpy(dst, src, width * lines * sizeof(*data));
} else {
@@ -606,6 +628,22 @@
}
break;
}
+ case 3: {
+ uint8_t* ptr = (uint8_t*) buffer->map_address;
+ uint8_t* curr_ptr;
+ uint8_t b0 = (uint8_t)(fb_clear_color & 0xFF);
+ uint8_t b1 = (uint8_t)((fb_clear_color >> 8) & 0xFF);
+ uint8_t b2 = (uint8_t)((fb_clear_color >> 16) & 0xFF);
+ for (j = 0; j < fb_height; j++) {
+ curr_ptr = ptr + j * fb_stride * 3;
+ for (i = 0; i < fb_width; i++) {
+ *curr_ptr++ = b0;
+ *curr_ptr++ = b1;
+ *curr_ptr++ = b2;
+ }
+ }
+ break;
+ }
case 2: {
uint16_t* ptr = (uint16_t*) buffer->map_address;
uint16_t* curr_ptr;
diff --git a/src/ply-kms.c b/src/ply-kms.c
index 809514d..855dfbd 100644
--- a/src/ply-kms.c
+++ b/src/ply-kms.c
@@ -26,7 +26,7 @@
#include "ply-utils.h"
int ply_kms_open() {
- const char *kModuleList[] = { "i915", "exynos" };
+ const char *kModuleList[] = { "i915", "exynos", "cirrus" };
int fd = -1;
int i;