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 + -
显示快捷键?