fb.cpp
来自「Ray tracing on PS3, using the accelerati」· C++ 代码 · 共 224 行
CPP
224 行
/* Copyright (c) 2007 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * fb.cpp - Implementation for the frame buffer utility routines * @author Russel Ryan * @author Natalia Chernenko */#include "fb.h"#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <getopt.h>#include <string.h>#include <errno.h>#include <stdint.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <linux/fb.h>//#include <sys/time.h>#include <asm/ps3fb.h>int fd = -1;unsigned char *fb = NULL;unsigned char *fbs[2] = { NULL, NULL };unsigned char *fb_cur = NULL;unsigned int total_length=0, buffer_length=0;unsigned int mem_width=0, mem_height=0;unsigned int screen_width=0, screen_height=0;unsigned int cur_buffer=0;bool fb_init() { struct ps3fb_ioctl_res res; struct fb_vblank vblank; fd = open(FB_NAME, O_RDWR); if (fd < 0) { printf("error opening framebuffer\n"); return false; } if (ioctl(fd, FBIOGET_VBLANK, (unsigned long)&vblank) < 0) { printf("FBIOGET_VBLANK\n"); close(fd); return false; } else if (!(vblank.flags & FB_VBLANK_HAVE_VSYNC)) { printf("no VSYNC\n"); close(fd); return false; } if (ioctl(fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res) < 0) { printf("PS3FB_IOCTL_SCREENINFO failed\n"); close(fd); return false; } //printf("xres: %d, yres: %d, xoff: %d, yoff: %d num_frames: %d\r\n", // res.xres, res.yres, res.xoff, res.yoff, res.num_frames); //total_length = (res.xres - res.xoff*2) * (res.yres - res.yoff*2) * BPP; total_length = res.xres * res.yres * BPP * res.num_frames; total_length = total_length - res.xres * res.yoff * BPP * 2; buffer_length = res.xres * res.yres * BPP; //length of one buffer mem_width = res.xres; mem_height = res.yres; screen_width = res.xres - 2*res.xoff; screen_height = res.yres - 2*res.yoff; // printf("length: %d\n", buffer_length); //void *addr = mmap(NULL, buffer_length*2, PROT_WRITE, MAP_SHARED, fd, 0); //void *addr = mmap(NULL, buffer_length, PROT_WRITE, MAP_SHARED, fd, 0); fb = (unsigned char*)mmap(NULL, total_length, PROT_WRITE, MAP_SHARED, fd, 0); if(!fb) { printf("couldn't mmap\r\n"); close(fd); return false; } /* stop flipping in kernel thread with vsync*/ ioctl(fd, PS3FB_IOCTL_ON, 0); fbs[0] = fb; fbs[1] = fb + mem_width * mem_height * BPP; //fb_cur = fbs[0]; //cur_buffer = 0; memset(fb, 0, total_length); fb_flip_to_buffer(0); fb_set_all_pixels(fbs[0], RGB32(0, 0, 0)); fb_set_all_pixels(fbs[1], RGB32(0, 0, 0)); return true;}void fb_flip_to_buffer(unsigned int next_buffer) { uint32_t crt = 0; ioctl(fd, FBIO_WAITFORVSYNC, (unsigned long)&crt); ioctl(fd, PS3FB_IOCTL_FSEL, (unsigned long)&next_buffer); cur_buffer = 1 - next_buffer; fb_cur = fbs[cur_buffer];}void fb_flip_buffer() { fb_flip_to_buffer(cur_buffer);}unsigned char* fb_get_buffer_addr(int buffer) { return fbs[buffer];}unsigned char* fb_get_buffer_addr() { return fb_cur;}void fb_set_all_pixels(unsigned int color) { fb_set_all_pixels(fb_cur, color);}void fb_set_all_pixels(unsigned char *buffer, unsigned int color) { unsigned int x, y; uint32_t *line; for(y=0; y<screen_height; y++) { line = (unsigned int *)(buffer + y * mem_width * BPP); for(x=0; x<screen_width; x++) { //r = 0xFF * (i & 0x01); //g = 0xFF * (i & 0x02); //b = 0xFF * !(i & 0x01); //*line = (r << 16 | g << 8 | b); *line = color; line++; } } }void fb_set_pixel(unsigned char *buffer, unsigned int x, unsigned int y, unsigned int color) { //if(x<0 || y<0 || x >= screen_width || y>=screen_height) if(x >= screen_width || y>=screen_height) //x/y are unsigned return; *((unsigned int *)(buffer + (y*mem_width + x)*BPP)) = color;}void fb_set_pixel(unsigned int x, unsigned int y, unsigned int color) { fb_set_pixel(fb_cur, x, y, color);}//need to free up resources we usevoid fb_shutdown() { ioctl(fd, PS3FB_IOCTL_ON, 0); //kernel resumes flipping munmap(NULL, total_length); //free up mapped memory close(fd); //close /dev/fb}void fb_memcpy_frame(unsigned int *image, int width, int height) { unsigned int x, y; unsigned int *line; unsigned int max_y = (height < screen_height)? height:screen_height; /* if(height < screen_height) max_y = height; */ unsigned int *source; for(y=0; y < max_y; y++) { line = (unsigned int *)(fb_cur + y * mem_width * BPP); source = &image[(height-y-1)*width]; memcpy(line, source, width*4); } //printf("done");}/*int main() { printf("main start\n"); init_buffer(); printf("passed init\n"); //printf("addr1 is: %u\n", (unsigned int)get_buffer_addr(0)); //printf("addr2 is: %u\n", (unsigned int)get_buffer_addr(1)); //printf("buffer_length: %d\n", buffer_length); while(1) { flip_buffer(); sleep(1); } //flip_to_buffer(1); //printf("flipped buffer to 1\n"); //flip_to_buffer(0); //printf("flipped buffer to 0\n"); finish_buffer(); printf("finished buffer\n"); return 0;}*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?