http://hi.baidu.com/aokikyon/blog/item/0f8e857eaf285e340dd7da36.htmlhttp://hi.baidu.com/aokikyon/blog/item/906ee2ca3db13f4af31fe740.htmlhttp://hi.baidu.com/aokikyon/blog/item/8ca566439c8b871d9213c647.htmlhttp://www.google.com/codesearch/p?hl=zh-CN#2IXyam9IX44/drivers/video/samsung/s3cfb_fimd4x.c&q=S3C_FB_OSD_SET_INFO&d=0其实就是双BUFFER惹的祸, 其实只要框架和驱动配合好就OK。驱动部分在git://github.com/leshak/i5700-leshak-kernel.git中的driver/video/samsung 中已经实现可以参考。框架部分 参考 http://hi.baidu.com/aokikyon/blog/item/0f8e857eaf285e340dd7da36.html。EGLDisplaySurface分析(3)——for S3C64102010-04-04 20:10//这是较早的一份三星修改的6410代码,以适应其寄存器。//这里列出的代码是改动较大的部分//怀疑实现时用了None PAGE FLIP,即copy2VirtualDoubleBuffer的硬件加速方法uint32_t EGLDisplaySurface::swapBuffers()//swapbuffers并没有用到copybit{    /* If we can't do the page_flip, just copy the back buffer to the front */    if (!(mFlags & PAGE_FLIP)){   int dev_index = getIndexOfFB(mFb[1].format);   if(copy2VirtualDoubleBuffer(dev_index) 0)//diff 这儿要注意,如果没有PAGE FLIP,不是直接拷贝,而是调用该函数   {    LOGE("%s::copy2VirtualDoubleBuffer fail\n", __func__);    return -errno;   }       return 0;    }    // do the actual flip    mIndex = 1 - mIndex;    mInfo.activate = FB_ACTIVATE_VBL;mInfo.yoffset = mIndex ? mInfo.yres : 0;#if 0//diff这儿注意,不去调用FBIOPUT_VSCREENINFO,因为这个操作会重写显示寄存器,导致屏幕闪烁if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1){      LOGE("FBIOPUT_VSCREENINFO failed");      return 0;}#else// added by sy82.yoon - remove blinking window on S3C6410(2009.04.21)/*diff 注意,使用FBIOPAN_DISPLAY ,需要测试这种方法是否能够正常work*fb_pan_display()*s3cfb_pan_display()*s3cfb_set_buffer_address()*writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));Window 0’s buffer start address register, buffer 0*just only rewrite few regs*/if (ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo) 0){   LOGE("%s::FBIOPAN_DISPLAY fail(%s)", __func__, strerror(errno));   return 0;}  unsigned int crtc = 0;if(ioctl(egl_native_window_t::fd, FBIO_WAITFORVSYNC, &crtc) 0) {//s3cfb_wait_for_vsync->wait_event_interruptible_timeout   LOGE("%s::FBIO_WAITFORVSYNC fail(%s)", __func__, strerror(errno));   return 0;}#endif//update the address of the buffer to draw to nextconst GGLSurface& buffer = mFb[1 - mIndex];egl_native_window_t::offset = intptr_t(buffer.data) - egl_native_window_t::base;    mPageFlipCount++;    // We don't support screen-size changes for now    return 0;}status_t EGLDisplaySurface::mapFrameBuffer(){//... ...省略    if (flags & PAGE_FLIP)//有PAGE_FLIP{   unsigned int frame_size = finfo.line_length*info.yres;        offscreen[1] = (uint8_t*)buffer + frame_size;   m_FbPhysAddr[1] = finfo.smem_start + frame_size;    }else//使用VirtualDoubleBuffer 要调用CMM(Codec Memory Management))这个硬件{   offscreen[1] = createVirtualDoubleBuffer(info.xres_virtual, info.yres_virtual, info.bits_per_pixel,                                           finfo.smem_len,             fd, dev_index, ggl_color_format);   #ifdef HW_VIRTUAL_BUFFER   {    m_FbPhysAddr[1] = m_s3cCmm->phys_addr;   }   #endif // HW_VIRTUAL_BUFFER          if (offscreen[1] == 0)   {    LOGE("%s::createVirtualDoubleBuffer fail\n", __func__);            munmap(buffer, finfo.smem_len);            return NO_MEMORY;        }   memset(offscreen[1], 0, finfo.smem_len);}}// ----------------------------------------------------------------------------// s3c6410// 以下是为s3c6410添加的代码// ----------------------------------------------------------------------------unsigned char * EGLDisplaySurface::createVirtualDoubleBuffer(int width, int height, int bpp,                                                             unsigned int buffer_size,                                                             int fb_fd, int fb_index,                int ggl_color_format){//... ...省略#ifdef HW_VIRTUAL_BUFFER{   s3c_fb_next_info_t fb_info;   int g2d_colorformat = convertFormatGGL2G2d(ggl_color_format);//将GGL转换为G2d模式   if(createG2d(m_s3cG2d, g2d_colorformat) 0)//createG2d   {    LOGE("%s::createG2d fail\n", __func__);    return NULL;   }     if(createCmm(m_s3cCmm, fb_info.phy_start_addr, buffer_size) 0)//createCmm   {    LOGE("%s::createCmm fail\n", __func__);    return NULL;   }   virtual_buffer = m_s3cCmm->virt_addr;}#else{   virtual_buffer = (uint8_t*)malloc(buffer_size);}#endif // HW_VIRTUAL_BUFFERreturn virtual_buffer;}int EGLDisplaySurface::destroyVirtualDoubleBuffer(int fb_index){//卸载函数}int EGLDisplaySurface::copy2VirtualDoubleBuffer(int fb_index){#ifdef HW_VIRTUAL_BUFFER{    if(doG2D(m_s3cG2d, m_s3cCmm->phys_addr, m_s3cCmm->phys_addr_dst,//也可以用g2d加速方法           mInfo.xres, mInfo.yres) 0)   {    LOGE("%s::doG2D fail\n", __func__);    return -1;   }}#else{   memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);//这是android的默认模式}#endif // HW_VIRTUAL_BUFFERreturn 0;}// ----------------------------------------------------------------------------#ifdef HW_VIRTUAL_BUFFER// ----------------------------------------------------------------------------// s3c-g2d创建函数int EGLDisplaySurface::createG2d(s3c_g2d_t * s3c_g2d, int color_format){#define S3C_G2D_DEV_NAME "/dev/s3c-g2d"s3c_g2d->dev_fd = open(S3C_G2D_DEV_NAME, O_RDWR);s3c_g2d_params *params = &s3c_g2d->params;params->bpp_src = (G2D_COLOR_SPACE)color_format;params->bpp_dst = (G2D_COLOR_SPACE)color_format;params->alpha_mode = 0;params->alpha_val = 0;params->color_key_mode = 0;params->color_key_val = 0;return 0;}int EGLDisplaySurface::destroyG2d(s3c_g2d_t *s3c_g2d){close(s3c_g2d->dev_fd);s3c_g2d->dev_fd = 0;return 0;}//g2d真正的操作函数,2D引擎负责搬运,CMM负责管理内存int EGLDisplaySurface::doG2D(s3c_g2d_t * s3c_g2d, unsigned int src_addr, unsigned int dst_addr, u32 width, u32 height){s3c_g2d_params *params = &s3c_g2d->params;   params->src_base_addr = src_addr;//源地址params->src_full_width = width;params->src_full_height = height;params->src_start_x = 0;params->src_start_y = 0;params->src_work_width = width-1;params->src_work_height = height-1;  params->dst_base_addr = dst_addr;//目的地址params->dst_full_width = width;params->dst_full_height = height;params->dst_start_x = 0;params->dst_start_y = 0;params->dst_work_width = width-1;params->dst_work_height = height-1;  //initialize clipping windowparams->cw_x1 = 0;params->cw_y1 = 0;params->cw_x2 = width-1;params->cw_y2 = height-1;if(ioctl(s3c_g2d->dev_fd, S3C_G2D_ROTATOR_0, params) 0)//其实g2D只有一个S3C_G2D_ROTATOR_0函数{   LOGE("%s::S3C_G2D_ROTATOR fail\n", __func__);   return -1;}return 0;}// ----------------------------------------------------------------------------// s3c-cmm Codec Memory Management 创建函数int EGLDisplaySurface::createCmm (s3c_cmm_t * s3c_cmm, unsigned int phys_addr_dst, unsigned int size){CODEC_GET_PHY_ADDR_ARG codec_get_phy_addr_arg;unsigned char * cmm_cached_addr;unsigned char * cmm_non_cached_addr;#define CMM_DEVICE_DEV_NAME "/dev/s3c-cmm"s3c_cmm->dev_fd = open(CMM_DEVICE_DEV_NAME, O_RDWR | O_NDELAY);// Mapping cacheable memory areacmm_cached_addr = (unsigned char *)mmap(0, CODEC_CACHED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, s3c_cmm->dev_fd, 0);// Mapping non-cacheable memory areacmm_non_cached_addr = (unsigned char *)mmap(0, CODEC_NON_CACHED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, s3c_cmm->dev_fd, CODEC_CACHED_MEM_SIZE);s3c_cmm->alloc_arg.buffSize = size;s3c_cmm->alloc_arg.cached_mapped_addr = (unsigned int)cmm_cached_addr;s3c_cmm->alloc_arg.non_cached_mapped_addr = (unsigned int)cmm_non_cached_addr;s3c_cmm->alloc_arg.cacheFlag = 1; // 1: cacheable, 0: non-cacheableif (ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_MEM_ALLOC, &s3c_cmm->alloc_arg) == 0){   LOGE("IOCTL_CODEC_MEM_ALLOC fail \n");   return -1;}CODEC_CACHE_FLUSH_ARG codec_cache_flush_arg;codec_cache_flush_arg.u_addr = s3c_cmm->alloc_arg.out_addr;codec_cache_flush_arg.size = s3c_cmm->alloc_arg.buffSize;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_CACHE_FLUSH, &codec_cache_flush_arg);// Get physical addresscodec_get_phy_addr_arg.u_addr = s3c_cmm->alloc_arg.out_addr;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_GET_PHY_ADDR, &codec_get_phy_addr_arg);s3c_cmm->virt_addr = (unsigned char*)codec_get_phy_addr_arg.u_addr;s3c_cmm->phys_addr = (unsigned int)codec_get_phy_addr_arg.p_addr;s3c_cmm->phys_addr_dst = phys_addr_dst;return 0;}int EGLDisplaySurface::destroyCmm(s3c_cmm_t * s3c_cmm){codec_mem_free_arg.u_addr = s3c_cmm->alloc_arg.out_addr;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_MEM_FREE, codec_mem_free_arg);}#endif // HW_VIRTUAL_BUFFER============================================================================//这是另外一份三星修改的6410代码//同样列出的代码是改动较大的部分//已经没有copy2VirtualDoubleBuffer硬件加速方法,swapbuffer使用PAN_DISPLAYEGLDisplaySurface::EGLDisplaySurface()    : EGLNativeSurfaceEGLDisplaySurface>(){//构造函数没有变化}EGLDisplaySurface::~EGLDisplaySurface(){//析构多了以下内容if(2 = DEFAULT_FB_NUM){   if(ioctl(egl_native_window_t::fd, S3C_FB_OSD_STOP) 0)    LOGE("%s::S3C_FB_OSD_SET_INFO error\n", __func__);}}uint32_t EGLDisplaySurface::swapBuffers(){//swapbuffer函数主要是将ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo)//修改为ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo)//nocite!我测试时会报错!/* If we can't do the page_flip, just copy the back buffer to the front */if (!(mFlags & PAGE_FLIP)){   memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);   return 0;}// do the actual flipmIndex = 1 - mIndex;mInfo.activate = FB_ACTIVATE_VBL;mInfo.yoffset = mIndex ? mInfo.yres : 0;if (ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo) 0){   LOGE("%s::FBIOPAN_DISPLAY fail(%s)", __func__, strerror(errno));   return 0;}unsigned int crtc = 0;if(ioctl(egl_native_window_t::fd, FBIO_WAITFORVSYNC, &crtc) 0){   LOGE("%s::FBIO_WAITFORVSYNC fail(%s)", __func__, strerror(errno));   return 0;}// update the address of the buffer to draw to nextconst GGLSurface& buffer = mFb[1 - mIndex];egl_native_window_t::offset = intptr_t(buffer.data) - egl_native_window_t::base;    mPageFlipCount++;    // We don't support screen-size changes for now    return 0;}status_t EGLDisplaySurface::mapFrameBuffer(){char const * const device_template[] = {    "/dev/graphics/fb%u",    "/dev/fb%u",    0 };int fd = -1;int i=0;char name[64];int ggl_color_format = GGL_PIXEL_FORMAT_RGB_565;int dev_index = DEFAULT_FB_NUM;//初始化时多了一些OSD内容if(ioctl(fd, S3C_FB_VS_START) 0){   LOGE("%s::S3C_FB_VS_START fail\n", __func__);   return -errno;}if(ioctl(fd, S3C_FB_SET_VSYNC_INT) 0){   LOGE("%s::S3C_FB_SET_VSYNC_INT fail\n", __func__);   return -errno;}//if(2{   s3c_win_info_t s3c_win_info;   s3c_win_info.left_x = 0;   s3c_win_info.top_y = 0;   s3c_win_info.width = info.xres;   s3c_win_info.height = info.yres;   s3c_win_info.bpp = info.bits_per_pixel;   if (ioctl(fd, S3C_FB_OSD_SET_INFO, &s3c_win_info) 0)   {    LOGE("%s::S3C_FB_OSD_SET_INFO error\n", __func__);    return -errno;   }   if (ioctl(fd, S3C_FB_OSD_START) 0)   {    LOGD("%s::S3C_FB_OSD_START error\n", __func__);    return -errno;   }}return fd;}EGLDisplaySurface分析(3)——for S3C64102010-04-04 20:10//这是较早的一份三星修改的6410代码,以适应其寄存器。//这里列出的代码是改动较大的部分//怀疑实现时用了None PAGE FLIP,即copy2VirtualDoubleBuffer的硬件加速方法uint32_t EGLDisplaySurface::swapBuffers()//swapbuffers并没有用到copybit{    /* If we can't do the page_flip, just copy the back buffer to the front */    if (!(mFlags & PAGE_FLIP)){   int dev_index = getIndexOfFB(mFb[1].format);   if(copy2VirtualDoubleBuffer(dev_index)   {    LOGE("%s::copy2VirtualDoubleBuffer fail\n", __func__);    return -errno;   }       return 0;    }    // do the actual flip    mIndex = 1 - mIndex;    mInfo.activate = FB_ACTIVATE_VBL;mInfo.yoffset = mIndex ? mInfo.yres : 0;#if 0//diff这儿注意,不去调用FBIOPUT_VSCREENINFO,因为这个操作会重写显示寄存器,导致屏幕闪烁if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1){        LOGE("FBIOPUT_VSCREENINFO failed");      return 0;}#else// added by sy82.yoon - remove blinking window on S3C6410(2009.04.21)/*diff 注意,使用FBIOPAN_DISPLAY ,需要测试这种方法是否能够正常work*fb_pan_display()*s3cfb_pan_display()*s3cfb_set_buffer_address()*writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));Window 0’s buffer start address register, buffer 0*just only rewrite few regs*/if (ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo){   LOGE("%s::FBIOPAN_DISPLAY fail(%s)", __func__, strerror(errno));     return 0;}  unsigned int crtc = 0;if(ioctl(egl_native_window_t::fd, FBIO_WAITFORVSYNC, &crtc)//s3cfb_wait_for_vsync->wait_event_interruptible_timeout   LOGE("%s::FBIO_WAITFORVSYNC fail(%s)", __func__, strerror(errno));     return 0;}#endif//update the address of the buffer to draw to nextconst GGLSurface& buffer    = mFb[1 - mIndex];egl_native_window_t::offset = intptr_t(buffer.data) - egl_native_window_t::base;    mPageFlipCount++;    // We don't support screen-size changes for now    return 0;}status_t EGLDisplaySurface::mapFrameBuffer(){//... ...省略    if (flags & PAGE_FLIP)//有PAGE_FLIP{   unsigned int frame_size = finfo.line_length*info.yres;        offscreen[1]    = (uint8_t*)buffer + frame_size;   m_FbPhysAddr[1] = finfo.smem_start + frame_size;    }else//使用VirtualDoubleBuffer 要调用CMM(Codec Memory Management))这个硬件{   offscreen[1] = createVirtualDoubleBuffer(info.xres_virtual, info.yres_virtual, info.bits_per_pixel,                                           finfo.smem_len,             fd, dev_index, ggl_color_format);   #ifdef HW_VIRTUAL_BUFFER   {    m_FbPhysAddr[1] = m_s3cCmm->phys_addr;   }   #endif // HW_VIRTUAL_BUFFER          if (offscreen[1] == 0)   {    LOGE("%s::createVirtualDoubleBuffer fail\n", __func__);            munmap(buffer, finfo.smem_len);            return NO_MEMORY;        }   memset(offscreen[1], 0, finfo.smem_len);}}// ----------------------------------------------------------------------------// s3c6410// 以下是为s3c6410添加的代码// ----------------------------------------------------------------------------unsigned char * EGLDisplaySurface::createVirtualDoubleBuffer(int width, int height, int bpp,                                                             unsigned int buffer_size,                                                             int fb_fd, int fb_index,                int ggl_color_format){//... ...省略#ifdef HW_VIRTUAL_BUFFER{   s3c_fb_next_info_t fb_info;   int g2d_colorformat = convertFormatGGL2G2d(ggl_color_format);//将GGL转换为G2d模式   if(createG2d(m_s3cG2d, g2d_colorformat)   {    LOGE("%s::createG2d fail\n", __func__);    return NULL;   }     if(createCmm(m_s3cCmm, fb_info.phy_start_addr, buffer_size)   {    LOGE("%s::createCmm fail\n", __func__);    return NULL;   }   virtual_buffer = m_s3cCmm->virt_addr;}#else{   virtual_buffer = (uint8_t*)malloc(buffer_size);}#endif // HW_VIRTUAL_BUFFERreturn virtual_buffer;}int EGLDisplaySurface::destroyVirtualDoubleBuffer(int fb_index){//卸载函数}int EGLDisplaySurface::copy2VirtualDoubleBuffer(int fb_index){#ifdef HW_VIRTUAL_BUFFER{    if(doG2D(m_s3cG2d, m_s3cCmm->phys_addr, m_s3cCmm->phys_addr_dst,//也可以用g2d加速方法           mInfo.xres, mInfo.yres)   {    LOGE("%s::doG2D fail\n", __func__);    return -1;   }}#else{   memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);//这是android的默认模式}#endif // HW_VIRTUAL_BUFFERreturn 0;}// ----------------------------------------------------------------------------#ifdef HW_VIRTUAL_BUFFER// ----------------------------------------------------------------------------// s3c-g2d创建函数int EGLDisplaySurface::createG2d(s3c_g2d_t * s3c_g2d, int color_format){#define S3C_G2D_DEV_NAME "/dev/s3c-g2d"s3c_g2d->dev_fd = open(S3C_G2D_DEV_NAME, O_RDWR);s3c_g2d_params *params = &s3c_g2d->params;params->bpp_src        = (G2D_COLOR_SPACE)color_format;params->bpp_dst        = (G2D_COLOR_SPACE)color_format;params->alpha_mode     = 0;params->alpha_val      = 0;params->color_key_mode = 0;params->color_key_val = 0;return 0;}int EGLDisplaySurface::destroyG2d(s3c_g2d_t *s3c_g2d){close(s3c_g2d->dev_fd);s3c_g2d->dev_fd = 0;return 0;}//g2d真正的操作函数,2D引擎负责搬运,CMM负责管理内存int EGLDisplaySurface::doG2D(s3c_g2d_t * s3c_g2d, unsigned int src_addr, unsigned int dst_addr, u32 width, u32 height){s3c_g2d_params *params = &s3c_g2d->params;   params->src_base_addr   = src_addr;//源地址params->src_full_width = width;params->src_full_height = height;params->src_start_x     = 0;params->src_start_y     = 0;params->src_work_width = width-1;params->src_work_height = height-1;  params->dst_base_addr   = dst_addr;//目的地址params->dst_full_width = width;params->dst_full_height = height;params->dst_start_x     = 0;params->dst_start_y     = 0;params->dst_work_width = width-1;params->dst_work_height = height-1;  //initialize clipping windowparams->cw_x1 = 0;params->cw_y1 = 0;params->cw_x2 = width-1;params->cw_y2 = height-1;if(ioctl(s3c_g2d->dev_fd, S3C_G2D_ROTATOR_0, params){   LOGE("%s::S3C_G2D_ROTATOR fail\n", __func__);   return -1;}return 0;}// ----------------------------------------------------------------------------// s3c-cmm Codec Memory Management 创建函数int EGLDisplaySurface::createCmm (s3c_cmm_t * s3c_cmm, unsigned int phys_addr_dst, unsigned int size){CODEC_GET_PHY_ADDR_ARG codec_get_phy_addr_arg;unsigned char * cmm_cached_addr;unsigned char * cmm_non_cached_addr;#define CMM_DEVICE_DEV_NAME "/dev/s3c-cmm"s3c_cmm->dev_fd = open(CMM_DEVICE_DEV_NAME, O_RDWR | O_NDELAY);// Mapping cacheable memory areacmm_cached_addr = (unsigned char *)mmap(0, CODEC_CACHED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, s3c_cmm->dev_fd, 0);// Mapping non-cacheable memory areacmm_non_cached_addr = (unsigned char *)mmap(0,CODEC_NON_CACHED_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,s3c_cmm->dev_fd, CODEC_CACHED_MEM_SIZE);s3c_cmm->alloc_arg.buffSize               = size;s3c_cmm->alloc_arg.cached_mapped_addr     = (unsigned int)cmm_cached_addr;s3c_cmm->alloc_arg.non_cached_mapped_addr = (unsigned int)cmm_non_cached_addr;s3c_cmm->alloc_arg.cacheFlag              = 1; // 1: cacheable, 0: non-cacheableif (ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_MEM_ALLOC, &s3c_cmm->alloc_arg) == 0){   LOGE("IOCTL_CODEC_MEM_ALLOC fail \n");   return -1;}CODEC_CACHE_FLUSH_ARG codec_cache_flush_arg;codec_cache_flush_arg.u_addr = s3c_cmm->alloc_arg.out_addr;codec_cache_flush_arg.size   = s3c_cmm->alloc_arg.buffSize;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_CACHE_FLUSH, &codec_cache_flush_arg);// Get physical addresscodec_get_phy_addr_arg.u_addr = s3c_cmm->alloc_arg.out_addr;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_GET_PHY_ADDR, &codec_get_phy_addr_arg);s3c_cmm->virt_addr = (unsigned char*)codec_get_phy_addr_arg.u_addr;s3c_cmm->phys_addr = (unsigned int)codec_get_phy_addr_arg.p_addr;s3c_cmm->phys_addr_dst = phys_addr_dst;return 0;}int EGLDisplaySurface::destroyCmm(s3c_cmm_t * s3c_cmm){codec_mem_free_arg.u_addr = s3c_cmm->alloc_arg.out_addr;ioctl(s3c_cmm->dev_fd, IOCTL_CODEC_MEM_FREE, codec_mem_free_arg);}#endif // HW_VIRTUAL_BUFFER============================================================================//这是另外一份三星修改的6410代码//同样列出的代码是改动较大的部分//已经没有copy2VirtualDoubleBuffer硬件加速方法,swapbuffer使用PAN_DISPLAYEGLDisplaySurface::EGLDisplaySurface()    : EGLNativeSurface(){//构造函数没有变化}EGLDisplaySurface::~EGLDisplaySurface(){//析构多了以下内容if(2{   if(ioctl(egl_native_window_t::fd, S3C_FB_OSD_STOP)    LOGE("%s::S3C_FB_OSD_SET_INFO error\n", __func__);}}uint32_t EGLDisplaySurface::swapBuffers(){//swapbuffer函数主要是将ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo)//修改为ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo)//nocite!我测试时会报错!/* If we can't do the page_flip, just copy the back buffer to the front */if (!(mFlags & PAGE_FLIP)){   memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);   return 0;}// do the actual flipmIndex = 1 - mIndex;mInfo.activate = FB_ACTIVATE_VBL;mInfo.yoffset = mIndex ? mInfo.yres : 0;if (ioctl(egl_native_window_t::fd, FBIOPAN_DISPLAY, &mInfo){     LOGE("%s::FBIOPAN_DISPLAY fail(%s)", __func__, strerror(errno));   return 0;}unsigned int crtc = 0;if(ioctl(egl_native_window_t::fd, FBIO_WAITFORVSYNC, &crtc){     LOGE("%s::FBIO_WAITFORVSYNC fail(%s)", __func__, strerror(errno));   return 0;}// update the address of the buffer to draw to nextconst GGLSurface& buffer    = mFb[1 - mIndex];egl_native_window_t::offset = intptr_t(buffer.data) - egl_native_window_t::base;    mPageFlipCount++;    // We don't support screen-size changes for now    return 0;}status_t EGLDisplaySurface::mapFrameBuffer(){char const * const device_template[] = {    "/dev/graphics/fb%u",    "/dev/fb%u",    0 };int fd = -1;int i=0;char name[64];int ggl_color_format = GGL_PIXEL_FORMAT_RGB_565;int dev_index = DEFAULT_FB_NUM;//初始化时多了一些OSD内容if(ioctl(fd, S3C_FB_VS_START){   LOGE("%s::S3C_FB_VS_START fail\n", __func__);   return -errno;}if(ioctl(fd, S3C_FB_SET_VSYNC_INT){   LOGE("%s::S3C_FB_SET_VSYNC_INT fail\n", __func__);   return -errno;}//if(2{   s3c_win_info_t s3c_win_info;   s3c_win_info.left_x = 0;   s3c_win_info.top_y = 0;   s3c_win_info.width = info.xres;   s3c_win_info.height = info.yres;   s3c_win_info.bpp    = info.bits_per_pixel;   if (ioctl(fd, S3C_FB_OSD_SET_INFO, &s3c_win_info)   {    LOGE("%s::S3C_FB_OSD_SET_INFO error\n", __func__);    return -errno;   }   if (ioctl(fd, S3C_FB_OSD_START)   {    LOGD("%s::S3C_FB_OSD_START error\n", __func__);    return -errno;   }}return fd;}
10-25 11:28
查看更多