• 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

  • 相关阅读:
    iview的modal点击确定消失(自动关闭)问题,自定义modal页脚
    vue实现组件数据双向绑定
    vue中封装svg-icon组件并使用
    闭包的概念
    vue基本集
    websocket
    99multiplication table
    h5c3增加了哪些新特性
    防抖与节流函数
    网页性能优化小技巧
  • 原文地址:https://www.cnblogs.com/leaven/p/2079933.html
Copyright © 2020-2023  润新知