Files
pikasTech-HWLAB/skills/arm2d-skill/references/generic-loader.md
T
Codex Agent 712db9c597 feat: arm2d-skill directory seed for CaseRun agent workspace
Add B1 directory-type seed mechanism to AGENT_WORKSPACE_SEED_FILES:
- Extended agentWorkspaceFilesForRun with collectDirectorySeedFiles helper
- arm2d-skill (SKILL.md + references/ + python/) auto-injected to .agents/skills/arm2d-skill/
- Enables Code Agent to follow ARM-2D constraints and call asset scripts in case

Skill source: https://github.com/notLabyet/HWLabOA
2026-06-07 14:40:48 +08:00

3.4 KiB
Raw Blame History

ARM-2D Generic Loader 参考

适用场景

使用 generic loader 的情况:

  • 动态渲染,软件生成式内容,例如粒子模拟。
  • 需要按 ROI 逐块生成或解码资源内容。
  • 资源太大,不适合整帧解码到 SRAM。
  • 希望配合 PFB / ROI / dirty region 做局部刷新。

基本结构

建议新建一对文件:

project/mdk/<feature>/user_generic_loader_<feature>.c
project/mdk/<feature>/user_generic_loader_<feature>.h

头文件通常包含:

typedef struct xxx_cfg_t {
    arm_2d_size_t tSize;
    uint16_t bUseHeapForVRES : 1;

    struct {
        const arm_loader_io_t *ptIO;
        uintptr_t pTarget;
    } ImageIO;

    arm_2d_scene_t *ptScene;
} xxx_cfg_t;

typedef struct xxx_t xxx_t;

struct xxx_t {
    union {
        arm_2d_tile_t tTile;
        inherit(arm_generic_loader_t);
    };

ARM_PRIVATE(
    xxx_cfg_t tCFG;
)
};

C 文件通常开头:

#define __GENERIC_LOADER_INHERIT__
#define __xxx_IMPLEMENT__

#include "user_generic_loader_xxx.h"

init 模式

arm_generic_loader_cfg_t tCFG = {
    .bUseHeapForVRES = this.tCFG.bUseHeapForVRES,
    .tColourInfo.chScheme = ARM_2D_COLOUR,
    .bBlendWithBG = false,
    .ImageIO = {
        .ptIO = this.tCFG.ImageIO.ptIO,
        .pTarget = this.tCFG.ImageIO.pTarget,
    },
    .UserDecoder = {
        .fnDecoderInit = &__xxx_decoder_init,
        .fnDecode = &__xxx_draw,
    },
    .ptScene = this.tCFG.ptScene,
};

arm_generic_loader_init(&this.use_as__arm_generic_loader_t, &tCFG);

初始化后要设置 tile 尺寸:

this.tTile.tRegion.tSize = this.tCFG.tSize;

show 模式

void xxx_show(xxx_t *ptThis,
              const arm_2d_tile_t *ptTile,
              const arm_2d_region_t *ptRegion,
              bool bIsNewFrame)
{
    ARM_2D_UNUSED(bIsNewFrame);

    if (-1 == (intptr_t)ptTile) {
        ptTile = arm_2d_get_default_frame_buffer();
    }

    arm_2d_tile_copy_only(&this.tTile, ptTile, ptRegion);
}

fnDecode 约定

函数签名:

static arm_2d_err_t __xxx_draw(
    arm_generic_loader_t *ptObj,
    arm_2d_region_t *ptROI,
    uint8_t *pchBuffer,
    uint32_t iTargetStrideInByte,
    uint_fast8_t chBitsPerPixel)

规则:

  • 必须只写 ptROI 对应区域。
  • 不能假设目标 buffer 是全屏连续 framebuffer。
  • 每行写完后用 iTargetStrideInByte 跳到下一行。
  • RGB565 时通常这样写:
for (int_fast16_t y = yStart; y < yLimit; y++) {
    uint16_t *phwPixel = (uint16_t *)pchBuffer;

    for (int_fast16_t x = xStart; x < xLimit; x++) {
        *phwPixel++ = colour;
    }

    pchBuffer += iTargetStrideInByte;
}

scene 接入

arm_2d_scene_0.h 中 include 对应 loader 头文件。

arm_2d_scene_0.c 中:

xxx_t Xxx;

load

xxx_on_load(&Xxx);

frame start

xxx_on_frame_start(&Xxx);

depose

xxx_depose(&Xxx);

PFB draw handler

arm_2d_align_centre(__top_canvas, 240, 240) {
    xxx_show(&Xxx, ptTile, &__centre_region, bIsNewFrame);
}

init

xxx_cfg_t tCFG = {
    .tSize = {
        .iWidth = 240,
        .iHeight = 240,
    },
    .ptScene = &this.use_as__arm_2d_scene_t,
};
xxx_init(&Xxx, &tCFG);

注意事项

  • 如果 decoder 很重,不要在每个 ROI 里重复计算整帧。
  • 可以使用低分辨率缓存,然后 ROI 采样放大。
  • 如果使用压缩资源,尽量做 ROI 解码或 tile/block 解码。