intmapFrameBufferLocked(structprivate_module_t*module) { // already initialized... if(module->framebuffer){ return0; } charconst*constdevice_template[]={ "/dev/graphics/fb%u", "/dev/fb%u", 0};
intfd=-1; inti=0; charname[64]; while((fd==-1)&&device_template[i]){ snprintf(name,64,device_template[i],0); fd=open(name,O_RDWR,0); i++; } if(fd<0) return-errno;
structfb_fix_screeninfo finfo; if(ioctl(fd,FBIOGET_FSCREENINFO,&finfo)==-1) return-errno; structfb_var_screeninfo info; if(ioctl(fd,FBIOGET_VSCREENINFO,&info)==-1) return-errno; info.reserved[0]=0; info.reserved[1]=0; info.reserved[2]=0; info.xoffset=0; info.yoffset=0; info.activate=FB_ACTIVATE_NOW; /* * Explicitly request 5/6/5 */ info.bits_per_pixel=16; info.red.offset=11; info.red.length=5; info.green.offset=5; info.green.length=6; info.blue.offset=0; info.blue.length=5; info.transp.offset=0; info.transp.length=0;
/* * Request NUM_BUFFERS screens (at lest 2 for page flipping) */ info.yres_virtual=info.yres*NUM_BUFFERS; uint32_tflags=PAGE_FLIP; if(ioctl(fd,FBIOPUT_VSCREENINFO,&info)==-1){ info.yres_virtual=info.yres; flags&=~PAGE_FLIP; LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); } if(info.yres_virtual<info.yres*2){ // we need at least 2 for page-flipping info.yres_virtual=info.yres; flags&=~PAGE_FLIP; LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual,info.yres*2); } if(ioctl(fd,FBIOGET_VSCREENINFO,&info)==-1) return-errno; intrefreshRate=1000000000000000LLU/ ( uint64_t(info.upper_margin+info.lower_margin+info.yres) *(info.left_margin+info.right_margin+info.xres) *info.pixclock ); if(refreshRate==0){ // bleagh, bad info from the driver refreshRate=60*1000;// 60 Hz } if(int(info.width)<=0||int(info.height)<=0){ // the driver doesn't return that information // default to 160 dpi info.width=((info.xres*25.4f)/160.0f+0.5f); info.height=((info.yres*25.4f)/160.0f+0.5f); } floatxdpi=(info.xres*25.4f)/info.width; floatydpi=(info.yres*25.4f)/info.height; floatfps=refreshRate/1000.0f; LOGI("using (fd=%d)\n" "id = %s\n" "xres = %d px\n" "yres = %d px\n" "xres_virtual = %d px\n" "yres_virtual = %d px\n" "bpp = %d\n" "r = %2u:%u\n" "g = %2u:%u\n" "b = %2u:%u\n", fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset,info.red.length, info.green.offset,info.green.length, info.blue.offset,info.blue.length );
LOGI("width = %d mm (%f dpi)\n" "height = %d mm (%f dpi)\n" "refresh rate = %.2f Hz\n", info.width,xdpi, info.height,ydpi, fps ); if(ioctl(fd,FBIOGET_FSCREENINFO,&finfo)==-1) return-errno; if(finfo.smem_len<=0) return-errno; module->flags=flags; module->info=info; module->finfo=finfo; module->xdpi=xdpi; module->ydpi=ydpi; module->fps=fps; /* * map the framebuffer */ interr; size_tfbSize=roundUpToPageSize(finfo.line_length*info.yres_virtual);//对齐页 module->framebuffer=newprivate_handle_t(dup(fd),fbSize,0);
module->numBuffers=info.yres_virtual/info.yres; module->bufferMask=0;
void*vaddr=mmap(0,fbSize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if(vaddr==MAP_FAILED){ LOGE("Error mapping the framebuffer (%s)",strerror(errno)); return-errno; } module->framebuffer->base=intptr_t(vaddr); memset(vaddr,0,fbSize); return0; } |