/* * Copyright (C) 2006 Sony Computer Entertainment Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Sony Computer Entertainment Inc. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bitblt.h" #define FB_NAME "/dev/fb0" #define BPP 4 #define PIX 4 void prepare_buffer(void *addr, struct ps3fb_ioctl_res *res, uint32_t num_frames, int color) { uint32_t i; int x, y, x_size, y_size; uint32_t r, g, b; uint32_t *p; void *fb; x_size = res->xres - 2 * res->xoff; y_size = res->yres - 2 * res->yoff; for (i = 0; i < num_frames; i++) { fb = addr + (res->xres * res->yres * BPP) * i; // printf("addr:%d %p\n", i, fb); for (y = 0; y < y_size ; y++) { p = (uint32_t *)(fb + y * res->xres * BPP); for (x = 0; x < x_size ; x++) { if (color) { r = 0xff * (i & 0x01); g = 0xff * (i & 0x02); b = 0xff * !(i & 0x01); } else { r = 0xff * 0; g = 0xff * 0; b = 0xff * 0; } *p = (r << 16 | g << 8 | b); p++; } } } } // 32x16 (10x16) enum { e_ext_w = 32, e_ext_h = 16, e_int_w = 10, e_int_h = 16, }; static uint64_t g_chip[] aligned(128) = { 0x1000000000000000, 0x0000000000000000, 0x1100000000000000, 0x0000000000000000, 0x1210000000000000, 0x0000000000000000, 0x1331000000000000, 0x0000000000000000, 0x1444100000000000, 0x0000000000000000, 0x1555510000000000, 0x0000000000000000, 0x1666661000000000, 0x0000000000000000, 0x1777777100000000, 0x0000000000000000, 0x1888888810000000, 0x0000000000000000, 0x1999991111000000, 0x0000000000000000, 0x1aa1aa1000000000, 0x0000000000000000, 0x1b11bb1000000000, 0x0000000000000000, 0x11001cc100000000, 0x0000000000000000, 0x10001dd100000000, 0x0000000000000000, 0x00001ee100000000, 0x0000000000000000, 0x0000111100000000, 0x0000000000000000, }; static tlb4bpp_t g_tlb = { {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x8f, 0x4f, 0x0f, 0x4f, 0x8f, 0xcf, 0xff, 0xff}, {0x00, 0xff, 0xff, 0xcf, 0x8f, 0x4f, 0x0f, 0x4f, 0x8f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, {0x00, 0xff, 0x00, 0x4f, 0x8f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x8f, 0x4f, 0x0f, 0xff}, }; static bitmap_t g_bmp = { g_chip, // addr e_ext_w, // width e_ext_h, // height e_ext_w/2, // row bytes 0, // reserved }; void draw_chip(uint32_t x, uint32_t y, bitmap_t * dest_bmp) { bitblt4bpp( &g_bmp, // source bitmap 0, 0, // source x, y e_int_w, e_int_h, // source & destination w, h dest_bmp, // destination bitmap x, y, // destination x, y &g_tlb // color table ); } void draw_screen(int fd, int i, uint32_t num_frames, void *addr, struct ps3fb_ioctl_res *res) { uint32_t crt = 0; uint32_t frame; uint32_t x_size, y_size; frame = i % num_frames; x_size = res->xres - 2 * res->xoff; y_size = res->yres - 2 * res->yoff; bitmap_t screen = { addr + (res->xres * res->yres * BPP) * frame, // addr res->xres, // width res->yres, // height res->xres * BPP, // row bytes 0 // reserved }; /* wait for vsync interrupt */ ioctl(fd, FBIO_WAITFORVSYNC, (unsigned long)&crt); /* clear screen */ memset( screen.addr, 0, res->xres * y_size * BPP ); /* draw chip */ /* for ( int j = 0; j < 1000; j++ ) { uint32_t x = rand() % (x_size - e_int_w); uint32_t y = rand() % (y_size - e_int_h); draw_chip(x, y, &screen); for ( int k = 0; k < 16; k++ ) { g_tlb.r[k] = rand() % 256; g_tlb.g[k] = rand() % 256; g_tlb.b[k] = rand() % 256; } } */ draw_chip(i, i, &screen); /* blit and flip with vsync request */ ioctl(fd, PS3FB_IOCTL_FSEL, (unsigned long)&frame); } void sample1(int fd, uint32_t num_frames, void *addr, struct ps3fb_ioctl_res *res) { int i, j; for (j = 0; j < 4; j++) { for (i = 0; i < 0x80; i++) { draw_screen(fd, i, num_frames, addr, res); } for (i = 0x80; i >= 0; i--) { draw_screen(fd, i, num_frames, addr, res); } } } int main(int argc, char *argv[]) { int fd; int mode; void *addr; int length; struct ps3fb_ioctl_res res; struct fb_vblank vblank; uint32_t num_frames; mode = 1; printf("mode:%d\n", mode); /* open device */ if ((fd = open(FB_NAME, O_RDWR)) < 0) { printf("error open:%d\n", fd); return -1; } /* check capacity */ if (ioctl(fd, FBIOGET_VBLANK, (unsigned long)&vblank) < 0) { printf("FBIOGET_VBLANK\n"); goto end; } else if (!(vblank.flags & FB_VBLANK_HAVE_VSYNC)) { printf("no VSYNC\n"); goto end; } /* get screen info */ if (ioctl(fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0) { printf("PS3FB_IOCTL_SCREENINFO failed\n"); goto end; } printf("xres:%d yres:%d xoff:%d yoff:%d\n", res.xres, res.yres, res.xoff, res.yoff); if (mode == 2) num_frames = 1; else num_frames = res.num_frames; printf("num_frames:%d\n", num_frames); length = res.xres * res.yres * BPP * num_frames - res.xres * res.yoff * BPP * 2; /* top and bottom margins */ addr = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, 0); if (!addr) { printf("mmap failed\n"); goto end; } /* stop flipping in kernel thread with vsync*/ ioctl(fd, PS3FB_IOCTL_ON, 0); memset(addr, 0, length); /* draw */ if (mode < 3) { prepare_buffer(addr, &res, num_frames, 0); sample1(fd, num_frames, addr, &res); } /* start flipping in kernel thread with vsync*/ ioctl(fd, PS3FB_IOCTL_OFF, 0); munmap(NULL, length); end: /* close device */ close(fd); return 0; }