转载时请注明出处和作者
作者:李先静
Marvell的PXA300/310都有硬件2D图形加速单元,Broncho A1用是PXA300,但一直没有使用它的图形加速功能,前几天花了点时间研究它,这个里记个笔记:
在Android平台上,各个相关组件之间的关系如下:
最下层是Graphics Controller,这就是CPU提供的硬件加速单元,提供画直线,填充和各种blit功能。这个在Monahans_L_LV_Processor_Dev_Man_Vol_III.pdf里有详细描述。
再上层是驱动程序,它对Graphics Controller的寄存器进行包装,为应用程序提供设备文件/dev/m2d。
m2d_append 函数负责向命令队列中写入要执行的命令:
static int m2d_append(struct m2d_device *dev, void *usrbuf, size_t len)
{
volatile gcu_regs_t *gr = dev->gcu_regs;
unsigned int tail_room, head_room;
unsigned long exhead = gr->gcrbexhr;
unsigned long tail = dev->ring_tail_dma;
unsigned long base = dev->ring_addr_dma;
unsigned long size = dev->ring_size;
unsigned char *ring_addr = (unsigned char *)dev->ring_addr;
if (tail >= exhead) {
tail_room = size - (tail - base);
head_room = exhead - base;
} else {
tail_room = exhead - tail;
head_room = 0;
}
if (tail_room >= len) {
if (copy_from_user(ring_addr + (tail - base),
usrbuf, len))
return -EFAULT;
tail += len;
#ifdef FILL_NOP
} else if (head_room >= len) {
m2d_fill_nop(ring_addr + (tail - base), tail_room);
#else
} else if (head_room + tail_room >= len) {
if (copy_from_user(ring_addr + (tail - base),
usrbuf, tail_room))
return -EFAULT;
usrbuf += tail_room; len -= tail_room;
#endif
if (copy_from_user(ring_addr, usrbuf, len))
return -EFAULT;
tail = dev->ring_addr_dma + len;
} else {
return -ENOSPC;
}
if (tail - base == size)
tail = base;
switch_m2d_clk(1);
dev->ring_tail_dma = tail;
gr->gcrbtr = tail;
return 0;
}
执行完成后,GCU会通过中断通知CPU:
static int m2d_gcu_irq(int irq, void *dev_id)
{
struct m2d_device *dev = (struct m2d_device *)dev_id;
volatile gcu_regs_t *gr = dev->gcu_regs;
unsigned long status = gr->gciscr & gr->gciecr;
if (irq != IRQ_GRPHICS)
return IRQ_NONE;
/* FIXME: what if this interrupt occurs with no current context
* in execution
*/
if (status & (GCISCR_PF_INTST | GCISCR_IIN_INTST
| GCISCR_IOP_INTST))
m2d_interrupt_err(dev, gr);
if (status & GCISCR_EEOB_INTST)
m2d_interrupt_eeob(dev, gr);
return IRQ_HANDLED;
}
再上层是函数库,它对Graphics Controller提供的基本功能进行包装,然后通过/dev/m2d的ioctrl把命令发给Graphics Controller。
这里的大部分函数的功能只是将数据打包,然后通过ioctrl把命令传递给驱动程序,如:
int m2d_color_fill(
struct m2d_context *ctx,
struct m2d_op_region *opr)
{
int len = 0;
fprintf(stdout, "%s:%d/n", __func__, __LINE__);
if (ctx == NULL) return -1;
CHECK_BOUNDARY( opr->dx0, opr->dy0,
opr->width, opr->height,
ctx->dstbuf);
SETUP_CFILL_IMM(ctx->cmdbuf.cb_ptr, len,
opr->dx0, opr->dy0,
opr->width, opr->height,
ctx->fill_color_format,
ctx->fill_color_value);
UPDATE_CMDBUF(ctx, len);
fprintf(stdout, "%s:%d/n", __func__, __LINE__);
return len;
}
打包数据:
#define SETUP_CFILL_IMM(buf, len, x, y, w, h, pf, c) /
do { /
fprintf(stdout, "SETUP_CFILL_IMM: x=%d y=%d w=%d h=%d/n",x, y, w, h); /
uint32_t f = GCU_PXLFMT_FORMAT(pf); /
if ((f) < 0x0a) { /
buf[0] = GC_CFILL_IMM | ((f) << 8) | 0x04; len = 5; /
buf[4] = (uint32_t)(c); /
} else if ((f) <= 0x0B) { /
buf[0] = GC_CFILL_IMM | ((f) << 8) | 0x05; len = 6; /
buf[4] = (uint32_t)(c >> 32); /
buf[5] = (uint32_t)(c); /
} else { /
len = -ERR_IPF; break; /
} /
buf[1] = (x); buf[2] = (y); /
buf[3] = ((h) << 16) | ((w) & 0xffff); /
} while (0)
提交数据:
#define UPDATE_CMDBUF(context, len) /
do { /
DUMP_CMDBUF((context)->cmdbuf.cb_ptr, (len)); /
(context)->cmdbuf.cb_ptr += (len); /
(context)->cmdbuf.cb_len += ((len) << 2); /
if ((context)->cmdbuf.cb_len + CMDBUF_SAFE_ROOM > CMDBUF_SIZE) /
_m2d_submit((context), 0); /
} while (0)
再上层包括两个部分,gcu对m2d_lib进一步包装,给视频播放器调用的。copybit插件是给OpenGL调用的。
PXA300/310的2D图形加速
原创
©著作权归作者所有:来自51CTO博客作者ZLG李先静的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
cocos2d-x中的动作替换成Cocos creator 3.8中的Tween动画
文章简单介绍从Cocos2d-x向Cocos Creator转移过程中,原先的Action动作在Creator中如何实现。
Cocos Creator Cocos2d-x 动作 Tween -
java图形处理-Java 2D
Java 2D API分为以下几个包java.awt.geom 提供用于在与二维几何形状相关的对象上定义和执行操作的 Java
图形 java string 图像处理 image -
ios OC 1字节Byte转int
我先贴出最终转换的代码,再来进行一步一步的介绍:/** * 将int数值转换为占四个字节的byte数组 * @param value * 要转换的int值 * @return byte数组 */ public static byte[] intToBytes(int value ) { byte[] src =
ios OC 1字节Byte转int int转byte byte转int &oxff 运算符