S3C2416 2D加速----转载
2011-09-19 22:39
375 查看
S3C2416 2D加速 最近调试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(¶ms, (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-eclair 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 |
相关文章推荐
- S3C2416 2D加速
- S3C2416 2D加速
- 【转载】HAL Copybit 2D加速实例
- S3c2416中的2D加速在framebuffer的实现
- S3C2416 2D加速
- 百度“类人脑算法”研发加速(转载)
- 教你如何处理加速电脑速度(转载)
- 提高Linux上socket性能---加速网络应用程序(转载)
- android中使用2D动画 — SurfaceView 转载
- Starling------基于GPU加速的2D Flash API
- 【转载】通过数据库引擎来加速MySQL数据库
- 闪客工具:基于Flash 3D API Molehill 进行GPU加速2D的引擎
- 转载:什么是CDN及CDN加速原理
- 【转载】从零实现3D图像引擎:(2)画2D直线不简单
- [其他]VS2005SP1安装加速【转载】
- ARM S3C2416 800*600 LCD驱动----转载
- 使用Starling框架在Flash Builder里搭建第一个GPU加速的2D项目
- 闪客工具:基于Flash 3D API Molehill 进行GPU加速2D的引擎
- Android系统2D/3D硬件加速分析报告
- 五分钟使你的Firefox加速两倍(转载)