zoukankan      html  css  js  c++  java
  • S3C2416 2D加速

    http://blog.csdn.net/zanget/archive/2010/11/18/6019528.aspx

    最近调试2D一忙就是2周,现在终于忙完了,要将之前的调试信息全部都写下来,可是不大可能的。

    当然,主要还是要驱动程序和 应用程序结合调试才能达到效果。

    最开始一直使用光栅(ROP),希望能达到想要的效果,结果却一直是出现颜色混合。。

    后来发现自己居然只使用到了FB0。。至于FB1....默认是关闭的;

    而2416上的关键色,要求是两个窗口叠加才能出现效果;这个主要是集中在处理OSD的时候,没能开启。汗一个先。。。

    关于加速显示的测试程序,在网上找到了几篇,比如

     http://apps.hi.baidu.com/share/detail/17513859

    虽然貌似不上架,很难使用,但是基本上思路还有的。

    根据需要,改成我自己驱动的情况:

    00001: #include <stdlib.h>

    00002: #include <stdio.h>

    00003: #include <string.h>

    00004: #include <unistd.h>

    00005: #include <fcntl.h>

    00006: #include <sys/ioctl.h>

    00007: #include <sys/types.h>

    00008: #include <sys/mman.h>

    00010: #include <errno.h>

    00012: #include <stdint.h> //uint32_t uint8_t

    00013: #include "s3c_g2d.h"

    00014: #include <linux/fb.h>

    00015:

    00016: #include <sys/stat.h>

    00017: #include <unistd.h>

    00018:

    00019: #include <sys/time.h>

    00020:

    00021: #include "def.h"

    00022:

    00023: /***********************************************************

    00024: * Global image file descriptor

    00025: ***********************************************************/

    00026: int g2d_fd;

    00027:

    00028: #ifdef FB0_OPERATION

    00029: int fb0_fd;

    00030: #endif

    00031:

    00032: int fb1_fd;

    00033:

    00034: struct fb_fix_screeninfo finfo;

    00035: struct fb_var_screeninfo info;

    00036:

    00037: void printHex(char * p, unsigned char * data, int len)

    00038: {

    00039:     int i;

    00040:     if(p)

    00041:     {

    00042:         printf("|%s|:[addr=%p][len=%d]:\n",p,data,len);

    00043:     }

    00044:     len = len>128 ? 128: len;

    00045:     for(i=0;i<len;i++)

    00046:     {

    00047:         printf("%02x,",data[i]);

    00048:         if((i+1)%16 ==0)

    00049:         printf("\n");

    00050:     }

    00051:     printf("|%s|\n\n",p);

    00052: }

    00053:

    00054: /*********************************************

    00055: * file operaton

    00056: **********************************************/

    00057: int open_file_image(char* file_name,int * file_fd,int * file_len)

    00058: {

    00059:     int rv;

    00060:     struct stat buf;

    00061:

    00062:     rv = stat (file_name,&buf);

    00063:     if(rv != 0 || buf.st_size < 1)

    00064:     {

    00065:        perror("stat");

    00066:     return -1;

    00067:     }

    00068:

    00069:     *file_len = buf.st_size;

    00070:

    00071:     *file_fd = open(file_name,O_RDWR);

    00072:     if((*file_fd) < 0)

    00073:     {

    00074:         perror("fopen");

    00075:         return -1;

    00076:     }

    00078:     return 0;

    00079: } ? end open_file_image ?

    00080:

    00081:

    00082: void fb_info()

    00083: {

    00084:     printf("using (fd=%d)\n"

    00085:     "id = %s\n"

    00086:     "xres = %d px\n"

    00087:     "yres = %d px\n"

    00088:     "xres_virtual = %d px\n"

    00089:     "yres_virtual = %d px\n"

    00090:     "bpp = %d\n"

    00091:     "r = %2u:%u\n"

    00092:     "g = %2u:%u\n"

    00093:     "b = %2u:%u\n"

    00094:     "smem_start = 0x%lx\n",

    00095:     fb1_fd ,

    00096:     finfo .id,

    00097:     info .xres,

    00098:     info .yres,

    00099:     info .xres_virtual,

    00100:     info .yres_virtual,

    00101:     info .bits_per_pixel,

    00102:     info .red.offset, info .red.length,

    00103:     info .green.offset, info .green.length,

    00104:     info .blue.offset, info .blue.length,

    00105:     finfo .smem_start

    00107:     );

    00108:

    00109: } ? end fb_info ?

    00110:

    00111: /*********************************************************

    00112: * g2d & fb init & mmap

    00113: **********************************************************/

    00114: unsigned int g2d_fb_init()

    00115: {

    00116:     s3c_color_key_info_t ckey;

    00117:     s3c_color_val_info_t cvalue;

    00118:     // s3c_win_info_t osd; //set for win0,win1, SET_OSD_INFO

    00119:

    00120:     int rv;

    00121:

    00122: ////////////////////////////////////////////////////////////////////////////////////

    00123:

    00124:     g2d_fd = open(S3C_G2D_DEV_NAME, O_RDWR);//open g2d

    00125:     if(g2d_fd <0)

    00126:     {

    00127:         perror("open S3C_G2D_DEV_NAME:");

    00128:         return -1;

    00129:     }

    00130:

    00131: #ifdef G2D_CUSTOMED

    00132: /*************************************************************

    00133: * G2D: color key and alpha

    00134: *************************************************************/

    00135: // G2D_NO_ALPHA = 0,

    00136: // G2D_PLANE_ALPHA,//fixed..

    00137: // G2D_PIXEL_ALPHA // with fallback to plane alpha

    00138:     rv = ioctl(g2d_fd , S3C_G2D_SET_BLENDING, G2D_PIXEL_ALPHA); //光栅 先于 S3C_G2D_SET_RASTER_OP

    00139:     if (rv != 0)

    00140:     {

    00141:        DBG("S3C_G2D_SET_BLENDING failed rv = %d, %s \n",rv, strerror(errno));

    00142:        return -2;

    00143:     }

    00144:

    00145:

    00146: //alpha = (ALPHA+1) / 256, blended: ALPHA_REG = 0xf

    00147: //win 1 透明度 //max 0xff

    00148:     rv = ioctl(g2d_fd , S3C_G2D_SET_ALPHA_VAL, 0xf);

    00149:     if (rv != 0)

    00150:     {

    00151:        DBG("set color key info error rv = %d, %s \n",rv, strerror(errno));

    00152:        return rv;

    00153:     }

    00154:

    00155: // #define G2D_ROP_SRC_ONLY (0xf0)

    00156: // #define G2D_ROP_3RD_OPRND_ONLY (0xaa) //make the screen black

    00157: // #define G2D_ROP_DST_ONLY (0xcc) //nothing.

    00158: // #define G2D_ROP_SRC_OR_DST (0xfc) //覆盖 以前的画面

    00159: // #define G2D_ROP_SRC_OR_3RD_OPRND (0xfa) // same as G2D_ROP_SRC_ONLY

    00160: // #define G2D_ROP_SRC_AND_DST (0xc0) //覆盖 以前的画面,但是更透明

    00161: // #define G2D_ROP_SRC_AND_3RD_OPRND (0xa0) //黑屏

    00162: // #define G2D_ROP_SRC_XOR_3RD_OPRND (0x5a) // same as G2D_ROP_SRC_ONLY

    00163: // #define G2D_ROP_DST_OR_3RD_OPRND (0xee) // nothing ?? same as G2D_ROP_SRC_ONLY ?

    00163: ?

    00164:

    00165: //G2D_ROP_SRC_OR_DST

    00166: //G2D_ROP_SRC_AND_DST

    00167:

    00168:     rv = ioctl(g2d_fd , S3C_G2D_SET_RASTER_OP, G2D_ROP_SRC_ONLY);//rop

    00169:     if (rv != 0)

    00170:     {

    00171:        DBG("S3C_G2D_SET_RASTER_OP failed rv = %d, %s \n",rv, strerror(errno));

    00172:        return -2;

    00173:     }

    00174:     #ifdef G2D_SET_TRANSFORM_90

    00175:     rv = ioctl(g2d_fd , S3C_G2D_SET_TRANSFORM, G2D_ROT_90);

    00176:     if (rv != 0)

    00177:     {

    00178:        DBG("g2d TRANSFORM error rv = %d, %s \n",rv, strerror(errno));

    00179:        return -1;

    00180:     }

    00181: #endif //G2D_SET_TRANSFORM_90

    00182:

    00183: #endif //G2D_CUSTOMED

    00184:

    00185: ////////////////////////////////////////////////////////////////////////////////////

    00186:

    00187:

    00188: #ifdef FB0_OPERATION

    00189: /*************************************************

    00190: * fb0 info

    00191: *************************************************/

    00192:     fb0_fd = open(S3C_FB0_DEV_NAME, O_RDWR);//open fb0

    00193:     if(fb0_fd <0)

    00194:     {

    00195:        DBG("open framebuffer device %s \n", strerror(errno));

    00196:        return -1;

    00197:     }

    00198: #endif //FB0_OPERATION

    00199:

    00200: ////////////////////////////////////////////////////////////////////////////////////

    00201:

    00202: /*************************************************

    00203: * fb1 info

    00204: *************************************************/

    00205:     fb1_fd = open(S3C_FB1_DEV_NAME, O_RDWR);//open fb1

    00206:     if(fb1_fd <0)

    00207:     {

    00208:         DBG("open framebuffer device %s \n", strerror(errno));

    00209:         return -1;

    00210:     }

    00211:     rv = ioctl(fb1_fd , FBIOGET_FSCREENINFO, &finfo );

    00212:     if (rv != 0)

    00213:     {

    00214:         DBG("%s get fix info error rv = %d, %s \n",__FUNCTION__,rv, strerror(errno));

    00215:         return -1;

    00216:     }

    00217:     rv = ioctl(fb1_fd , FBIOGET_VSCREENINFO, &info );

    00218:     if (rv != 0)

    00219:     {

    00220:         DBG("get var info error rv = %d, %s \n",rv, strerror(errno));

    00221:         return -1;

    00222:     }

    00223:

    00224: #ifdef FB1_CUSTOMED

    00225: /*************************************************

    00226: * OSD for fb1

    00227: *************************************************/

    00228:

    00229:     rv = ioctl(fb1_fd , SET_OSD_START);

    00230:     if (rv != 0)

    00231:     {

    00232:         DBG("set OSD Start error rv = %d, %s \n",rv, strerror(errno));

    00233:         return rv;

    00234:     }

    00235:

    00236:

    00237: /***********************************************************

    00238: * configure the color key to black and bg display

    00239: ************************************************************/

    00240:

    00241: /**

    00242: * set the blending mode and alpha1_R/G/B

    00243: */

    00244:     //0 Plane Blending & 1 Pixel Blending & chroma(color) key

    00245:     rv = ioctl(fb1_fd , SET_COLOR_ALPHA_MODE, 1);//Pixel Blending & chroma(color) key

    00246:     if (rv != 0)

    00247:     {

    00248:         DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));

    00249:         return rv;

    00250:     }

    00251:

    00252:     //color for win 1

    00253:     cvalue.colval_red = 0;

    00254:     cvalue.colval_green = 0;

    00255:     cvalue.colval_blue = 0;

    00256:     rv = ioctl(fb1_fd , SET_COLOR_ALPHA0_VALUE, &cvalue);

    00256:     //Pixel Blending & chroma(color) key

    00257:     if (rv != 0)

    00258:     {

    00259:        DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));

    00260:        return rv;

    00261:     }

    00262:

    00263:     //color for win 0

    00264:     cvalue.colval_red = 0xf;

    00265:     cvalue.colval_green = 0xf;

    00266:     cvalue.colval_blue = 0xf;

    00267:     rv = ioctl(fb1_fd , SET_COLOR_ALPHA1_VALUE, &cvalue);

    00267:     //Pixel Blending & chroma(color) key

    00268:     if (rv != 0)

    00269:     {

    00270:         DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));

    00271:         return rv;

    00272:     }

    00273:

    00274:     // direction = 0 means win1 is breen compared with color value

    00275:     ckey.direction = COLOR_KEY_DIR_FG_DISPLAY;

    00275:     //COLOR_KEY_DIR_BG_DISPLAY COLOR_KEY_DIR_FG_DISPLAY

    00276:     //each bit is set to 0 means that each bit in colval is been compared

    00277:     ckey.compkey_red = 0;

    00278:     ckey.compkey_green = 0;

    00279:     ckey.compkey_blue = 0;

    00280:     //set color key info to be compared in color value

    00281:     rv = ioctl(fb1_fd , SET_COLOR_KEY_INFO, &ckey);

    00282:     if (rv != 0)

    00283:     {

    00284:        DBG("set color key info error rv = %d, %s \n",rv, strerror(errno));

    00285:        return rv;

    00286:     }

    00287:

    00288:     cvalue.colval_red = 0;

    00289:     cvalue.colval_green = 0;

    00290:     cvalue.colval_blue = 0;

    00291:     //set color value

    00292:     rv = ioctl(fb1_fd , SET_COLOR_KEY_COLVAL, &cvalue);

    00293:     if (rv != 0)

    00294:     {

    00295:         DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));

    00296:         return rv;

    00297:     }

    00298:

    00299:

    00300:     //没用?????????????????????????????????????????????//

    00301:     //start color key KEYEN_F[25] Color Key Chroma Key( 浓度 色度 ) Enable control

    00302:     rv = ioctl(fb1_fd , SET_COLOR_KEY_START);

    00303:     if (rv != 0)

    00304:     {

    00305:         DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));

    00306:         return rv;

    00307:     }

    00308:

    00309:

    00310:     //start alpha of color key KEYBLEN D [26]=1:alpha value selected by

    00311:     // non-key area: alpha0_r/g/b

    00312:     // key area : alpha1_r/g/b

    00313:     rv = ioctl(fb1_fd , SET_COLOR_KEY_ALPHA_START);

    00314:     if (rv != 0)

    00315:     {

    00316:     DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));

    00317:     return rv;

    00318:     }

    00319:

    00320:     #endif //FB1_CUSTOMED

    00321:

    00322:     return 0;

    00323: } ? end g2d_fb_init ?

    00324:

    00325:

    00326: /*********************************************

    00327: * g2d implement

    00328: **********************************************/

    00329: int s3c_g2d_copy_buffer(struct s3c_g2d_req * req, unsigned long buffer_base, unsigned

    00329: long fb_base/*,

    00330: int x, int y, int w, int h*/)

    00331: {

    00332:     int rv;

    00333:     memset(req, 0, sizeof(struct s3c_g2d_req));

    00334:

    00335:

    00336:     req->src.w = SOURCE_WIDTH;

    00337:     req->src.h = SOURCE_HEIGHT;

    00338:     req->src.offs = 0;

    00339:     req->src.base = buffer_base;

    00340:     req->src.fmt = SOURCE_FMT;

    00341:

    00342:     req->src.l = 0;

    00343:     req->src.t = 0;

    00344:     req->src.r = req->src.w;

    00345:     req->src.b = req->src.h;

    00346:

    00347:     req->dst.w = DEST_WIDTH;

    00348:     req->dst.h = DEST_HEIGHT;

    00349:     req->dst.offs = 0;

    00350:     req->dst.base = fb_base;

    00351:     req->dst.fmt = DST_FMT;

    00352:

    00353:     req->dst.l = DST_LEFT_X;

    00354:     req->dst.t = DST_TOP_Y;

    00355:

    00356:     req->dst.r = DST_RIGHT_X;

    00357:     req->dst.b = DST_DOWN_Y;

    00358:

    00359:     rv = ioctl(g2d_fd , S3C_G2D_BITBLT, req);

    00360:     if (rv != 0)

    00361:     {

    00362:         DBG("S3C_G2D_BITBLT failed = %d", -errno);

    00363:         return -2;

    00364:     }

    00365:     // DBG("src base:0xx%u dst:base:0x%x\n",req->src.base,req->dst.base);

    00366:     return 0;

    00367: } ? end s3c_g2d_copy_buffer ?

    00368:

    00369: int main(int argc, char *argv[])

    00370: {

    00371:     u32 fb_phy;

    00372:     struct s3c_g2d_req params;

    00373:     int file_len,frame=0,rv,image_fd,times = 10;

    00374:

    00375:     struct timeval start,end;

    00376:     double timeuse;

    00377:     void * pmem_base /*, *fb_mem_map */;

    00378:     char * file_name = YUV_FILE;

    00379:

    00380:     if(argc >= 2)

    00381:     {

    00382:         file_name = argv[1];

    00383:         if(argc >= 3)

    00384:         times = atoi(argv[2]);

    00385:        DBG("Request Play times %d \n",times);

    00386:     }

    00387:

    00388: /* get framebuffer phyaddr */

    00389:     if(g2d_fb_init() != 0)

    00390:        return -3;

    00391:     fb_phy = finfo .smem_start;

    00392:

    00393: /* get pmem source addr */

    00394:     pmem_base = mmap(NULL, G2D_SFR_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, g2d_fd , 0);

    00395:     if(pmem_base == MAP_FAILED)

    00396:     {

    00397:        perror("mmap");

    00398:        return -1;

    00399:     }

    00400:     memset(pmem_base,0, G2D_SFR_SIZE);

    00401:

    00402:     DBG("pmem_base = %p\n",pmem_base);

    00403:

    00404:

    00405:     /* get image file */

    00406:     rv = open_file_image(file_name,&image_fd,&file_len);

    00407:     if(rv < 0)

    00408:     {

    00409:         return rv;

    00410:     }

    00411:

    00412:     DBG("File[%s], size[%d], Frame[%d]\n",file_name,file_len,file_len/G2D_SFR_SIZE);

    00413:

    00414:     sleep(1);

    00415:

    00416:

    00417:     gettimeofday(&start, NULL);

    00418:     while(1)

    00419:     {

    00420:     /* Start: read the content of the image file to the mem */

    00421:         rv = read(image_fd,pmem_base,G2D_SFR_SIZE);

    00422:         if(rv > 0)

    00423:         {

    00424:

    00425:             rv = s3c_g2d_copy_buffer(&params, (unsigned long)pmem_base, fb_phy);

    00426:             if(rv)

    00427:            break;

    00428:        }

    00429:        else

    00430:         {

    00431:            if(--times <= 0)

    00432:            break;

    00433:            lseek(image_fd,0,SEEK_SET);//seek to begin

    00434:        }

    00435:         frame++;

    00436:     // DBG("times=%d, frame=%d\n",times,frame);

    00437:     usleep(50000);

    00438:     } ? end while 1 ?

    00439:     gettimeofday(&end, NULL);

    00440:     timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;

    00441:     timeuse/=1000;

    00442:

    00443:     DBG("Total Frame[%d], Total Time[%2.1f] ms,Time Pre Frame[%2.1f] ms\n",frame,timeuse,timeuse/frame);

    00444:

    00445:

    00446:     //fb_info();

    00447:

    00448:     // printHex(file_name, pmem_base,128);

    00449:     close(image_fd);

    00450:     munmap(pmem_base,G2D_SFR_SIZE);

    00451:

    00452:

    00453:     close(g2d_fd );

    00454:     #ifdef FB0_OPERATION

    00455:     close(fb0_fd );

    00456:     #endif

    00457:     close(fb1_fd );

    00458:     return 0;

    00459:} ? end main ?

    00460:

    最终测试的效果,当然要 上传一张啦。。

    横着的条纹是win0, 竖着的条文是win1,COLVAL是黑色

    win0是显示整屏幕,win1只有1/2屏幕,也可想成是win0旋转+缩放后得到的。

    参考网站:

    http://lxr.post-tech.com/source/drivers/media/video/samsung/g2d/?v=linux-2.6.29-eclairhttp://apps.hi.baidu.com/share/detail/17513887http://blogold.chinaunix.net/u3/111323/showart_2200014.htmlhttp://apps.hi.baidu.com/share/detail/17513859

    http://apps.hi.baidu.com/share/detail/17513887

    http://blogold.chinaunix.net/u3/111323/showart_2200014.html

    http://apps.hi.baidu.com/share/detail/17513859

    下面是常见问题的总结:

    鱼 19:43:35

    请问你的测试代码里面 SOURCE_FMT 与 DST_FMT 颜色模式 是什么?

    鱼 19:43:45

    6410手册里面讲的太不清楚,有几个寄存器的设置他就没讲清楚甚至没讲!

        1、DST_BASE_ADDR和SRC_BASE_ADDR要设置物理地址。不能是内核的虚拟地址或者应用程序中的地址。对于FB,要使用 dma_alloc_writecombine 第三个参数返回的物理地址 fbi->fix.smem_start。

    鱼 19:56:26

    怎么要设置成物理地址啊?

    鱼 19:56:56

    目的地址是framebuff 地址 而源地址怎么设置啊?

    典当七秒的魚 08:55:36

    是 颜色模式。

    DST_FMT 是你驱动里使用的格式。像rgb565等。

     SOURCE_FMT  是你要显示的(在内存里)image的格式。

    至于硬件支持哪几种 可转换的,你要看看数据手册了。

    典当七秒的魚 08:57:37

    硬件能处理的只有物理地址吧。我想。

    因为你写进去的到下面寄存器的

    DST_BASE_ADDR和SRC_BASE_ADDR

    只能是物理 地址吧。。。这个地址是硬件能去访问的。

    硬件的搬运负责吧原地址SRC_BASE_ADDR的数据 经过6步转换后,显示在DST_BASE_ADDR里面。

    典当七秒的魚 08:58:45

    我想着就是为何要用物理地址的原因。

    你能找到 这个说明真的相当不错了

    我当时可是在这里郁闷了好几天。。

    因为 一直将虚拟地址写到  源地址。。

    操作完成后一直黑屏 。。

    鱼 09:09:59

    就是这个帖子啊

    http://blog.chinaunix.net/u3/111323/showart_2200014.html

    鱼 09:10:24

    那src_base 物理地址是怎么确定的呢?

    典当七秒的魚 09:15:54

    我是这样做的

    在初始化的时候就分配好可用的,共享的内存。和显存差不多大, 主要用于 应用层 放src Image

    驱动记录这个地址,并将其转换得到物理地址,用于src_base(其实,应用层会再次将此地址对应的虚拟地址写入,而驱动层将会舍弃此地址,因为是虚拟地址嘛),将虚拟地址传给应用层,应用层使用这个地址将src image写到这里地址(应用层能操作的就只能是虚拟地址,并且和内核层的不同。),因此对应的物理地址 的内容也相应的被应用填充了。

    鱼 09:17:21

    完全明白了 非常感谢

    鱼 09:18:17

    注:因为不知道如何将用户空间的虚拟地址转换为物理地址,只好在内核里面alloc了一块buffer s3c_g2d_userFB,每次都要用copy_from_user把图片先拷贝到s3c_g2d_userFB,再由2D搬到屏幕。

    大概测试过一下,一张800*600的图片 copy_from_user 用了大概 4ms。2D搬到屏幕上用了大概5~6ms。还是想把copy_from_user给剩了!

    鱼 09:18:39

    这是刚才那个帖子里面提到的 方法估计和你一样的

    典当七秒的魚 09:18:46

    一样

    典当七秒的魚 09:19:12

    每次都要用copy_from_user把图片先拷贝到s3c_g2d_userFB  这个不用 。

    鱼~BOBO 09:27:22

    昨晚我也尝试把mmap 返回的虚拟地址在内核空间转换成物理地址 也是不行 我想说的是在内核空间分配的buff(虚拟地址) 与 mmap 映射返回到用户空间的虚拟地址有何不同 如果相同的话 昨晚的尝试就应该是成功的 谢谢

    典当七秒的魚 09:31:40

    使用setpagereserved就行了吧。。


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zanget/archive/2010/11/18/6019528.aspx

  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/leaven/p/2079933.html
Copyright © 2011-2022 走看看