libge2d: add support for independent alpha channel [1/1]

PD#SWPL-151902

Problem:
need support for 'nv12 + alpha -> rgba'

Solution:
complete this support

Verify:
sc2

Change-Id: I8e33e0f24b82eca8a59c7b3cf1339d1565fef022
Signed-off-by: Jian Cao <jian.cao@amlogic.com>
diff --git a/libge2d/aml_ge2d.c b/libge2d/aml_ge2d.c
index dfeed25..ca759ff 100644
--- a/libge2d/aml_ge2d.c
+++ b/libge2d/aml_ge2d.c
@@ -77,6 +77,7 @@
             break;
         case PIXEL_FORMAT_Y8:
         case PIXEL_FORMAT_CLUT8:
+        case PIXEL_FORMAT_ALPHA8:
             size_out[0] = CANVAS_ALIGNED(image_width) * buffer->canvas_h;
             break;
         default:
diff --git a/libge2d/ge2d_port.c b/libge2d/ge2d_port.c
index e59e804..073ca2e 100644
--- a/libge2d/ge2d_port.c
+++ b/libge2d/ge2d_port.c
@@ -138,6 +138,11 @@
         *p_bpp = GE2D_BPP_8;
         is_one_plane = 1;
         break;
+        case  PIXEL_FORMAT_ALPHA8:
+        *pge2d_format = GE2D_FORMAT_S8_A;
+        *p_bpp = GE2D_BPP_8;
+        is_one_plane = 1;
+        break;
         default:
         E_GE2D("Image format %d not supported!", *img_format);
         *pge2d_format = 0xffffffff;
@@ -206,6 +211,23 @@
         return 0;
 }
 
+/* for example, append alpha for nv12:
+ * nv12 + alpha -> rgba
+ */
+static int is_not_append_alpha(aml_ge2d_info_t *pge2dinfo)
+{
+    if (pge2dinfo->src_info[0].format == PIXEL_FORMAT_ALPHA8 ||
+        pge2dinfo->src_info[1].format == PIXEL_FORMAT_ALPHA8)
+        return 0;
+    else
+        return 1;
+}
+
+static int is_append_alpha(aml_ge2d_info_t *pge2dinfo)
+{
+    return !is_not_append_alpha(pge2dinfo);
+}
+
 static int is_need_swap_src2(int format,buffer_info_t *src2, buffer_info_t *dst,
                              int cap_attr)
 {
@@ -275,6 +297,7 @@
     case PIXEL_FORMAT_YCbCr_420_SP_NV12:
     case PIXEL_FORMAT_YCbCr_422_UYVY:
     case PIXEL_FORMAT_BGR_888:
+    case PIXEL_FORMAT_ALPHA8:
         op_number = 1;
         break;
     case PIXEL_FORMAT_YV12:
@@ -398,7 +421,8 @@
                 ge2d_config_ex.dst_planes[1].h = d_canvas_h/2;
             }
         }  else if (output_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                    output_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                    output_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                    output_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex.dst_planes[0].addr = output_buffer_info->offset[0];
             ge2d_config_ex.dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
             ge2d_config_ex.dst_planes[0].w = d_canvas_w;
@@ -632,7 +656,8 @@
                 ge2d_config_ex.src_planes[1].h = s_canvas_h/2;
             }
         } else if (input_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex.src_planes[0].addr = input_buffer_info->offset[0];
             ge2d_config_ex.src_planes[0].shared_fd = input_buffer_info->shared_fd[0];
             ge2d_config_ex.src_planes[0].w = s_canvas_w;
@@ -749,6 +774,7 @@
         case PIXEL_FORMAT_BGRA_8888:
         case PIXEL_FORMAT_Y8:
         case PIXEL_FORMAT_CLUT8:
+        case PIXEL_FORMAT_ALPHA8:
             if (pge2dinfo->dst_op_cnt == 0) {
                 ge2d_config_ex.dst_planes[0].addr = output_buffer_info->offset[0];
                 ge2d_config_ex.dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
@@ -1118,7 +1144,8 @@
                 ge2d_config_ex.src_planes[1].h = s_canvas_h/2;
             }
         } else if (input_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex.src_planes[0].addr = input_buffer_info->offset[0];
             ge2d_config_ex.src_planes[0].shared_fd = input_buffer_info->shared_fd[0];
             ge2d_config_ex.src_planes[0].w = s_canvas_w;
@@ -1246,7 +1273,8 @@
                 ge2d_config_ex.src2_planes[1].h = s2_canvas_h/2;
             }
         } else if (input2_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input2_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input2_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input2_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex.src2_planes[0].addr = input2_buffer_info->offset[0];
             ge2d_config_ex.src2_planes[0].shared_fd = input2_buffer_info->shared_fd[0];
             ge2d_config_ex.src2_planes[0].w = s2_canvas_w;
@@ -1373,7 +1401,8 @@
                 ge2d_config_ex.dst_planes[1].h = d_canvas_h/2;
             }
         }  else if (output_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                    output_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                    output_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                    output_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex.dst_planes[0].addr = output_buffer_info->offset[0];
             ge2d_config_ex.dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
             ge2d_config_ex.dst_planes[0].w = d_canvas_w;
@@ -1610,7 +1639,8 @@
                 ge2d_config_ex->dst_planes[1].h = d_canvas_h/2;
             }
         }  else if (output_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                    output_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                    output_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                    output_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex->dst_planes[0].addr = output_buffer_info->offset[0];
             ge2d_config_ex->dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
             ge2d_config_ex->dst_planes[0].w = d_canvas_w;
@@ -1859,7 +1889,8 @@
                 ge2d_config_ex->src_planes[1].h = s_canvas_h/2;
             }
         } else if (input_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex->src_planes[0].addr = input_buffer_info->offset[0];
             ge2d_config_ex->src_planes[0].shared_fd = input_buffer_info->shared_fd[0];
             ge2d_config_ex->src_planes[0].w = s_canvas_w;
@@ -1975,6 +2006,7 @@
         case PIXEL_FORMAT_BGRA_8888:
         case PIXEL_FORMAT_Y8:
         case PIXEL_FORMAT_CLUT8:
+        case PIXEL_FORMAT_ALPHA8:
             if (pge2dinfo->dst_op_cnt == 0) {
                 ge2d_config_ex->dst_planes[0].addr = output_buffer_info->offset[0];
                 ge2d_config_ex->dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
@@ -2372,7 +2404,8 @@
                 ge2d_config_ex->src_planes[1].h = s_canvas_h/2;
             }
         } else if (input_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex->src_planes[0].addr = input_buffer_info->offset[0];
             ge2d_config_ex->src_planes[0].shared_fd = input_buffer_info->shared_fd[0];
             ge2d_config_ex->src_planes[0].w = s_canvas_w;
@@ -2500,7 +2533,8 @@
                 ge2d_config_ex->src2_planes[1].h = s2_canvas_h/2;
             }
         } else if (input2_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                   input2_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                   input2_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                   input2_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex->src2_planes[0].addr = input2_buffer_info->offset[0];
             ge2d_config_ex->src2_planes[0].shared_fd = input2_buffer_info->shared_fd[0];
             ge2d_config_ex->src2_planes[0].w = s2_canvas_w;
@@ -2629,7 +2663,8 @@
 
             }
         }  else if (output_buffer_info->format == PIXEL_FORMAT_Y8 ||
-                    output_buffer_info->format == PIXEL_FORMAT_CLUT8) {
+                    output_buffer_info->format == PIXEL_FORMAT_CLUT8 ||
+                    output_buffer_info->format == PIXEL_FORMAT_ALPHA8) {
             ge2d_config_ex->dst_planes[0].addr = output_buffer_info->offset[0];
             ge2d_config_ex->dst_planes[0].shared_fd = output_buffer_info->shared_fd[0];
             ge2d_config_ex->dst_planes[0].w = d_canvas_w;
@@ -2801,6 +2836,7 @@
     case PIXEL_FORMAT_YCbCr_422_SP:
     case PIXEL_FORMAT_YCbCr_420_SP_NV12:
     case PIXEL_FORMAT_YCbCr_422_UYVY:
+    case PIXEL_FORMAT_ALPHA8:
         if (pge2dinfo->dst_op_cnt == 0) {
             op_ge2d_info.dst_rect.x = dx;
             op_ge2d_info.dst_rect.y = dy;
@@ -2879,6 +2915,7 @@
     case PIXEL_FORMAT_YCbCr_422_SP:
     case PIXEL_FORMAT_YCbCr_420_SP_NV12:
     case PIXEL_FORMAT_YCbCr_422_UYVY:
+    case PIXEL_FORMAT_ALPHA8:
         if (pge2dinfo->dst_op_cnt == 0) {
             op_ge2d_info.dst_rect.x = dx;
             op_ge2d_info.dst_rect.y = dy;
@@ -2954,6 +2991,7 @@
     case PIXEL_FORMAT_YCrCb_420_SP:
     case PIXEL_FORMAT_YCbCr_420_SP_NV12:
     case PIXEL_FORMAT_YCbCr_422_UYVY:
+    case PIXEL_FORMAT_ALPHA8:
         if (pge2dinfo->dst_op_cnt == 0) {
             op_ge2d_info.dst_rect.x = drect->x;
             op_ge2d_info.dst_rect.y = drect->y;
@@ -3031,6 +3069,7 @@
     case PIXEL_FORMAT_YCrCb_420_SP:
     case PIXEL_FORMAT_YCbCr_420_SP_NV12:
     case PIXEL_FORMAT_YCbCr_422_UYVY:
+    case PIXEL_FORMAT_ALPHA8:
         if (pge2dinfo->dst_op_cnt == 0) {
             op_ge2d_info.dst_rect.x = drect->x;
             op_ge2d_info.dst_rect.y = drect->y;
@@ -3146,16 +3185,29 @@
             break;
         case BLEND_MODE_COVERAGE:
             if (pge2dinfo->b_src_swap) {
-                blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA;
-                blend_op.color_blending_dst_factor = COLOR_FACTOR_DST_ALPHA;
-                blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE_MINUS_DST_ALPHA;
-                blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA;
-            }
-            else {
-                blend_op.color_blending_src_factor = COLOR_FACTOR_SRC_ALPHA;
-                blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA;
-                blend_op.alpha_blending_src_factor = ALPHA_FACTOR_SRC_ALPHA;
-                blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA;
+                if (is_append_alpha(pge2dinfo)) {
+                    blend_op.color_blending_src_factor = COLOR_FACTOR_ZERO;
+                    blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE;
+                    blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE;
+                    blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ZERO;
+                } else {
+                    blend_op.color_blending_src_factor = COLOR_FACTOR_ONE_MINUS_DST_ALPHA;
+                    blend_op.color_blending_dst_factor = COLOR_FACTOR_DST_ALPHA;
+                    blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE_MINUS_DST_ALPHA;
+                    blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA;
+                }
+            } else {
+                if (is_append_alpha(pge2dinfo)) {
+                    blend_op.color_blending_src_factor = COLOR_FACTOR_ONE;
+                    blend_op.color_blending_dst_factor = COLOR_FACTOR_ZERO;
+                    blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ZERO;
+                    blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ONE;
+                } else {
+                    blend_op.color_blending_src_factor = COLOR_FACTOR_SRC_ALPHA;
+                    blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA;
+                    blend_op.alpha_blending_src_factor = ALPHA_FACTOR_SRC_ALPHA;
+                    blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA;
+                }
             }
             break;
         case BLEND_MODE_INVALID:
@@ -3260,8 +3312,7 @@
                 blend_op.color_blending_dst_factor = COLOR_FACTOR_DST_ALPHA;
                 blend_op.alpha_blending_src_factor = ALPHA_FACTOR_ONE_MINUS_SRC_ALPHA;
                 blend_op.alpha_blending_dst_factor = ALPHA_FACTOR_DST_ALPHA;
-            }
-            else {
+            } else {
                 blend_op.color_blending_src_factor = COLOR_FACTOR_SRC_ALPHA;
                 blend_op.color_blending_dst_factor = COLOR_FACTOR_ONE_MINUS_SRC_ALPHA;
                 blend_op.alpha_blending_src_factor = ALPHA_FACTOR_SRC_ALPHA;
@@ -3465,9 +3516,10 @@
             dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y;
             ret = ge2d_blend_config_ex(fd,pge2dinfo);
             if (ret == ge2d_success) {
-                if ((is_no_alpha(pge2dinfo->src_info[0].format))
+                if (is_not_append_alpha(pge2dinfo)
+                    && ((is_no_alpha(pge2dinfo->src_info[0].format))
                     || (is_no_alpha(pge2dinfo->src_info[1].format))
-                    || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON)) {
+                    || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON))) {
                     if (pge2dinfo->b_src_swap)
                         ge2d_blend_noalpha(fd,pge2dinfo,&(pge2dinfo->src_info[1].rect),
                             &(pge2dinfo->src_info[0].rect),
@@ -3669,9 +3721,10 @@
             dst_rect.x =  pge2dinfo->dst_info.rect.x;
             dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y;
 
-            if ((is_no_alpha(pge2dinfo->src_info[0].format))
+            if (is_not_append_alpha(pge2dinfo)
+                && ((is_no_alpha(pge2dinfo->src_info[0].format))
                 || (is_no_alpha(pge2dinfo->src_info[1].format))
-                || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON)) {
+                || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON))) {
                 if (pge2dinfo->b_src_swap)
                     ret = ge2d_blend_noalpha(fd,pge2dinfo,&(pge2dinfo->src_info[1].rect),
                         &(pge2dinfo->src_info[0].rect),
@@ -3783,9 +3836,10 @@
             dst_rect.y = pge2dinfo->offset + pge2dinfo->dst_info.rect.y;
             ret = ge2d_blend_config_ex_ion(fd,pge2dinfo);
             if (ret == ge2d_success) {
-                if ((is_no_alpha(pge2dinfo->src_info[0].format))
+                if (is_not_append_alpha(pge2dinfo)
+                    && ((is_no_alpha(pge2dinfo->src_info[0].format))
                     || (is_no_alpha(pge2dinfo->src_info[1].format))
-                    || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON)) {
+                    || (pge2dinfo->src_info[0].layer_mode == LAYER_MODE_NON))) {
                     if (pge2dinfo->b_src_swap)
                         ret = ge2d_blend_noalpha(fd,pge2dinfo,&(pge2dinfo->src_info[1].rect),
                             &(pge2dinfo->src_info[0].rect),
diff --git a/libge2d/include/ge2d_port.h b/libge2d/include/ge2d_port.h
index fc1817b..18bd0a3 100644
--- a/libge2d/include/ge2d_port.h
+++ b/libge2d/include/ge2d_port.h
@@ -97,7 +97,8 @@
     PIXEL_FORMAT_ARGB_1555,
     PIXEL_FORMAT_ARGB_4444,
     PIXEL_FORMAT_RGBA_4444,
-    PIXEL_FORMAT_CLUT8
+    PIXEL_FORMAT_CLUT8,
+    PIXEL_FORMAT_ALPHA8
 } pixel_format_t;
 
 #define PIXEL_FORMAT_LITTLE_ENDIAN 0