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
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
00093 ioctl(fd, PS3FB_IOCTL_ON, 0);
00094
00095
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
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
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197