main.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <SDL/SDL.h>
#include <mi_sys.h>
#include <mi_gfx.h>
int fd_fb = 0;
struct fb_fix_screeninfo finfo = {0};
struct fb_var_screeninfo vinfo = {0};
MI_PHY fb_phyAddr = {0};
MI_GFX_Surface_t stSrc = {0};
MI_GFX_Rect_t stSrcRect = {0};
MI_GFX_Surface_t stDst = {0};
MI_GFX_Rect_t stDstRect = {0};
MI_GFX_Opt_t stOpt = {0};
void GFX_Init(void)
{
if (fd_fb == 0) {
SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
MI_SYS_Init();
MI_GFX_Open();
fd_fb = open("/dev/fb0", O_RDWR);
ioctl(fd_fb, FBIOGET_FSCREENINFO, &finfo);
fb_phyAddr = finfo.smem_start;
ioctl(fd_fb, FBIOGET_VSCREENINFO, &vinfo);
vinfo.yoffset = 0;
ioctl(fd_fb, FBIOPUT_VSCREENINFO, &vinfo);
MI_SYS_MemsetPa(fb_phyAddr, 0, 640 * 480 * 4 * 2);
stDst.phyAddr = fb_phyAddr;
stDst.eColorFmt = E_MI_GFX_FMT_ARGB8888;
stDst.u32Width = 640;
stDst.u32Height = 480;
stDst.u32Stride = 640 * 4;
stDstRect.s32Xpos = 0;
stDstRect.s32Ypos = 0;
stDstRect.u32Width = 640;
stDstRect.u32Height = 480;
memset(&stOpt, 0, sizeof(stOpt));
stOpt.eSrcDfbBldOp = E_MI_GFX_DFB_BLD_ONE;
stOpt.eRotate = E_MI_GFX_ROTATE_180;
}
}
void GFX_Quit(void)
{
if (fd_fb) {
vinfo.yoffset = 0;
ioctl(fd_fb, FBIOPUT_VSCREENINFO, &vinfo);
close(fd_fb);
fd_fb = 0;
MI_GFX_Close();
MI_SYS_Exit();
}
}
#define pixelsPa unused1
SDL_Surface* GFX_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask)
{
SDL_Surface *surface;
MI_PHY phyAddr;
void *virAddr;
int pitch = width * uint32_t(depth/8);
uint32_t size = pitch * height;
MI_SYS_MMA_Alloc(NULL, size, &phyAddr);
MI_SYS_Mmap(phyAddr, size, &virAddr, TRUE);
surface = SDL_CreateRGBSurfaceFrom(virAddr,width,height,depth,pitch,Rmask,Gmask,Bmask,Amask);
if (surface != NULL) {
surface->pixelsPa = phyAddr;
}
return surface;
}
void GFX_FreeSurface(SDL_Surface *surface)
{
MI_PHY phyAddr = surface->pixelsPa;
void *virAddr = surface->pixels;
uint32_t size = surface->pitch * surface->h;
SDL_FreeSurface(surface);
if (phyAddr) {
MI_SYS_Munmap(virAddr, size);
MI_SYS_MMA_Free(phyAddr);
}
}
void GFX_ClearSurface(SDL_Surface *surface)
{
MI_SYS_MemsetPa(surface->pixelsPa,0,surface->pitch * surface->h);
}
void GFX_CopySurface(SDL_Surface *src, SDL_Surface *dst)
{
uint32_t size = src->pitch * src->h;
if (size == uint32_t(dst->pitch * dst->h)) {
MI_SYS_FlushInvCache(src->pixels, size);
MI_SYS_MemcpyPa(dst->pixelsPa,src->pixelsPa,size);
}
}
void GFX_Flip(SDL_Surface *surface)
{
MI_U16 u16Fence;
stSrc.phyAddr = surface->pixelsPa;
if (surface->format->BytesPerPixel == 2) {
stSrc.eColorFmt = E_MI_GFX_FMT_RGB565;
}
else {
stSrc.eColorFmt = E_MI_GFX_FMT_ARGB8888;
}
stSrc.u32Width = surface->w;
stSrc.u32Height = surface->h;
stSrc.u32Stride = surface->pitch;
stSrcRect.s32Xpos = 0;
stSrcRect.s32Ypos = 0;
stSrcRect.u32Width = stSrc.u32Width;
stSrcRect.u32Height = stSrc.u32Height;
#ifdef DOUBLEBUF
vinfo.yoffset ^= 480;
stDst.phyAddr = fb_phyAddr + (640 * vinfo.yoffset * 4);
#endif
MI_SYS_FlushInvCache(surface->pixels, surface->pitch * surface->h);
MI_GFX_BitBlit(&stSrc,&stSrcRect,&stDst,&stDstRect,&stOpt,&u16Fence);
MI_GFX_WaitAllDone(FALSE, u16Fence);
#ifdef DOUBLEBUF
ioctl(fd_fb, FBIOPAN_DISPLAY, &vinfo);
#endif
}
SDL_Surface *screen = NULL;
int main(int argc, char *argv[])
{
SDL_Rect rt = {0};
SDL_Init(SDL_INIT_VIDEO);
GFX_Init();
SDL_ShowCursor(0);
screen = GFX_CreateRGBSurface(0, 640, 480, 16, 0, 0, 0, 0);
SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xff, 0x00, 0x00));
rt.x = 50;
rt.y = 50;
rt.w = 30;
rt.h = 30;
SDL_FillRect(screen, &rt, SDL_MapRGB(screen->format, 0x00, 0xff, 0x00));
rt.x = 100;
rt.y = 100;
rt.w = 50;
rt.h = 100;
SDL_FillRect(screen, &rt, SDL_MapRGB(screen->format, 0x00, 0x00, 0xff));
GFX_Flip(screen);
SDL_Delay(3000);
GFX_FreeSurface(screen);
GFX_Quit();
SDL_Quit();
return 0;
}