linux_fb_surf.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:11k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: linux_fb_surf.cpp,v 1.1.10.1 2004/07/09 01:59:14 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "minisite.h"
  50. #include "hxvsurf.h"
  51. #include "coloracc.h"
  52. #include "minisurf.h"
  53. #include "platform/unix/linux_fb_surf.h"
  54. #include "minifmt.h"
  55. //#include <unistd.h>
  56. #include <fcntl.h>
  57. #include <linux/fb.h>
  58. //#include <linux/kd.h>
  59. #include <sys/ioctl.h>
  60. #include <sys/mman.h>
  61. //#include <sys/time.h>
  62. //#include <sys/types.h>
  63. //#include <sys/select.h>
  64. static CFmtObj ImageHelper;
  65. CLinuxFrameBufferSurface::CLinuxFrameBufferSurface(IUnknown* pContext, 
  66.  CMiniBaseSite* pSite)
  67.     :  CMiniBaseSurface(pContext, pSite)
  68.     , m_nScreenNumber(0)
  69.     , m_unDepth(0)
  70.     , m_nBitsPerPixel(0)
  71.     , m_nCompositionSize(0)
  72.     , m_pCompositionSurface(NULL)
  73.     , m_frameBufferFD(-1)
  74.     , m_pFrameBuffer(0)
  75. {}
  76. CLinuxFrameBufferSurface::~CLinuxFrameBufferSurface()
  77. {
  78.     if (m_frameBufferFD != -1)
  79.     {
  80. m_pFrameBuffer = 0;
  81. close(m_frameBufferFD);
  82. m_frameBufferFD = -1;
  83.     }
  84.     HX_FREE(m_pCompositionSurface);
  85.     m_nCompositionSize  = 0;
  86.     m_nCompositionPitch = 0;
  87.     memset(&m_surfaceSize, 0, sizeof( m_surfaceSize ) );
  88. }
  89. HX_RESULT CLinuxFrameBufferSurface::_CreateDestBuffer(int cidIn,
  90.                                               int nWidth,
  91.                                               int nHeight,
  92.                                               int& nCount)
  93. {
  94.     HX_RESULT res = HXR_OK;
  95.     HX_ASSERT( m_pSite );
  96.     //HX_ASSERT( m_unDepth );
  97.     //For now, we just support 1 format
  98.     HX_ASSERT( cidIn == CID_I420 );
  99.     
  100.     //Get the size of this site.
  101.     m_pSite->GetSize(m_surfaceSize);
  102.     //Malloc the room to hold the actual bits.
  103.     HXBitmapInfo bmiTemp;
  104.     ImageHelper.MakeBitmap( &bmiTemp,
  105.                       sizeof(bmiTemp),
  106.                       GetDstCID(),
  107.                       m_surfaceSize.cx,
  108.                       m_surfaceSize.cy,
  109.                       NULL,
  110.                       0);
  111.     
  112.     m_nCompositionPitch = ImageHelper.GetBitmapPitch(&bmiTemp);
  113.     int imageSize = bmiTemp.bmiHeader.biSizeImage;
  114.     res = _ResizeVideoBuffer(imageSize);
  115.     HX_ASSERT( ImageHelper.GetBitmapColor(&bmiTemp) == GetDstCID() );
  116.     if (!m_pFrameBuffer)
  117.     {
  118. res = _OpenFrameBuffer();
  119.     }
  120.     
  121.     return res;
  122. }
  123.          
  124. HX_RESULT CLinuxFrameBufferSurface::_LockDestBuffer(UCHAR** ppDestPtr,
  125.        LONG32* pnDestPitch,
  126.        int& cid,
  127.        REF(HXxSize) srcSize,
  128.        int nIndex)
  129. {
  130.     *ppDestPtr = m_pCompositionSurface;
  131.     *pnDestPitch = m_nCompositionPitch;
  132.     cid = GetDstCID();
  133.     
  134.     return HXR_OK;
  135. }
  136.          
  137. HX_RESULT CLinuxFrameBufferSurface::_TransferToDestBuffer(UCHAR* pSrcBuffer,
  138.                                                   HXBitmapInfoHeader* pBitmapInfo,
  139.                                                   HXxRect* prSrcRect,
  140.                                                   HXxRect* prDstRect,
  141.                                                   UCHAR* pDstBuffer,
  142.                                                   LONG32 nDstPitch)
  143. {
  144.     HX_RESULT res = HXR_OK;
  145.     int nCidIn = ImageHelper.GetBitmapColor( (HXBitmapInfo*)pBitmapInfo );
  146.     //This minisite, as written, is just doing a blind I420->RGB32
  147.     //color convert. Feel free to add whatever you want...
  148.     HX_ASSERT( nCidIn == CID_I420 );
  149.     if( nCidIn == CID_I420 )
  150.     {
  151.         //This calls the m_fpColorConverter init'ed in the base class.
  152.         res =  CMiniBaseSurface::_TransferToDestBuffer(pSrcBuffer,
  153.                                                        pBitmapInfo,
  154.                                                        prSrcRect,
  155.                                                        prDstRect,
  156.                                                        pDstBuffer,
  157.                                                        nDstPitch);
  158.     }
  159.     return res;
  160. }
  161.          
  162. HX_RESULT CLinuxFrameBufferSurface::_UnlockDestBuffer(UCHAR* pSurfPtr, int nIndex=0)
  163. {
  164.     return HXR_OK;
  165. }
  166.          
  167. HX_RESULT CLinuxFrameBufferSurface::_RenderDestBuffer(HXxRect* prSrcRect,
  168.  HXxRect* prDestRect,
  169.  int nIndex)
  170. {
  171.     HX_RESULT res = HXR_FAILED;
  172.     int imgWidth  = prDestRect->right - prDestRect->left;
  173.     int imgHeight = prDestRect->bottom - prDestRect->top;
  174.     
  175.     if (m_pFrameBuffer)
  176.     {
  177. #ifdef HELIX_FEATURE_CC_RGB32out
  178. UINT32* pSrc = (UINT32*)m_pCompositionSurface;
  179. #elif defined(HELIX_FEATURE_CC_RGB565out)
  180. UINT16* pSrc = (UINT16*)m_pCompositionSurface;
  181. #endif
  182. UINT16* pDest = m_pFrameBuffer;
  183. int srcDelta = 0;
  184. int dstDelta = 0;
  185. // Compute how much of the image we want to copy
  186. int lines = (imgHeight < m_fbHeight) ? imgHeight : m_fbHeight;
  187. int copyWidth = imgWidth;
  188. if (imgWidth < m_fbWidth)
  189. {
  190.     dstDelta = m_fbWidth - imgWidth;
  191. }
  192. else if (imgWidth > m_fbWidth)
  193. {
  194.     srcDelta = imgWidth - m_fbWidth;
  195.     copyWidth = m_fbWidth;
  196. }
  197. // Center image
  198. int left = (m_fbWidth / 2) - (copyWidth / 2);
  199. int top = (m_fbHeight / 2) - (lines / 2);
  200. pDest += top * m_fbWidth + left;
  201. int i = 0;
  202. for (int y = 0; y < lines; y++)
  203. {
  204.     for (int x = 0; x < copyWidth; x++)
  205.     {
  206. #ifdef HELIX_FEATURE_CC_RGB32out
  207. // We need to convert RGB32 -> RGB565
  208. UINT32 src   = *pSrc++;
  209. UINT32 dst = (((src & 0x00f80000) >> 8) | 
  210.       ((src & 0x0000fc00) >> 5) | 
  211.       ((src & 0x000000f8) >> 3));
  212. *pDest++ = (UINT16)dst;
  213. #elif defined(HELIX_FEATURE_CC_RGB565out)
  214. *pDest++ = *pSrc++;
  215. #endif
  216.     }
  217.     pSrc += srcDelta;
  218.     pDest += dstDelta;
  219. }
  220. res = HXR_OK;
  221.     }
  222.     
  223.     return res;
  224. }
  225.          
  226. HX_RESULT CLinuxFrameBufferSurface::_DestroyDestBuffer(int cid, int nCount)
  227. {
  228.   HX_FREE(m_pCompositionSurface);
  229.     m_nCompositionSize  = 0;
  230.     m_nCompositionPitch = 0;
  231.     memset(&m_surfaceSize, 0, sizeof( m_surfaceSize ) );
  232.     
  233.     return HXR_OK;
  234. }
  235. int CLinuxFrameBufferSurface::GetDstCID(int nIndex)
  236. {
  237.     //Right now the mini site just always outputs in RGB32. 
  238. #ifdef HELIX_FEATURE_CC_RGB32out
  239.     return CID_RGB32;
  240. #elif defined(HELIX_FEATURE_CC_RGB565out)
  241.     return CID_RGB565;
  242. #endif
  243. }
  244. HX_RESULT CLinuxFrameBufferSurface::_ResizeVideoBuffer( INT32 nSize)
  245. {
  246.     HX_RESULT retVal=HXR_OK;
  247.     //XXXgfw. Trade off here. We can use lots of mem if we just return and
  248.     //the user has scaled the image up very much and then goes back down.
  249.     //If we don't just return we can do tons and tons of mallocs. Maybe we
  250.     //should add a timed callback to reclaim some of this mem after a few
  251.     //seconds.
  252.     if(nSize <= m_nCompositionSize)
  253.         return retVal;
  254.     if(m_pCompositionSurface == NULL)
  255.     {
  256.         m_pCompositionSurface = (UCHAR*) malloc(nSize);
  257.     }
  258.     else
  259.     {
  260.         m_pCompositionSurface = (UCHAR*) realloc(m_pCompositionSurface, nSize);
  261.     }
  262.     if( m_pCompositionSurface )
  263.     {
  264.         m_nCompositionSize = nSize;
  265.     }
  266.     else
  267.     {
  268.         HX_ASSERT("We can't alloc the composition surface." == NULL );
  269.         m_nCompositionSize = 0;
  270.     }
  271.     return retVal;
  272. }
  273. HX_RESULT CLinuxFrameBufferSurface::_OpenFrameBuffer()
  274. {
  275.     HX_RESULT res = HXR_FAILED;
  276.     struct fb_var_screeninfo vinfo;
  277.     struct fb_fix_screeninfo finfo;
  278.     char *fbp = 0;
  279.     int x = 0, y = 0;
  280.     long int location = 0;
  281.   /* Open the file for reading and writing */
  282.     m_frameBufferFD = open("/dev/fb0", O_RDWR);
  283.     if (m_frameBufferFD == -1) 
  284.     {
  285. printf("Error: cannot open framebuffer device.n");
  286.     }
  287.     else if (ioctl(m_frameBufferFD, FBIOGET_FSCREENINFO, &finfo)) 
  288.     {
  289. printf("Error reading fixed information.n");
  290.     }
  291.     else if (ioctl(m_frameBufferFD, FBIOGET_VSCREENINFO, &vinfo)) 
  292.     {
  293. printf("Error reading variable information.n");
  294.     }
  295.     else
  296.     {
  297. printf("xres:%i , yres:%i , BBP:%in ", 
  298.        vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
  299. m_fbWidth = vinfo.xres;
  300. m_fbHeight = vinfo.yres;
  301. int screen_size  = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
  302. /* Map the device to memory */
  303. m_pFrameBuffer = (UINT16*)mmap(0, screen_size, 
  304.        PROT_READ | PROT_WRITE, MAP_SHARED,
  305.        m_frameBufferFD, 0);       
  306. if ((int)m_pFrameBuffer == -1) 
  307.     printf("Error: failed to map framebuffer device to memory.n"); 
  308. }
  309. else
  310. {
  311.     res = HXR_OK;
  312. }
  313.     }
  314.     return res;
  315. }