MercuryWindowFB.cpp

Go to the documentation of this file.
00001 #include "MercuryWindowFB.h"
00002 #include "MercuryLog.h"
00003 #include "MercuryDisplay.h"
00004     
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <unistd.h>
00008 #include <fcntl.h>
00009 #include <getopt.h>
00010 #include <string.h>
00011 #include <errno.h>
00012 #include <stdint.h>
00013 #include <sys/ioctl.h>
00014 #include <sys/mman.h>
00015 #include <linux/fb.h>
00016 #include <sys/time.h>
00017 #include <asm/ps3fb.h>
00018 
00019 #define FB_NAME "/dev/fb0"
00020 #define BPP 4
00021 
00022 MercuryWindowFB::MercuryWindowFB()
00023 :MercuryWindow(0,0,false)
00024 {
00025     LOG.Log("Video render: FRAMEBUFFER");
00026 }
00027 
00028 MercuryWindowFB::~MercuryWindowFB()
00029 {
00030     munmap(NULL, length);
00031     close(fd);
00032     DestroyWindowAndRender();
00033 }
00034 
00035 //FIGURE OUT HOW TO FORCEFULLY SET SIZE
00036 
00037 bool MercuryWindowFB::MakeWindow(const char* title, int width, int height, int bits, bool fullscreenflag)
00038 {
00039     
00040     struct ps3fb_ioctl_res res;
00041     struct fb_vblank vblank;        
00042 
00043     if ((fd = open(FB_NAME, O_RDWR)) < 0) 
00044     {
00045         LOG.Warn( ssprintf("error open for framebuffer:%d\n", fd) );
00046         return false;
00047     }
00048 
00049     if (ioctl(fd, FBIOGET_VBLANK, (unsigned long)&vblank) < 0)
00050     {
00051         LOG.Warn( "Cannot obtain VBLANK on framebuffer" );
00052         return false;
00053     }
00054     if (!(vblank.flags & FB_VBLANK_HAVE_VSYNC)) 
00055     {
00056         LOG.Warn("no VSYNC available on framebuffer");
00057         return false;
00058     }
00059 
00060     if (ioctl(fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0)
00061     {
00062         LOG.Warn( "Could not obtain screen resolution information" );
00063         return false;
00064     }
00065 
00066     width = res.xres - 2 * res.xoff;
00067     height = res.yres - res.yoff;
00068     bits = 8 * BPP;
00069 
00070     SetTitle(title);
00071     m_width = width;
00072     m_height  = height;
00073     m_bits = bits;
00074 
00075     if( m_RT == RT_OGL )
00076     {
00077         LOG.Warn( "You cannot run the framebuffer using hardware-accelerated OpenGL" );
00078     }
00079     if( m_RT == RT_SW )
00080     {
00081         unsigned char *addr;
00082         length = width * height * BPP * 2;
00083         addr = (unsigned char*)mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, 0);
00084         if( !addr )
00085         {
00086             LOG.Warn( "Cannot mmap the ram necessiary for this!" );
00087             return false;
00088         }
00089         m_BackBuffer = (unsigned char*)addr;
00090         m_FrontBuffer = &((unsigned char*)addr)[length/2];
00091 
00092         // stop flipping in kernel thread with vsync
00093         ioctl(fd, PS3FB_IOCTL_ON, 0);
00094 
00095         // black out the buffers
00096         memset(addr, 0x00, length/2);
00097         memset(&addr[length/2], 0xFF, length/2);
00098 
00099         m_iFrame=0;
00100 
00101         return true;
00102     }
00103     return false;
00104 }
00105 
00106 void MercuryWindowFB::DestroyWindow()
00107 {
00108 }
00109 
00110 void MercuryWindowFB::SwapBuffersInternal() 
00111 {
00112     if( m_RT == RT_SW )
00113     {
00114         unsigned char * fr = (unsigned char*)GetBackDirectBuffer();
00115         for( unsigned i = 0; i < (m_height*m_width*4); i+=4 )
00116         {
00117             unsigned char a = fr[i];
00118             unsigned char b = fr[i+1];
00119             unsigned char c = fr[i+2];
00120             unsigned char d = fr[i+3];
00121             fr[i] = d;
00122             fr[i+1] = c;
00123             fr[i+2] = b;
00124             fr[i+3] = a;
00125         }
00126             //TO_ENDIAN( fr[i] );
00127         uint32_t crt = 0;
00128         uint32_t frame = m_iFrame;
00129         ioctl(fd, PS3FB_IOCTL_FSEL, (unsigned long)&frame);
00130         ioctl(fd, FBIO_WAITFORVSYNC, (unsigned long)&crt);
00131         m_iFrame = (m_iFrame)?0:1;
00132     }
00133 }
00134 
00135 bool MercuryWindowFB::Update(const float dTime)
00136 {
00137     return true;
00138 }
00139 
00140 bool MercuryWindowFB::HasFocus()
00141 {
00142     return true;
00143 }
00144 
00145 void MercuryWindowFB::DestroyWindowAndRender()
00146 {
00147 }
00148 
00149 bool MercuryWindowFB::RestoreDevice()
00150 {
00151     return true;
00152 }
00153 
00154 bool MercuryWindowFB::MakeRenderCurrent()
00155 {
00156     return true;
00157 }
00158 
00159 unsigned char * MercuryWindowFB::GetBackDirectBuffer()
00160 {
00161     return (unsigned char*)(m_iFrame)?m_FrontBuffer:m_BackBuffer;
00162 }
00163 
00164 bool MercuryWindowFB::MakeRender(const char* title, int width, int height, int bits, bool fullscreenflag, RendererType rt )
00165 {
00166     m_RT = rt;
00167     return MakeWindow(title, width, height,bits, fullscreenflag);
00168 }
00169 
00170 /* 
00171  * Copyright (C) 2006  Sony Computer Entertainment Inc.
00172  * Copyright (c) 2005-2006, Charles Lohr
00173  * All rights reserved.
00174  *
00175  * Redistribution and use in source and binary forms, with or
00176  * without modification, are permitted provided that the following
00177  * conditions are met:
00178  *  -   Redistributions of source code must retain the above
00179  *      copyright notice, this list of conditions and the following disclaimer.
00180  *  -   Redistributions in binary form must reproduce the above copyright
00181  *      notice, this list of conditions and the following disclaimer in
00182  *      the documentation and/or other materials provided with the distribution.
00183  *  -   Neither the name of the Mercury Engine nor the names of its
00184  *      contributors may be used to endorse or promote products derived from
00185  *      this software without specific prior written permission.
00186  *
00187  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00188  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00189  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00190  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00191  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00192  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00193  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00194  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00195  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00196  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00197  */

Hosted by SourceForge.net Logo