Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4921236
  • 博文数量: 1169
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 14058
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
  • 认证徽章:
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1169)

文章存档

2019年(143)

2018年(81)

2017年(80)

2016年(70)

2015年(52)

2014年(41)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(288)

分类: LINUX

2010-09-15 11:06:41

http://hi.baidu.com/aokikyon/blog/item/0f8e857eaf285e340dd7da36.html
http://hi.baidu.com/aokikyon/blog/item/906ee2ca3db13f4af31fe740.html
http://hi.baidu.com/aokikyon/blog/item/8ca566439c8b871d9213c647.html
http://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 S3C6410
2010-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 next

const 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_BUFFER


return 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_BUFFER


return 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 window

params->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 area

cmm_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 area

cmm_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-cacheable


if (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 address

codec_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_DISPLAY


EGLDisplaySurface::EGLDisplaySurface()
    : EGLNativeSurface<EGLDisplaySurface>()
{
//构造函数没有变化

}

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 flip

mIndex = 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 next

const 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 <= DEFAULT_FB_NUM)

{
   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 S3C6410
2010-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 next
const 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_BUFFER

return 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_BUFFER

return 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 window
params->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 area
cmm_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 area
cmm_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-cacheable

if (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 address
codec_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_DISPLAY

EGLDisplaySurface::EGLDisplaySurface()
    : EGLNativeSurface()
{
//构造函数没有变化
}

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 flip
mIndex = 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 next
const 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 <= DEFAULT_FB_NUM)
{
   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;
}


阅读(3901) | 评论(0) | 转发(0) |
0

上一篇:emdebian for mini2440

下一篇:Gtk+的裁剪

给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册