blob: 594969dc8fb8dc35a1612cb9e88572e60fc778e0 [file] [log] [blame]
#include "asrfb.h"
#include "lcd_fns.h"
int get_format_plane(unsigned int format)
{
int plane = 1;
switch (format) {
case LCD_FORMAT_RGB565:
case LCD_FORMAT_RGB1555:
case LCD_FORMAT_RGB888_PACKED:
case LCD_FORMAT_RGB888_UNPACKED:
case LCD_FORMAT_RGBA888:
case LCD_FORMAT_RGB888A:
case LCD_FORMAT_YUV422_PACKED:
plane = 1;
break;
case LCD_FORMAT_YUV422_PLANAR:
case LCD_FORMAT_YUV420_PLANAR:
plane = 3;
break;
case LCD_FORMAT_YUV420_SEMI:
plane = 2;
break;
}
return plane;
}
int get_format_bpp(unsigned int format)
{
int bpp = 0;
switch (format) {
case LCD_FORMAT_RGB565:
case LCD_FORMAT_RGB1555:
bpp = 16;
break;
case LCD_FORMAT_RGB888_PACKED:
bpp = 24;
break;
case LCD_FORMAT_RGB888_UNPACKED:
case LCD_FORMAT_RGBA888:
case LCD_FORMAT_RGB888A:
bpp = 32;
break;
case LCD_FORMAT_YUV422_PACKED:
case LCD_FORMAT_YUV422_PLANAR:
bpp = 16;
break;
case LCD_FORMAT_YUV420_PLANAR:
case LCD_FORMAT_YUV420_SEMI:
bpp = 12;
break;
}
return bpp;
}
int is_format_yuv(unsigned int format)
{
int is_yuv = 0;
switch (format) {
case LCD_FORMAT_RGB565:
case LCD_FORMAT_RGB1555:
case LCD_FORMAT_RGB888_PACKED:
case LCD_FORMAT_RGB888_UNPACKED:
case LCD_FORMAT_RGBA888:
case LCD_FORMAT_RGB888A:
is_yuv = 0;
break;
case LCD_FORMAT_YUV422_PACKED:
case LCD_FORMAT_YUV422_PLANAR:
case LCD_FORMAT_YUV420_PLANAR:
case LCD_FORMAT_YUV420_SEMI:
is_yuv = 1;
break;
}
return is_yuv;
}
int get_uv_height_dividor(unsigned int format)
{
int dividor = 0;
switch (format) {
case LCD_FORMAT_RGB565:
case LCD_FORMAT_RGB1555:
case LCD_FORMAT_RGB888_PACKED:
case LCD_FORMAT_RGB888_UNPACKED:
case LCD_FORMAT_RGBA888:
case LCD_FORMAT_RGB888A:
dividor = 0;
break;
case LCD_FORMAT_YUV422_PACKED:
case LCD_FORMAT_YUV422_PLANAR:
dividor = 1;
break;
case LCD_FORMAT_YUV420_PLANAR:
case LCD_FORMAT_YUV420_SEMI:
dividor = 2;
break;
}
return dividor;
}
static int get_layer_rgb_data(int position_x, int position_y, int is_first_layer,
struct s_compose_layer_setting *layer, unsigned int *rgb_data, unsigned char *alpha)
{
unsigned int data;
unsigned char al_data;
unsigned char *psrc8 = NULL;
unsigned int *psrc32 = NULL;
if (layer->format == LCD_FORMAT_RGB888_PACKED) {
psrc8 = (unsigned char *)(layer->addr + position_y * layer->stride + position_x * 3);
data = (*psrc8++) & 0xFF; /*b*/
data = (((*psrc8++) & 0xFF) << 8) | data; /*g*/
data = (((*psrc8++) & 0xFF) << 16) | data; /*r*/
if (1 != is_first_layer) {
if (layer->alpha_sel != LCD_ALPHA_LAYER) {
printf("%s: Invalid alpha setting!\n", __func__);
return -1;
}
al_data = layer->layer_alpha;
}
else {
al_data = 0;
}
}
else if (layer->format == LCD_FORMAT_RGB888_UNPACKED) {
psrc32 = (unsigned int *)(layer->addr + position_y * layer->stride + position_x * 4);
data = (*psrc32++) & 0xFFFFFF;
if (1 != is_first_layer) {
if (layer->alpha_sel != LCD_ALPHA_LAYER) {
printf("%s: Invalid alpha setting!\n", __func__);
return -1;
}
al_data = layer->layer_alpha;
}
else {
al_data = 0;
}
}
else if (layer->format == LCD_FORMAT_RGBA888) {
psrc32 = (unsigned int *)(layer->addr + position_y * layer->stride + position_x * 4);
psrc8 = (unsigned char *)(layer->addr + position_y * layer->stride + position_x * 4 + 3);
data = (*psrc32) & 0xFFFFFF;
if ((1 != is_first_layer) && (layer->alpha_sel == LCD_ALPHA_LAYER)) {
al_data = layer->layer_alpha;
}
else {
al_data = *psrc8;
}
}
else if (layer->format == LCD_FORMAT_RGB888A) {
psrc32 = (unsigned int *)(layer->addr + position_y * layer->stride + position_x * 4);
psrc8 = (unsigned char *)(layer->addr + position_y * layer->stride + position_x * 4);
data = ((*psrc32++) >> 8) & 0xFFFFFF;
if ((1 != is_first_layer) && (layer->alpha_sel == LCD_ALPHA_LAYER)) {
al_data = layer->layer_alpha;
}
else {
al_data = *psrc8;
}
}
else {
printf("%s: Invalid layer format (0x%x)!\n", __func__, layer->format);
return -1;
}
*rgb_data = data;
*alpha = al_data;
return 0;
}
static unsigned int do_compose(unsigned int *src1, unsigned int *src2, unsigned char alpha1,
unsigned char alpha2, unsigned char alpha_mode, unsigned char dest_format, unsigned int *dest_rgb,
unsigned char *dest_alpha, int log)
{
unsigned int result = 0;
unsigned char r1, g1, b1;
unsigned char r2, g2, b2;
unsigned char r3, g3, b3;
unsigned int r3_temp, g3_temp, b3_temp;
unsigned int alpha_temp;
unsigned char *pbyte;
if (1 == log)
printf("%s: a1 = %d, a2 = %d\n", __func__, (int)alpha1, (int)alpha2);
if (NULL == src2) {
*dest_rgb = (*src1) & 0xFFFFFF;
if (dest_format == LCD_FORMAT_RGB888_PACKED) {
result = (*src1) & 0xFFFFFF;
}
else if (dest_format == LCD_FORMAT_RGBA888) {
result = (alpha1 << 24) | ((*src1) & 0xFFFFFF);
}
else if (dest_format == LCD_FORMAT_RGB888A) {
result = ((*src1 << 8) & 0xFFFFFF00) | alpha1;
}
else if (dest_format == LCD_FORMAT_RGB888_UNPACKED) {
result = (*src1) & 0xFFFFFF;
}
else {
printf("%s: Invalid dest format (0x%x)!\n", __func__, dest_format);
}
return result;
}
pbyte = (unsigned char *)src1;
b1 = *pbyte++;
g1 = *pbyte++;
r1 = *pbyte++;
pbyte = (unsigned char *)src2;
b2 = *pbyte++;
g2 = *pbyte++;
r2 = *pbyte++;
if (1 == log)
printf("%s: r1 = %d, g1 = %d, b1 = %d, r2 = %d, g2 = %d, b2 = %d\n", __func__,
(int)r1, (int)g1, (int)b1, (int)r2, (int)g2, (int)b2);
if (alpha_mode == LCD_ALPHA_MODE_NORMAL) {
r3_temp = (r2 * alpha2 + r1 * (255 - alpha2)) / 255;
g3_temp = (g2 * alpha2 + g1 * (255 - alpha2)) / 255;
b3_temp = (b2 * alpha2 + b1 * (255 - alpha2)) / 255;
alpha_temp = alpha1 + alpha2 - alpha1 * alpha2 / 255;
}
else if (alpha_mode == LCD_ALPHA_MODE_PRE) {
r3_temp = (r2 * 255 + r1 * (255 - alpha2)) / 255;
g3_temp = (g2 * 255 + g1 * (255 - alpha2)) / 255;
b3_temp = (b2 * 255 + b1 * (255 - alpha2)) / 255;
alpha_temp = alpha1 + alpha2 - alpha1 * alpha2 / 255;
}
else {
r3_temp = (r2 * 255 + r1 * alpha2) / 255;
g3_temp = (g2 * 255 + g1 * alpha2) / 255;
b3_temp = (b2 * 255 + b1 * alpha2) / 255;
alpha_temp = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (1 == log) {
printf("%s: r3_temp = %d, g3_temp = %d, b3_temp = %d\n", __func__, r3_temp,
g3_temp, b3_temp);
}
}
r3 = (r3_temp > 255) ? 255 : r3_temp;
g3 = (g3_temp > 255) ? 255 : g3_temp;
b3 = (b3_temp > 255) ? 255 : b3_temp;
*dest_alpha = (alpha_temp > 255) ? 255 : alpha_temp;
if (1 == log) {
printf("%s: r3 = %d, g3 = %d, b3 = %d, alpha= %d\n", __func__, (int)r3, (int)g3,
(int)b3, (int)*dest_alpha);
}
*dest_rgb = (r3 << 16) | (g3 << 8) | b3;
if (dest_format == LCD_FORMAT_RGB888_PACKED) {
result = (r3 << 16) | (g3 << 8) | b3;
}
else if (dest_format == LCD_FORMAT_RGBA888) {
result = (*dest_alpha << 24) | (r3 << 16) | (g3 << 8) | b3;
}
else if (dest_format == LCD_FORMAT_RGB888A) {
result = (r3 << 24) | (g3 << 16) | (b3 << 8) | *dest_alpha;
}
else if (dest_format == LCD_FORMAT_RGB888_UNPACKED) {
result = (r3 << 16) | (g3 << 8) | b3;
}
if (1 == log) {
printf("%s: result = 0x%x\n", __func__, result);
}
return result;
}
static void dump_compose_setting(struct s_compose_setting *compose_setting)
{
}
static void draw_pure_color(unsigned int addr, unsigned int width,
unsigned int height, unsigned int color, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned int *pdata = (unsigned int *)addr;
unsigned int porch = 0;
unsigned char *pbyte = NULL;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
*pdata = color;
pdata++;
}
pbyte = (unsigned char *)pdata;
pbyte += porch;
pdata = (unsigned int *)pbyte;
}
}
static void draw_hcb(unsigned int addr, unsigned int width,
unsigned int height, unsigned int cb_num, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned int *pdata = (unsigned int *)addr;
unsigned int data[5] = {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00FFFFFF, 0x00000000};
unsigned int cur_index = 0;
unsigned int line_num;
unsigned int porch = 0;
unsigned char *pbyte = NULL;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
line_num = height / cb_num;
cur_index = 0;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
*pdata = data[cur_index];
pdata++;
}
if ((i + 1) % line_num == 0) {
cur_index++;
if (cur_index == 5) {
cur_index = 0;
}
}
pbyte = (unsigned char *)pdata;
pbyte += porch;
pdata = (unsigned int *)pbyte;
}
}
static void draw_vcb(unsigned int addr, unsigned int width,
unsigned int height, unsigned int cb_num, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned int *pdata = (unsigned int *)addr;
unsigned int data[5] = { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00FFFFFF, 0x00000000 };
unsigned int cur_index = 0;
unsigned int colum_num;
unsigned int porch = 0;
unsigned char *pbyte = NULL;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
colum_num = width / cb_num;
for (i = 0; i < height; i++) {
cur_index = 0;
for (j = 0; j < width; j++) {
*pdata = data[cur_index];
pdata++;
if ((j + 1) % colum_num == 0) {
cur_index++;
if (cur_index == 5) {
cur_index = 0;
}
}
}
pbyte = (unsigned char *)pdata;
pbyte += porch;
pdata = (unsigned int *)pbyte;
}
}
static void draw_line(unsigned int addr, unsigned int width,
unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned int *pdata = (unsigned int *)addr;
unsigned int data[3] = { 0x00FF0000, 0x0000FF00, 0x000000FF };
unsigned int cur_index = 0;
unsigned int porch = 0;
unsigned char *pbyte = NULL;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
cur_index = 0;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
*pdata = data[cur_index];
pdata++;
}
cur_index++;
cur_index = cur_index % 3;
pbyte = (unsigned char *)pdata;
pbyte += porch;
pdata = (unsigned int *)pbyte;
}
}
static void draw_grey_level(unsigned int addr, unsigned int width,
unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned int *pdata = (unsigned int *)addr;
unsigned int porch = 0;
unsigned char cur_value = 0;
unsigned char *pbyte = NULL;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
*pdata++ = cur_value | cur_value << 8 | cur_value << 16 /*| (0xFF << 24)*/;
}
if ((i % 4 == 0) && (i > 0)) {
cur_value += 3;
cur_value = cur_value % 6;
}
pbyte = (unsigned char *)pdata;
pbyte += porch;
pdata = (unsigned int *)pbyte;
}
}
static void prepare_argb8888_image(unsigned int addr, unsigned int pattern,
unsigned int width, unsigned int height, unsigned int align, unsigned int *stride)
{
switch (pattern) {
case IMG_PATTERN_RED:
draw_pure_color(addr, width, height, 0xFF0000, align, stride);
break;
case IMG_PATTERN_GREEN:
draw_pure_color(addr, width, height, 0xFF00, align, stride);
break;
case IMG_PATTERN_BLUE:
draw_pure_color(addr, width, height, 0xFF, align, stride);
break;
case IMG_PATTERN_WHITE:
draw_pure_color(addr, width, height, 0xFFFFFF, align, stride);
break;
case IMG_PATTERN_HCB_5:
draw_hcb(addr, width, height, 5, align, stride);
break;
case IMG_PATTERN_HCB_2:
draw_hcb(addr, width, height, 2, align, stride);
break;
case IMG_PATTERN_VCB_5:
draw_vcb(addr, width, height, 5, align, stride);
break;
case IMG_PATTERN_VCB_2:
draw_vcb(addr, width, height, 2, align, stride);
break;
case IMG_PATTERN_LINE:
draw_line(addr, width, height, align, stride);
break;
case IMG_PATTERN_GREY_LEVEL:
draw_grey_level(addr, width, height, align, stride);
break;
}
}
static void argb8888_to_rgb888(unsigned int src_addr, unsigned int dest_addr,
unsigned int width, unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned char *psrc, *pdest;
unsigned int porch;
*stride = WIDE_ALIGN(width * 3, align);
porch = *stride - width * 3;
psrc = (unsigned char *)src_addr;
pdest = (unsigned char *)dest_addr;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
*pdest++ = *psrc++; /*b*/
*pdest++ = *psrc++; /*g*/
*pdest++ = *psrc++; /*r*/
psrc++; /*alpha*/
}
pdest += porch;
}
}
static void argb8888_to_rgba8888(unsigned int src_addr, unsigned int dest_addr,
unsigned int width, unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned char *psrc, *pdest;
unsigned int porch;
unsigned char r, g, b, a;
*stride = WIDE_ALIGN(width * 4, align);
porch = *stride - width * 4;
psrc = (unsigned char *)src_addr;
pdest = (unsigned char *)dest_addr;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
b = *psrc++; /*b*/
g = *psrc++; /*g*/
r = *psrc++; /*r*/
a = *psrc++; /*alpha*/
*pdest++ = a;
*pdest++ = b;
*pdest++ = g;
*pdest++ = r;
}
pdest += porch;
}
}
static void argb8888_to_rgb565(unsigned int src_addr, unsigned int dest_addr,
unsigned int width, unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned char *psrc;
unsigned short *pdest;
unsigned char r, g, b;
unsigned char nr, ng, nb;
unsigned int porch;
*stride = WIDE_ALIGN(width * 2, align);
porch = *stride - width * 2;
psrc = (unsigned char *)src_addr;
pdest = (unsigned short *)dest_addr;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
b = *psrc++; /*b*/
g = *psrc++; /*g*/
r = *psrc++; /*r*/
psrc++; /*alpha*/
nr = r * 31 / 255;
ng = g * 63 / 255;
nb = b * 31 / 255;
*pdest++ = ((nr & 0x1F) << 11) |
((ng & 0x3F) << 5) | (nb & 0x1F);
}
pdest += (porch >> 1);
}
}
static void argb8888_to_rgb1555(unsigned int src_addr, unsigned int dest_addr,
unsigned int width, unsigned int height, unsigned int align, unsigned int *stride)
{
unsigned int i, j;
unsigned char *psrc;
unsigned short *pdest;
unsigned char r, g, b;
unsigned int porch;
*stride = WIDE_ALIGN(width * 2, align);
porch = *stride - width * 2;
psrc = (unsigned char *)src_addr;
pdest = (unsigned short *)dest_addr;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
b = *psrc++; /*b*/
g = *psrc++; /*g*/
r = *psrc++; /*r*/
psrc++; /*alpha*/
*pdest++ = ((r & 0x1F) << 10) |
((g & 0x1F) << 5) | (b & 0x1F);
}
pdest += (porch >> 1);
}
}
static void argb8888_to_yuv420_p2(unsigned int src_addr, unsigned int dest_addr_p1,
unsigned int *dest_addr_p2, unsigned int width, unsigned int height,
unsigned int align, unsigned int *stride_p1, unsigned int *stride_p2)
{
unsigned int i, j;
unsigned char *psrc, *pdest_p1, *pdest_p2;
unsigned int r, g, b;
unsigned char y, u, v;
unsigned int porch_p1, porch_p2;
unsigned int addr_p2;
*stride_p1 = WIDE_ALIGN(width, align);
*stride_p2 = WIDE_ALIGN(width, align);
porch_p1 = *stride_p1 - width;
porch_p2 = *stride_p2 - width;
addr_p2 = dest_addr_p1 + (*stride_p1) * height;
*dest_addr_p2 = addr_p2;
psrc = (unsigned char *)src_addr;
pdest_p1 = (unsigned char *)dest_addr_p1;
pdest_p2 = (unsigned char *)addr_p2;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i += 2) {
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
if (0 == j % 2) {
*pdest_p2++ = u;
}
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
if (0 == j % 2) {
*pdest_p2++ = v;
}
}
pdest_p1 += porch_p1;
if (0 == j % 2) {
pdest_p2 += porch_p2;
}
}
}
static void argb8888_to_yuv420_p3(unsigned int src_addr, unsigned int dest_addr_p1,
unsigned int *dest_addr_p2, unsigned int *dest_addr_p3,
unsigned int width, unsigned int height, unsigned int align,
unsigned int *stride_p1, unsigned int *stride_p2, unsigned int *stride_p3)
{
unsigned int i, j;
unsigned char *psrc, *pdest_p1, *pdest_p2, *pdest_p3;
unsigned int r, g, b;
unsigned char y, u, v;
unsigned int porch_p1, porch_p2, porch_p3;
unsigned int addr_p2, addr_p3;
*stride_p1 = WIDE_ALIGN(width, align);
*stride_p2 = WIDE_ALIGN(width / 2, align);
*stride_p3 = WIDE_ALIGN(width / 2, align);
porch_p1 = *stride_p1 - width;
porch_p2 = *stride_p2 - width / 2;
porch_p3 = *stride_p3 - width / 2;
addr_p2 = dest_addr_p1 + (*stride_p1) * height;
addr_p3 = addr_p2 + (*stride_p2) * height / 2;
*dest_addr_p2 = addr_p2;
*dest_addr_p3 = addr_p3;
psrc = (unsigned char *)src_addr;
pdest_p1 = (unsigned char *)dest_addr_p1;
pdest_p2 = (unsigned char *)addr_p2;
pdest_p3 = (unsigned char *)addr_p3;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i += 2) {
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
if (0 == j % 2) {
*pdest_p2++ = u;
}
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
if (0 == j % 2) {
*pdest_p3++ = v;
}
}
pdest_p1 += porch_p1;
if (0 == j % 2) {
pdest_p2 += porch_p2;
pdest_p3 += porch_p3;
}
}
}
static void argb8888_to_yuv422_p3(unsigned int src_addr, unsigned int dest_addr_p1,
unsigned int *dest_addr_p2, unsigned int *dest_addr_p3,
unsigned int width, unsigned int height, unsigned int align,
unsigned int *stride_p1, unsigned int *stride_p2, unsigned int *stride_p3)
{
unsigned int i, j;
unsigned char *psrc, *pdest_p1, *pdest_p2, *pdest_p3;
unsigned int r, g, b;
unsigned char y, u, v;
unsigned int porch_p1, porch_p2, porch_p3;
unsigned int addr_p2, addr_p3;
*stride_p1 = WIDE_ALIGN(width, align);
*stride_p2 = WIDE_ALIGN(width / 2, align);
*stride_p3 = WIDE_ALIGN(width / 2, align);
porch_p1 = *stride_p1 - width;
porch_p2 = *stride_p2 - width / 2;
porch_p3 = *stride_p3 - width / 2;
addr_p2 = dest_addr_p1 + (*stride_p1) * height;
addr_p3 = addr_p2 + (*stride_p2) * height;
*dest_addr_p2 = addr_p2;
*dest_addr_p3 = addr_p3;
psrc = (unsigned char *)src_addr;
pdest_p1 = (unsigned char *)dest_addr_p1;
pdest_p2 = (unsigned char *)addr_p2;
pdest_p3 = (unsigned char *)addr_p3;
for (j = 0; j < height; j++) {
for (i = 0; i < width; i += 2) {
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
*pdest_p2++ = u;
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = y;
*pdest_p3++ = v;
}
pdest_p1 += porch_p1;
pdest_p2 += porch_p2;
pdest_p3 += porch_p3;
}
}
static void argb8888_to_yuv422_p1(unsigned int src_addr, unsigned int dest_addr_p1,
unsigned int width, unsigned int height, unsigned int align,
unsigned int *stride_p1)
{
unsigned int i, j;
unsigned char *psrc, *pdest_p1;
unsigned int r, g, b;
unsigned char y, u, v;
unsigned int porch_p1;
*stride_p1 = WIDE_ALIGN(width * 2, align);
porch_p1 = *stride_p1 - width * 2;
psrc = (unsigned char *)src_addr;
pdest_p1 = (unsigned char *)dest_addr_p1;
/*format is UYVY*/
for (j = 0; j < height; j++) {
for (i = 0; i < width; i += 2) {
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = u;
*pdest_p1++ = y;
b = (unsigned int)*psrc++;
g = (unsigned int)*psrc++;
r = (unsigned int)*psrc++;
psrc++;
y = (unsigned char)((77 * r + 150 * g + 29 * b) >> 8);
u = (unsigned char)(128 + ((128 * b - 43 * r - 85 * g) >> 8));
v = (unsigned char)(128 + ((128 * r - 107 * g - 21 * b) >> 8));
*pdest_p1++ = v;
*pdest_p1++ = y;
}
pdest_p1 += porch_p1;
}
}
int lcd_draw_images(unsigned int addr_p1, unsigned int *addr_p2, unsigned int *addr_p3,
unsigned int format, unsigned int pattern, unsigned int width,
unsigned int height, unsigned int *stride_p1, unsigned int *stride_p2,
unsigned int *stride_p3)
{
unsigned int stride_temp = 0;
unsigned int addr_tmp = 0;
if ((LCD_FORMAT_RGBA888 == format) || (LCD_FORMAT_RGB888_UNPACKED == format)) {
prepare_argb8888_image(addr_p1, pattern, width, height, STRIDE_ALIGN, stride_p1);
return 0;
}
addr_tmp = (unsigned int)malloc(width * height * 4);
if (!addr_tmp) {
printf("%s: no mem w: %d, h: %d\n", __func__, width, height);
return -1;
}
prepare_argb8888_image(addr_tmp, pattern, width, height, 1, &stride_temp);
switch (format) {
case LCD_FORMAT_RGB888_PACKED:
argb8888_to_rgb888(addr_tmp, addr_p1, width, height, STRIDE_ALIGN, stride_p1);
break;
case LCD_FORMAT_RGB565:
argb8888_to_rgb565(addr_tmp, addr_p1, width, height, STRIDE_ALIGN, stride_p1);
break;
case LCD_FORMAT_RGB888A:
argb8888_to_rgba8888(addr_tmp, addr_p1, width, height, STRIDE_ALIGN, stride_p1);
break;
case LCD_FORMAT_YUV420_SEMI:
argb8888_to_yuv420_p2(addr_tmp, addr_p1, addr_p2,
width, height, STRIDE_ALIGN, stride_p1, stride_p2);
break;
case LCD_FORMAT_YUV422_PLANAR:
argb8888_to_yuv422_p3(addr_tmp, addr_p1, addr_p2,
addr_p3, width, height, STRIDE_ALIGN, stride_p1, stride_p2, stride_p3);
break;
case LCD_FORMAT_YUV420_PLANAR:
argb8888_to_yuv420_p3(addr_tmp, addr_p1, addr_p2,
addr_p3, width, height, STRIDE_ALIGN, stride_p1, stride_p2, stride_p3);
break;
case LCD_FORMAT_YUV422_PACKED:
argb8888_to_yuv422_p1(addr_tmp, addr_p1, width, height,
STRIDE_ALIGN, stride_p1);
break;
case LCD_FORMAT_RGB1555:
argb8888_to_rgb1555(addr_tmp, addr_p1, width, height,
STRIDE_ALIGN, stride_p1);
break;
default:
printf("%s: Unsupport formate = %d\n", __func__, format);
}
free((void *)addr_tmp);
return 0;
}
int lcd_compare_buffers(unsigned int src, unsigned int dest, unsigned int width,
unsigned int height, unsigned int stride_src, unsigned int stride_dest, unsigned int format, int log)
{
unsigned int var1, var2;
unsigned int res, i, j;
unsigned char *mem_ptr1;
unsigned char *mem_ptr2;
unsigned int bpp;
if ((LCD_FORMAT_RGB565 != format) && (LCD_FORMAT_RGB888_PACKED != format) &&
(LCD_FORMAT_RGB888A != format) && (LCD_FORMAT_RGBA888 != format)) {
printf("%s: only support RGB565 & RGB888_packet & RGB888A (0x%x)\n", __func__, format);
return -1;
}
if ((LCD_FORMAT_RGB565 == format) ||
(LCD_FORMAT_RGB1555 == format)) {
bpp = 2;
}
else if (LCD_FORMAT_RGB888_PACKED == format) {
bpp = 3;
}
else {
bpp = 4;
}
for (j = 0; j < height; j++) {
mem_ptr1 = (unsigned char *)(src + j * stride_src);
mem_ptr2 = (unsigned char *)(dest + j * stride_dest);
res = memcmp(mem_ptr1, mem_ptr2, width * bpp);
if (res != 0) {
res = 0;
for (i = 0; i < width; i++) {
if (4 == bpp) {
var1 = *(unsigned int *)mem_ptr1;
var2 = *(unsigned int *)mem_ptr2;
}
else if (3 == bpp) {
var1 = (*mem_ptr1 << 16) | (*(mem_ptr1 + 1) << 8) | *(mem_ptr1 + 2);
var2 = (*mem_ptr2 << 16) | (*(mem_ptr2 + 1) << 8) | *(mem_ptr2 + 2);
}
else {
var1 = (*mem_ptr1 << 8) | *(mem_ptr1 + 1);
var2 = (*mem_ptr2 << 8) | *(mem_ptr2 + 1);
}
if ((var1 & 0xFFFFFF) != (var2 & 0xFFFFFF)) {
if (1 == log) {
printf("%s: mismatch: source[0x%08X] = 0x%08X. dest[0x%08X] = 0x%08X.\n",
__func__, (unsigned int)mem_ptr1, var1, (unsigned int)mem_ptr2, var2);
}
res = -1;
}
mem_ptr1 += bpp;
mem_ptr2 += bpp;
}
if (res != 0) {
if (log) {
printf("%s: Error during check of bytes from address: 0x%08X.\n",
__func__, dest + j * stride_dest);
}
return -1;
}
}
}
return 0;
}
int lcd_compare_compose_buffer(struct s_compose_setting *compose_setting, int log)
{
struct s_compose_layer_setting *img_layer = NULL;
struct s_compose_layer_setting *osd1_layer = NULL;
struct s_compose_layer_setting *osd2_layer = NULL;
struct s_compose_layer_setting *first_layer = NULL;
struct s_compose_layer_setting *second_layer = NULL;
struct s_compose_layer_setting *third_layer = NULL;
unsigned int i, j, has_img = 0;
int ret, ret1 = 0;
unsigned int src1, src2, result, dest_rgb, dest_addr;
unsigned char alpha1, alpha2, dest_alpha;
unsigned char src_r, src_g, src_b, src_a;
unsigned char dest_r, dest_g, dest_b, dest_a;
unsigned char *pdest8 = NULL;
unsigned int *pdest32 = NULL;
unsigned int count = 0;
if (NULL == compose_setting) {
printf("%s: Invalid paramr\n", __func__);
return -1;
}
dump_compose_setting(compose_setting);
img_layer = &compose_setting->layer_setting[LCD_LAYER_IMG];
osd1_layer = &compose_setting->layer_setting[LCD_LAYER_OSD1];
osd2_layer = &compose_setting->layer_setting[LCD_LAYER_OSD2];
has_img = 0;
if (1 == img_layer->layer_en) {
has_img = 1;
first_layer = img_layer;
if (1 == osd1_layer->layer_en) {
second_layer = osd1_layer;
if (1 == osd2_layer->layer_en) {
third_layer = osd2_layer;
}
}
else if (1 == osd2_layer->layer_en) {
second_layer = osd2_layer;
}
}
else if (1 == osd1_layer->layer_en) {
first_layer = osd1_layer;
if (1 == osd2_layer->layer_en) {
second_layer = osd2_layer;
}
}
else if (1 == osd2_layer->layer_en) {
first_layer = osd2_layer;
}
if (NULL == first_layer) {
printf("%s: No layer is enabled!\n", __func__);
return -1;
}
for (i = 0; i < compose_setting->height; i++) {
for (j = 0; j < compose_setting->width; j++) {
/*get src1 data*/
ret = get_layer_rgb_data(j, i, 1, first_layer, &src1, &alpha1);
if (0 != ret) {
printf("%s: get_layer_rgb_data fail!\n", __func__);
return -1;
}
else {
if (1 == log) {
printf("%s: get src1 %d, %d rgb data is 0x%x, A is%d\n",
__func__, j, i, src1, alpha1);
}
}
if (NULL == second_layer) {
result = do_compose(&src1, NULL, alpha1, 0, compose_setting->alpha_mode,
compose_setting->dest_format, &dest_rgb, &dest_alpha, log);
goto compare;
}
/*get src2 data*/
ret = get_layer_rgb_data(j, i, 0, second_layer, &src2, &alpha2);
if (0 != ret) {
printf("%s: get_layer_rgb_data fail!\n", __func__);
return -1;
}
else {
if (1 == log) {
printf("%s: get src2 %d, %d rgb data is 0x%x, A is%d\n",
__func__, j, i, src2, alpha2);
}
}
if (has_img) {
result = do_compose(&src1, &src2, 0, alpha2, compose_setting->alpha_mode,
compose_setting->dest_format, &dest_rgb, &dest_alpha, log);
}
else {
result = do_compose(&src1, &src2, alpha1, alpha2, compose_setting->alpha_mode,
compose_setting->dest_format, &dest_rgb, &dest_alpha, log);
}
if (1 == log) {
printf("%s: compose 0x%x, 0x%x is 0x%x!\n", __func__, src1, src2, result);
}
if (NULL == third_layer) {
goto compare;
}
src1 = dest_rgb;
alpha1 = dest_alpha;
/*get src3 data*/
ret = get_layer_rgb_data(j, i, 0, third_layer, &src2, &alpha2);
if (0 != ret) {
printf("%s: get_layer_rgb_data fail!\n", __func__);
return -1;
}
else {
if (1 == log) {
printf("%s: get %d, %d rgb data is 0x%x!\n", __func__, j, i, src2);
}
}
result = do_compose(&src1, &src2, alpha1, alpha2, compose_setting->alpha_mode,
compose_setting->dest_format, &dest_rgb, &dest_alpha, log);
if (1 == log) {
printf("%s: compose 0x%x, 0x%x is 0x%x!\n", __func__, src1, src2, result);
}
compare:
if (compose_setting->dest_format == LCD_FORMAT_RGB888_PACKED) {
dest_addr = compose_setting->dest_addr + i * compose_setting->dest_stride
+ j * 3;
pdest8 = (unsigned char *)dest_addr;
dest_b = (*pdest8++) & 0xFF;
dest_g = (*pdest8++) & 0xFF;
dest_r = (*pdest8) & 0xFF;
dest_a = 0;
dest_rgb = (dest_r << 16) | (dest_g << 8) | dest_b;
result = result & 0xFFFFFF;
pdest8 = (unsigned char *)&result;
src_b = (*pdest8++) & 0xFF;
src_g = (*pdest8++) & 0xFF;
src_r = (*pdest8) & 0xFF;
src_a = 0;
}
else if (compose_setting->dest_format == LCD_FORMAT_RGB888A) {
dest_addr = compose_setting->dest_addr + i * compose_setting->dest_stride
+ j * 4;
pdest32 = (unsigned int *)dest_addr;
dest_rgb = *pdest32;
if ((compose_setting->alpha_mode != LCD_ALPHA_MODE_PRE) ||
(NULL == second_layer)) {
result = result & 0xFFFFFF00;
dest_rgb = dest_rgb & 0xFFFFFF00;
}
pdest8 = (unsigned char *)&dest_rgb;
dest_a = (*pdest8++) & 0xFF;
dest_b = (*pdest8++) & 0xFF;
dest_g = (*pdest8++) & 0xFF;
dest_r = (*pdest8) & 0xFF;
pdest8 = (unsigned char *)&result;
src_a = (*pdest8++) & 0xFF;
src_b = (*pdest8++) & 0xFF;
src_g = (*pdest8++) & 0xFF;
src_r = (*pdest8) & 0xFF;
}
else if (compose_setting->dest_format == LCD_FORMAT_RGBA888) {
dest_addr = compose_setting->dest_addr + i * compose_setting->dest_stride
+ j * 4;
pdest32 = (unsigned int *)dest_addr;
dest_rgb = *pdest32;
if ((compose_setting->alpha_mode != LCD_ALPHA_MODE_PRE) ||
(NULL == second_layer)) {
result = result & 0xFFFFFF;
dest_rgb = dest_rgb & 0xFFFFFF;
}
pdest8 = (unsigned char *)&dest_rgb;
dest_b = (*pdest8++) & 0xFF;
dest_g = (*pdest8++) & 0xFF;
dest_r = (*pdest8++) & 0xFF;
dest_a = (*pdest8) & 0xFF;
pdest8 = (unsigned char *)&result;
src_b = (*pdest8++) & 0xFF;
src_g = (*pdest8++) & 0xFF;
src_r = (*pdest8++) & 0xFF;
src_a = (*pdest8) & 0xFF;
}
else {
printf("%s: Unsupported dest format (0x%x)!\n",
__func__, compose_setting->dest_format);
return -1;
}
count++;
if ((dest_r < (src_r - 1)) || (dest_r > (src_r + 1)) ||
(dest_g < (src_g - 1)) || (dest_g > (src_g + 1)) ||
(dest_b < (src_b - 1)) || (dest_b > (src_b + 1)) ||
(dest_a < (src_a - 1)) || (dest_a > (src_a + 1))) {
printf("%s: Compare fail: (w=%d, h=%d) src = 0x%x, dest = 0x%x\n",
__func__, j, i, result, dest_rgb);
printf("%s: dest_addr = 0x%x\n", __func__, dest_addr);
printf("%s: src_r,g,b,a = %d, %d, %d, %d\n",
__func__, src_r, src_g, src_b, src_a);
printf("%s: dest_r,g,b,a = %d, %d, %d, %d\n",
__func__, dest_r, dest_g, dest_b, dest_a);
ret1 = -1;
return -1;
}
}
}
printf("%s: compare %d pixel are same\n", __func__, count);
return ret1;
}