PXA300/310的2D圖形加速

來源:互聯網
上載者:User

轉載時請註明出處和作者連絡方式
文章出處:http://www.limodev.cn/blog
作者連絡方式:李先靜 <xianjimli at hotmail dot com>

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)<br />{<br /> volatile gcu_regs_t *gr = dev->gcu_regs;<br /> unsigned int tail_room, head_room;<br /> unsigned long exhead = gr->gcrbexhr;<br /> unsigned long tail = dev->ring_tail_dma;<br /> unsigned long base = dev->ring_addr_dma;<br /> unsigned long size = dev->ring_size;<br /> unsigned char *ring_addr = (unsigned char *)dev->ring_addr;</p><p> if (tail >= exhead) {<br /> tail_room = size - (tail - base);<br /> head_room = exhead - base;<br /> } else {<br /> tail_room = exhead - tail;<br /> head_room = 0;<br /> }</p><p> if (tail_room >= len) {<br /> if (copy_from_user(ring_addr + (tail - base),<br /> usrbuf, len))<br /> return -EFAULT;<br /> tail += len;<br />#ifdef FILL_NOP<br /> } else if (head_room >= len) {<br /> m2d_fill_nop(ring_addr + (tail - base), tail_room);<br />#else<br /> } else if (head_room + tail_room >= len) {<br /> if (copy_from_user(ring_addr + (tail - base),<br /> usrbuf, tail_room))<br /> return -EFAULT;<br /> usrbuf += tail_room; len -= tail_room;<br />#endif<br /> if (copy_from_user(ring_addr, usrbuf, len))<br /> return -EFAULT;<br /> tail = dev->ring_addr_dma + len;<br /> } else {<br /> return -ENOSPC;<br /> }</p><p> if (tail - base == size)<br /> tail = base;</p><p> switch_m2d_clk(1);<br /> dev->ring_tail_dma = tail;<br /> gr->gcrbtr = tail;</p><p> return 0;<br />}

執行完成後,GCU會通過中斷通知CPU:
static int m2d_gcu_irq(int irq, void *dev_id)<br />{<br /> struct m2d_device *dev = (struct m2d_device *)dev_id;<br /> volatile gcu_regs_t *gr = dev->gcu_regs;<br /> unsigned long status = gr->gciscr & gr->gciecr;</p><p> if (irq != IRQ_GRPHICS)<br /> return IRQ_NONE;</p><p> /* FIXME: what if this interrupt occurs with no current context<br /> * in execution<br /> */<br /> if (status & (GCISCR_PF_INTST | GCISCR_IIN_INTST<br /> | GCISCR_IOP_INTST))<br /> m2d_interrupt_err(dev, gr);<br /> if (status & GCISCR_EEOB_INTST)<br /> m2d_interrupt_eeob(dev, gr);</p><p> return IRQ_HANDLED;<br />}

再上層是函數庫,它對Graphics Controller提供的準系統進行封裝,然後通過/dev/m2d的ioctrl把命令發給Graphics Controller。

這裡的大部分函數的功能只是將資料打包,然後通過ioctrl把命令傳遞給驅動程式,如:

int m2d_color_fill(<br /> struct m2d_context *ctx,<br /> struct m2d_op_region *opr)<br />{<br /> int len = 0;</p><p> fprintf(stdout, "%s:%d/n", __func__, __LINE__);<br /> if (ctx == NULL) return -1;</p><p> CHECK_BOUNDARY( opr->dx0, opr->dy0,<br /> opr->width, opr->height,<br /> ctx->dstbuf);</p><p> SETUP_CFILL_IMM(ctx->cmdbuf.cb_ptr, len,<br /> opr->dx0, opr->dy0,<br /> opr->width, opr->height,<br /> ctx->fill_color_format,<br /> ctx->fill_color_value);</p><p> UPDATE_CMDBUF(ctx, len);<br /> fprintf(stdout, "%s:%d/n", __func__, __LINE__);<br /> return len;<br />}

打包資料:

#define SETUP_CFILL_IMM(buf, len, x, y, w, h, pf, c) /<br />do { /<br /> fprintf(stdout, "SETUP_CFILL_IMM: x=%d y=%d w=%d h=%d/n",x, y, w, h); /<br /> uint32_t f = GCU_PXLFMT_FORMAT(pf); /<br /> if ((f) < 0x0a) { /<br /> buf[0] = GC_CFILL_IMM | ((f) << 8) | 0x04; len = 5; /<br /> buf[4] = (uint32_t)(c); /<br /> } else if ((f) <= 0x0B) { /<br /> buf[0] = GC_CFILL_IMM | ((f) << 8) | 0x05; len = 6; /<br /> buf[4] = (uint32_t)(c >> 32); /<br /> buf[5] = (uint32_t)(c); /<br /> } else { /<br /> len = -ERR_IPF; break; /<br /> } /<br /> buf[1] = (x); buf[2] = (y); /<br /> buf[3] = ((h) << 16) | ((w) & 0xffff); /<br />} while (0)<br />
提交資料:

#define UPDATE_CMDBUF(context, len) /<br />do { /<br /> DUMP_CMDBUF((context)->cmdbuf.cb_ptr, (len)); /<br /> (context)->cmdbuf.cb_ptr += (len); /<br /> (context)->cmdbuf.cb_len += ((len) << 2); /<br /> if ((context)->cmdbuf.cb_len + CMDBUF_SAFE_ROOM > CMDBUF_SIZE) /<br /> _m2d_submit((context), 0); /<br />} while (0)

再上層包括兩個部分,gcu對m2d_lib進一步封裝,給視頻播放器調用的。copybit外掛程式是給OpenGL調用的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.