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> #define DOUBLEBUF 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, 320, 240, 16, 0, 0, 0, 0); uint32_t cnt = 0; uint32_t col[] = {0xf800, 0x7e0, 0x001f}; while(cnt < 600){ cnt+= 1; SDL_FillRect(screen, &screen->clip_rect, col[cnt % 3]); GFX_Flip(screen); SDL_Delay(1000 / 60); } GFX_FreeSurface(screen); GFX_Quit(); SDL_Quit(); return 0; }