跳转至

GALITE 加速开发指南*

第一章 概述*

GALITE 是一款专门为智能业务定制的轻量级低功耗的 2D 图像加速引擎。

重要概念*

  • 位图: 完整的图像数据,通常有位图 A、位图 B、位图 D 三种。
  • 输入位图:需要处理的位图数据。位图 A 和位图 B 为输入位图。
  • 输出位图:处理完成后的图像数据。位图 D 为输出位图。

工作模式*

GALITE 有两种工作模式。config 模式和 submit 模式。

  • config 模式:在 config 模式下,GALITE 一次只能完成一次图像处理,需要处理下一个图像时需要等到上一次图像处理完成才可以重新提交。
  • submit 模式: 在 submit 模式下,可以一次提交多个图像处理请求。

重要信息

在 submit 模式下,只有当之前提交的图像处理请求完成后才可以重新提交。

位图数据类型格式*

GALITE 支持多种位图数据类型格式:

  • 输入位图数据格式
    • CLUT4、CLUT8、A4、A8
    • ARGB8888、ARGB4444、ARGB1555、BGR888、RGB565
  • 输出位图数据格式
    • CLUT4、CLUT8、A4、A8(仅在拷贝模式下有效)
    • ARGB8888、ARGB4444、ARGB1555、BGR888、RGB565

重要信息

在混合模式下,位图 B 不支持 CLUT4、CLUT8、A4、A8 格式。 输出位图格式只在拷贝模式下支持 CLUT4、CLUT8、A4、A8。

第二章 功能特性*

GALITE 支持矩形填充图像拷贝图像数据类型转换 (Blit)图像混合操作。根据使用需求又可以分为同步异步方式。所有的图像处理都按照 SURFACERECT 格式进行。

  • SURFACE:表示处理的位图数据信息。其中包括位图宽度、高度、位图地址、位图数据格式等。
  • RECT:表示位图区域内需要处理的区域。其中包括图像起始的 x、y 坐标,以及需要处理的宽度和高度。

重要信息

同步和异步不可以同时使用。

矩形填充*

矩形填充是在基宽为 DestBaseWidth 的图像上填充色往目标地址 DestAddr 填充一个宽度为 DestWidth,高度为 DestHeight 的矩形区域。

矩形填充可以往指定的矩形区域内填充固定的颜色,同时支持扫描行时机控制。可以通过 gx_hal_ga_lite_fill 函数对指定区域内的矩形进行填充。

示例代码*

  • config 模式下示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_CONFIGURE,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
}

int main (int argc, char **argv)
{
    gx_hal_ga_lite_init(&ga_lite);
    case_ga_fill(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);
    return 0;
}
  • submit 模式下示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_fill(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}

重要信息

位图颜色格式为 RGB888 时,填充区域的 x,y,width 和 位图宽度需要 4 像素点对齐。 位图颜色格式为 CLUT4/A4 时,填充区域的 x,y,width 和 位图宽度需要 2 像素点对齐。

Blit 功能*

从基宽为 SrcaBaseWidth 的图片的 SrcaAddr 起始地址 Blit 一块宽度为 SrcaWidth,高度为 SrcaHeight 的矩形区域到目标基宽为 DestBaseWidth,目标起始地址为 DestAddr,目标宽度为 DestWidth,高度为 DestHeight 的目标区域。

Blit 功能支持位图格式转换、位图数据格式的扩展、扫描时机控制等功能。可以通过 gx_hal_ga_lite_blit 函数对指定区域内的矩形进行 Blit 操作。

  • 可以 Blit 整张图片,也可以是一个区域。
  • Blit 可以进行数据类型转换,原图片和目标的位图格式可以不一致。
  • 输入位图格式 ARGB1555 支持 Alpha 扩展。如果打开 alpha_extern,A=1 时使用 alpha1 作为 alpha 值,A=0 时使用 alpha0 作为 alpha 值。
  • 如果输入位图格式为 A4/A8,需要设置 extern_color 的 R、G、B 值。extern_color 会和 A4 或者 A8 数据扩展成 ARGB8888 类型。
  • 如果输入位图格式为 RGB,需要设置 extern_color 的 alpha 值。alpha 会 RGB 数据扩展成 ARGB8888 类型。
  • 如果输入位图格式为 CLUT4/CLUT8,则需要设置色表地址。色表加载一次可以重复使用,直到重新加载新的色表或者复位 GA。

示例代码*

  • config 模式示例代码
static GX_HAL_GA_LITE ga_lite = {
   .regs = (void*)0xb6400000,
   .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_CONFIGURE,
   .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_blit(GX_HAL_GA_LITE *dev)
{
   GX_HAL_GA_SURFACE src;
   GX_HAL_GA_RECT src_rect;
   GX_HAL_GA_SURFACE dst;
   GX_HAL_GA_RECT dst_rect;
   GX_HAL_GA_BLIT_OPT opt;

   memset(&opt, 0, sizeof(GX_HAL_GA_BLIT_OPT));

   src.phy_addr = (uint32)VIRT_TO_PHY(src_buff);
   src.width = src_width_base; //位图A图像宽度
   src.height = src_height_base; //位图A图像高度
   src.color_format = GX_HAL_COLOR_ARGB8888;
   src.endian = GX_HAL_LITTLE_ENDIAN;

   src_rect.xpos = x0; //位图A起始地址的X坐标
   src_rect.ypos = y0; //位图A起始地址的Y坐标
   src_rect.width = width0; //位图A Blit区域的宽度
   src_rect.height = height0; //位图A Blit区域的高度

   dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
   dst.width = dst_width_base; //位图D图像宽度
   dst.height = dst_height_base; //位图D图像高度
   dst.color_format = GX_HAL_COLOR_ARGB8888;
   dst.endian = GX_HAL_LITTLE_ENDIAN;

   dst_rect.xpos = x1; //位图D起始地址的X坐标
   dst_rect.ypos = y1; // 位图D起始地址的Y坐标
   dst_rect.width = width1; // 位图D Blit区域的宽度
   dst_rect.height = height1; // 位图D Blit区域的高度

   gx_hal_ga_lite_blit(dev, &src, &src_rect, &dst, &dst_rect, &opt);

}

int main (int argc, char **argv)
{
   gx_hal_ga_lite_init(&ga_lite);
   case_ga_blit(&ga_lite);
   gx_hal_ga_lite_wait_done(&ga_lite);
   return 0;
}
  • submit 模式下示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_blit(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE src;
    GX_HAL_GA_RECT src_rect;
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_BLIT_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_BLIT_OPT));

    src.phy_addr = (uint32)VIRT_TO_PHY(src_buff);
    src.width = src_width_base; //位图A图像宽度
    src.height = src_height_base; //位图A图像高度
    src.color_format = GX_HAL_COLOR_ARGB8888;
    src.endian = GX_HAL_LITTLE_ENDIAN;

    src_rect.xpos = x0; //位图A起始地址的X坐标
    src_rect.ypos = y0; //位图A起始地址的Y坐标
    src_rect.width = width0; //位图A Blit区域的宽度
    src_rect.height = height0; //位图A Blit区域的高度

    dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
    dst.width = dst_width_base; //位图D图像宽度
    dst.height = dst_height_base; //位图D图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x1; //位图D起始地址的X坐标
    dst_rect.ypos = y1; // 位图D起始地址的Y坐标
    dst_rect.width = width1; // 位图D Blit区域的宽度
    dst_rect.height = height1; // 位图D Blit区域的高度

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_blit(dev, &src, &src_rect, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_blit(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}

重要信息

位图颜色格式为 RGB888 时,操作区域的 x,y,width 和 位图宽度需要 4 像素点对齐。 位图颜色格式为 CLUT4/A4 时,操作区域的 x,y,width 和 位图宽度需要 2 像素点对齐。

拷贝功能*

从基宽为 SrcaBaseWidth 的图片的 SrcaAddr 起始地址 copy 一块宽度为 SrcaWidth,高度为 SrcaHeight 的矩形区域到目标基宽为 DestBaseWidth,目标起始地址为 DestAddr,目标宽度为 DestWidth,高度为 DestHeight 的目标区域。

位图拷贝类似于 DMA 功能。原图片和目标图片的颜色格式一致。支持扫描行控制。可以通过 gx_hal_ga_lite_copy 函数对指定区域内的矩形进行拷贝。

示例代码*

  • config 模式示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_CONFIGURE,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_copy(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE src;
    GX_HAL_GA_RECT src_rect;
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_WAIT_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_WAIT_OPT));

    src.phy_addr = (uint32)VIRT_TO_PHY(src_buff);
    src.width = src_width_base; //位图A图像宽度
    src.height = src_height_base; //位图A图像高度
    src.color_format = GX_HAL_COLOR_ARGB8888;
    src.endian = GX_HAL_LITTLE_ENDIAN;

    src_rect.xpos = x0; //位图A起始地址的X坐标
    src_rect.ypos = y0; //位图A起始地址的Y坐标
    src_rect.width = width0; //位图A Blit区域的宽度
    src_rect.height = height0; //位图A Blit区域的高度

    dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
    dst.width = dst_width_base; //位图D图像宽度
    dst.height = dst_height_base; //位图D图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x1; //位图D起始地址的X坐标
    dst_rect.ypos = y1; // 位图D起始地址的Y坐标
    dst_rect.width = width1; // 位图D Blit区域的宽度
    dst_rect.height = height1; // 位图D Blit区域的高度

    gx_hal_ga_lite_copy(dev, &src, &src_rect, &dst, &dst_rect, &opt);

}

int main (int argc, char **argv)
{
    gx_hal_ga_lite_init(&ga_lite);
    case_ga_copy(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);
    return 0;
}
  • submit 模式下示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_copy(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE src;
    GX_HAL_GA_RECT src_rect;
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_WAIT_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_WAIT_OPT));

    src.phy_addr = (uint32)VIRT_TO_PHY(src_buff);
    src.width = src_width_base; //位图A图像宽度
    src.height = src_height_base; //位图A图像高度
    src.color_format = GX_HAL_COLOR_ARGB8888;
    src.endian = GX_HAL_LITTLE_ENDIAN;

    src_rect.xpos = x0; //位图A起始地址的X坐标
    src_rect.ypos = y0; //位图A起始地址的Y坐标
    src_rect.width = width0; //位图A Blit区域的宽度
    src_rect.height = height0; //位图A Blit区域的高度

    dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
    dst.width = dst_width_base; //位图D图像宽度
    dst.height = dst_height_base; //位图D图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x1; //位图D起始地址的X坐标
    dst_rect.ypos = y1; // 位图D起始地址的Y坐标
    dst_rect.width = width1; // 位图D Blit区域的宽度
    dst_rect.height = height1; // 位图D Blit区域的高度

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_copy(dev, &src, &src_rect, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);

}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_copy(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}

重要信息

位图颜色格式为 RGB888 时,操作区域的 x,y,width 和 位图宽度需要 4 像素点对齐。 位图颜色格式为 CLUT4/A4 时,操作区域的 x,y,width 和 位图宽度需要 2 像素点对齐。

混合功能*

混合功能是一个双目操作。源和目标根据不同的混合公式进行混合操作,最后将源和目标的混合结果相加得到最终的混合效果。

混合操作分为填充色混合和位图混合。两种混合又支持color 混合alpha 混合两大类混合函数。同时支持位图数据格式扩展、alpha 输出替换、扫描行时机控制。可以通过 gx_hal_ga_lite_blend 或者 gx_hal_ga_lite_fill_and_blend 函数对指定区域内的矩形进行混合。

  • 位图混合:位图 A、位图 B、目标图片的颜色格式可以不一致。
  • 填充色混合:填充色和位图 B 进行混合操作,位图 B、目标图片的颜色格式可以不一致。
  • 输入位图格式 ARGB1555 支持 Alpha 扩展。如果打开 alpha_extern,A=1 时使用 alpha1 作为 alpha 值,A=0 时使用 alpha0 作为 alpha 值。
  • 输出位图支持 alpha 替换,将输出 alpha 替换成 alpha_out。
  • 如果输入位图格式为 A4/A8,需要设置 src_global_color 的 R、G、B 值。src_global_color 会和 A4 或者 A8 数据扩展成 ARGB 类型。
  • 如果输入位图格式为 RGB,需要设置 src_global_color 或者 dst_global_color 的 alpha 值。alpha 会 RGB 数据扩展成 ARGB8888 类型。
  • 如果输入位图格式为 CLUT4/CLUT8,则需要设置色表地址。色表加载一次可以重复使用,直到重新加载新的色表或者复位 GA。

示例代码*

  • config 模式示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_CONFIGURE,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_blend(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE srca;
    GX_HAL_GA_RECT srca_rect;
    GX_HAL_GA_SURFACE srcb;
    GX_HAL_GA_RECT srcb_rect;
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_BLEND_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_BLEND_OPT));

    srca.phy_addr = (uint32)VIRT_TO_PHY(srca_buff);
    srca.width = srca_width_base; //位图A图像宽度
    srca.height = srca_height_base; //位图A图像高度
    srca.color_format = GX_HAL_COLOR_ARGB8888;
    srca.endian = GX_HAL_LITTLE_ENDIAN;

    srca_rect.xpos = x0; //位图A起始地址的X坐标
    srca_rect.ypos = y0; //位图A起始地址的Y坐标
    srca_rect.width = width0; //位图A Blit区域的宽度
    srca_rect.height = height0; //位图A Blit区域的高度

    srcb.phy_addr = (uint32)VIRT_TO_PHY(srcb_buff);
    srcb.width = srcb_width_base; //位图B图像宽度
    srcb.height = srcb_height_base; //位图B图像高度
    srcb.color_format = GX_HAL_COLOR_ARGB8888;
    srcb.endian = GX_HAL_LITTLE_ENDIAN;

    srcb_rect.xpos = x1; //位图B起始地址的X坐标
    srcb_rect.ypos = y1; //位图B起始地址的Y坐标
    srcb_rect.width = width1; //位图B Blit区域的宽度
    srcb_rect.height = height1; //位图B Blit区域的高度

    dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
    dst.width = dst_width_base; //位图D图像宽度
    dst.height = dst_height_base; //位图D图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x2; //位图D起始地址的X坐标
    dst_rect.ypos = y2; // 位图D起始地址的Y坐标
    dst_rect.width = width2; // 位图D Blit区域的宽度
    dst_rect.height = height2; // 位图D Blit区域的高度

    opt.src_alpha_blend_fun = GX_HAL_MIX_FUNC_ONE;
    opt.src_color_blend_fun = GX_HAL_MIX_FUNC_ONE;
    opt.dst_alpha_blend_fun = GX_HAL_MIX_FUNC_ZERO;
    opt.dst_color_blend_fun = GX_HAL_MIX_FUNC_ZERO;

    gx_hal_ga_lite_blend(dev, &srca, &srca_rect, &srcb, &srcb_rect, &dst, &dst_rect, &opt);

}

int main (int argc, char **argv)
{
    gx_hal_ga_lite_init(&ga_lite);
    case_ga_blend(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);
    return 0;
}
  • submit 模式下示例代码
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_copy(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE srca;
    GX_HAL_GA_RECT srca_rect;
    GX_HAL_GA_SURFACE srcb;
    GX_HAL_GA_RECT srcb_rect;
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_BLEND_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_BLEND_OPT));

    srca.phy_addr = (uint32)VIRT_TO_PHY(srca_buff);
    srca.width = srca_width_base; //位图A图像宽度
    srca.height = srca_height_base; //位图A图像高度
    srca.color_format = GX_HAL_COLOR_ARGB8888;
    srca.endian = GX_HAL_LITTLE_ENDIAN;

    srca_rect.xpos = x0; //位图A起始地址的X坐标
    srca_rect.ypos = y0; //位图A起始地址的Y坐标
    srca_rect.width = width0; //位图A Blit区域的宽度
    srca_rect.height = height0; //位图A Blit区域的高度

    srcb.phy_addr = (uint32)VIRT_TO_PHY(srcb_buff);
    srcb.width = srcb_width_base; //位图B图像宽度
    srcb.height = srcb_height_base; //位图B图像高度
    srcb.color_format = GX_HAL_COLOR_ARGB8888;
    srcb.endian = GX_HAL_LITTLE_ENDIAN;

    srcb_rect.xpos = x1; //位图B起始地址的X坐标
    srcb_rect.ypos = y1; //位图B起始地址的Y坐标
    srcb_rect.width = width1; //位图B Blit区域的宽度
    srcb_rect.height = height1; //位图B Blit区域的高度

    dst.phy_addr = (uint32)VIRT_TO_PHY(dst_buff);
    dst.width = dst_width_base; //位图D图像宽度
    dst.height = dst_height_base; //位图D图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x2; //位图D起始地址的X坐标
    dst_rect.ypos = y2; // 位图D起始地址的Y坐标
    dst_rect.width = width2; // 位图D Blit区域的宽度
    dst_rect.height = height2; // 位图D Blit区域的高度

    opt.src_alpha_blend_fun = GX_HAL_MIX_FUNC_ONE;
    opt.src_color_blend_fun = GX_HAL_MIX_FUNC_ONE;
    opt.dst_alpha_blend_fun = GX_HAL_MIX_FUNC_ZERO;
    opt.dst_color_blend_fun = GX_HAL_MIX_FUNC_ZERO;

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_blend(dev, &srca, &srca_rect, &srcb, &srcb_rect, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);

}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_blend(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}

重要信息

位图颜色格式为 RGB888 时,操作区域的 x、y、width 和 位图宽度需要 4 像素点对齐。 位图颜色格式为 CLUT4/A4 时,操作区域的 x、y、width 和 位图宽度需要 2 像素点对齐。

第三章 同步异步模式*

HAL 接口对于不同的使用场景提供了同步和异步两种模式。

同步模式*

同步模式是通过循环判断 GA 的工作状态等待 GA 工作完成后才会返回。

示例代码*

以填充功能为例,在同步模式下要使用 gx_hal_ga_lite_wait_done 接口等待 GA 操作完成。

  • config 模式
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_fill(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}
  • submit 模式
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

int main (int argc, char **argv)
{
    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    case_ga_fill(&ga_lite);
    gx_hal_ga_lite_wait_done(&ga_lite);

    return 0;
}

异步模式*

异步模式是通过中断的形式等待 GA 工作完成中断上报。

示例代码*

以填充功能为例,在异步模式下等待 GX_HAL_GA_INTER_DONE 上报。代表 GA 工作完成。

  • config 模式
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

static int case_ga_callback(GX_HAL_GA_INTERRUPT_STATUS irq, void *priv)
{
    if(irq & GX_HAL_GA_INTER_DONE) {
        complete = 1;
   }

}

int main (int argc, char **argv)
{
    GX_HAL_GA_CB cb;

    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    gx_ga_lite_enable_interrupt(handle->dev, GX_HAL_GA_INTER_DONE);
    cb.cb_func = case_ga_callback;
    gx_ga_lite_register_callback(handle->dev, &cb);

    complete = 0;
    case_ga_fill(&ga_lite);

    while(!complete);

    return 0;
}
  • submit 模式
static GX_HAL_GA_LITE ga_lite = {
    .regs = (void*)0xb6400000,
    .cmd_mode = GX_HAL_GA_LITE_CMD_MODE_SUBMIT,
    .cmd_timeout = 0xFFFFFFFF,
};

static case_ga_fill(GX_HAL_GA_LITE *dev)
{
    GX_HAL_GA_SURFACE dst;
    GX_HAL_GA_RECT dst_rect;
    GX_HAL_GA_FILL_OPT opt;

    memset(&opt, 0, sizeof(GX_HAL_GA_FILL_OPT));

    dst.phy_addr = (uint32)VIRT_TO_PHY(buff);
    dst.width = width_base; //图像宽度
    dst.height = height_base; //图像高度
    dst.color_format = GX_HAL_COLOR_ARGB8888;
    dst.endian = GX_HAL_LITTLE_ENDIAN;

    dst_rect.xpos = x; //填充起始地址的X坐标
    dst_rect.ypos = y; // 填充起始地址的Y坐标
    dst_rect.width = width; // 填充区域的宽度
    dst_rect.height = height; // 填充区域的高度

    opt.fill_color.color = color; //填充色

    gx_hal_ga_lite_begin(dev);
    gx_hal_ga_lite_fill(dev, &dst, &dst_rect, &opt);
    gx_hal_ga_lite_end(dev);
}

int main (int argc, char **argv)
{
    GX_HAL_GA_CB cb;

    ga_lite.cmd.virt_addr = (uint32_t*)MALLOC(10 * GX_HAL_GA_CMD_LEN);
    ga_lite.cmd.phy_addr = VIRT_TO_PHY(ga_lite.cmd.virt_addr);
    ga_lite.cmd.cmd_max_num = 10;

    gx_hal_ga_lite_init(&ga_lite);
    gx_ga_lite_enable_interrupt(handle->dev, GX_HAL_GA_INTER_DONE);
    cb.cb_func = case_ga_callback;
    gx_ga_lite_register_callback(handle->dev, &cb);

    complete = 0;
    case_ga_fill(&ga_lite);

    while(!complete);

    return 0;
}

重要信息

同步和异步不可以同时使用,只能选择其中一种。

第四章 混合规则*

混合规则分为源混合和目标混合。首先分别进行源混合和目标混合,最后将源混合和目标混合的结果相加得到最终的混合结果。

注意

源混合中的颜色数据通常为位图A,在填充混合时为填充色。目标混合的颜色数据通常为位图B。

混合函数*

源混合函数*

  • ssrc:表示源混合结果
  • src.a 表示源的 Alpha 值
  • src.r 表示源的 Red 分量
  • src.g 表示源的 Green 分量
  • src.b 表示源的 Blue 分量
  • dst.a 表示目标的 Alpha 值
  • dst.r 表示目标的 Red 分量
  • dst.g 表示目标的 Green 分量
  • dst.b 表示目标的 Blue 分量
  • sG.a 表示源全局变量 (src_global_color) 的 Alpha 值
  • sG.r 表示源全局变量 (src_global_color) 的 Red 值
  • sG.g 表示源全局变量 (src_global_color) 的 Green 值
  • sG.b 表示源全局变量 (src_global_color) 的 Blue 值
源 color 混合函数 源 color 混合公式
zero ssrc.r = ssrc.g = ssrc.b = 0
one ssrc.r = src.r
ssrc.g = src.g
ssrc.b = src.b
src_color ssrc.r = (src.r * src.r) >> 8
ssrc.g = (src.g * src.g) >> 8
ssrc.b = (src.b * src.b) >> 8
inv_src_color ssrc.r = (src.r * (255-src.r)) >> 8
ssrc.g = (src.g * (255-src.g)) >> 8
ssrc.b = (src.b * (255-src.b)) >> 8
src_alpha ssrc.r = (src.r * src.a) >> 8
ssrc.g = (src.g * src.a) >> 8
ssrc.b = (src.b * src.a) >> 8
inv_src_alpha ssrc.r = (src.r * (255-src.a)) >> 8
ssrc.g = (src.g * (255-src.a)) >> 8
ssrc.b = (src.b * (255-src.a)) >> 8
dest_alpha ssrc.r = (src.r * dst.a) >> 8
ssrc.g = (src.g * dst.a) >> 8
ssrc.b = (src.b * dst.a) >> 8
inv_dest_alpha ssrc.r = (src.r * (255-dst.a)) >> 8
ssrc.g = (src.g * (255-dst.a)) >> 8
ssrc.b = (src.b * (255-dst.a)) >> 8
dest_color ssrc.r = (src.r * dst.r) >> 8
ssrc.g = (src.g * dst.g) >> 8
ssrc.b = (src.b * dst.b) >> 8
inv_dest_color ssrc.r = (src.r * (255-dst.r)) >> 8
ssrc.g = (src.g * (255-dst.g)) >> 8
ssrc.b = (src.b * (255-dst.b)) >> 8
color_register ssrc.r = (src.r * sG.r) >> 8
ssrc.g = (src.g * sG.g) >> 8
ssrc.b = (src.b * sG.b) >> 8
alpha_register ssrc.r = (src.r * sG.a) >> 8
ssrc.g = (src.g * sG.a) >> 8
ssrc.b = (src.b * sG.a) >> 8
源 alpha 混合函数 源 alpha 混合公式
zero ssrc.a = 0
one ssrc.a = src.a
src_alpha ssrc.a = (src.a * src.a) >> 8
inv_src_alpha ssrc.a = (src.a * (255 - src.a)) >> 8
dest_alpha ssrc.a = (src.a * dst.a) >> 8
inv_dest_alpha ssrc.a = (src.a * (255-dst.a)) >> 8
alpha_register ssrc.a = (src.a * sG.a) >> 8

目标混合函数*

  • dsrc:表示源混合结果
  • src.a 表示源的 Alpha 值
  • src.r 表示源的 Red 分量
  • src.g 表示源的 Green 分量
  • src.b 表示源的 Blue 分量
  • dst.a 表示目标的 Alpha 值
  • dst.r 表示目标的 Red 分量
  • dst.g 表示目标的 Green 分量
  • dst.b 表示目标的 Blue 分量
  • dG.a 表示源全局变量 (dst_global_color) 的 Alpha 值
  • dG.r 表示源全局变量 (dst_global_color) 的 Red 值
  • dG.g 表示源全局变量 (dst_global_color) 的 Green 值
  • dG.b 表示源全局变量 (dst_global_color) 的 Blue 值
目标 color 混合函数 目标 color 混合公式
zero dsrc.r = dsrc.g = dsrc.b = 0
one dsrc.r = dst.r
dsrc.g = dst.g
dsrc.b = dst.b
src_color dsrc.r = (dst.r * src.r) >> 8
dsrc.g = (dst.g * src.g) >> 8
dsrc.b = (dst.b * src.b) >> 8
inv_src_color dsrc.r = (dst.r * (255-src.r)) >> 8
dsrc.g = (dst.g * (255-src.g)) >> 8
dsrc.b = (dst.b * (255-src.b)) >> 8
src_alpha dstc.r = (dst.r * src.a) >> 8
dsrc.g = (dst.g * src.a) >> 8
dsrc.b = (dst.b * src.a) >> 8
inv_src_alpha dsrc.r = (dst.r * (255-src.a)) >> 8
dsrc.g = (dst.g * (255-src.a)) >> 8
dsrc.b = (dst.b * (255-src.a)) >> 8
dest_alpha dsrc.r = (dst.r * dst.a) >> 8
dsrc.g = (dst.g * dst.a) >> 8
dsrc.b = (dst.b * dst.a) >> 8
inv_dest_alpha dsrc.r = (dst.r * (255-dst.a)) >> 8
dsrc.g = (dst.g * (255-dst.a)) >> 8
dsrc.b = (dst.b * (255-dst.a)) >> 8
dest_color dsrc.r = (dst.r * dst.r) >> 8
dsrc.g = (dst.g * dst.g) >> 8
dsrc.b = (dst.b * dst.b) >> 8
inv_dest_color dsrc.r = (dst.r * (255-dst.r)) >> 8
dsrc.g = (dst.g * (255-dst.g)) >> 8
dsrc.b = (dst.b * (255-dst.b)) >> 8
color_register dsrc.r = (dst.r * dG.r) >> 8
dsrc.g = (dst.g * dG.g) >> 8
ssrc.b = (dst.b * dG.b) >> 8
alpha_register dsrc.r = (dst.r * dG.a) >> 8
dsrc.g = (dst.g * dG.a) >> 8
ssrc.b = (dst.b * dG.a) >> 8
目标 alpha 混合函数 目标 alpha 混合公式
zero dsrc.a = 0
one dsrc.a = dst.a
src_alpha dsrc.a = (dst.a * src.a) >> 8
inv_src_alpha dsrc.a = (dst.a * (255 - src.a)) >> 8
dest_alpha dsrc.a = (dst.a * dst.a) >> 8
inv_dest_alpha dsrc.a = (dst.a * (255-dst.a)) >> 8
alpha_register dsrc.a = (dst.a * dG.a) >> 8

典型混合函数组合*

混合规则及组合方式*

混合规则 源混合函数 目标混合函数
clear zero zero
src one zero
dst zero one
src_over one inv_src_alpha
dst_over inv_dest_alpha one
src_in dest_alpha zero
dst_in zero src_alpha
src_out inv_dest_alpha zero
dst_out zero inv_src_alpha
src_atop dest_alpha inv_src_alpha
dst_atop inv_dest_alpha src_alpha
xor inv_dest_alpha inv_src_alpha

混合规则的效果展示*