annotate Renderer/Engine/ps3fb/cp_fb.cc @ 0:04e28d8d3c6f

first commit
author Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
date Mon, 08 Nov 2010 01:23:25 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 // cp_fb.c
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // Copyright (c) 2006, Mike Acton <macton@cellperformance.com>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 // documentation files (the "Software"), to deal in the Software without restriction, including without
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 // limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 // the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 // conditions:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 // The above copyright notice and this permission notice shall be included in all copies or substantial
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 // portions of the Software.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 // OR OTHER DEALINGS IN THE SOFTWARE.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 // NOTES:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 // From Geert Uytterhoeven 2007-01-26 04:50:44,
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 // http://patchwork.ozlabs.org/linuxppc/patch?id=9143
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 // "As the actual graphics hardware cannot be accessed directly by Linux,
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 // ps3fb uses a virtual frame buffer in main memory. The actual screen image is
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 // copied to graphics memory by the GPU on every vertical blank, by making a
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 // hypervisor call."
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 #include <stdio.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include <stdlib.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 #include <unistd.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 #include <fcntl.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 #include <getopt.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 #include <string.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 #include <errno.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 #include <stdint.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 #include <sys/ioctl.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 #include <sys/mman.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 #include <linux/fb.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 #include <sys/time.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 #include <asm/ps3fb.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 #include <linux/vt.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 #include <linux/kd.h>
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 #include "cp_fb.h"
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 static inline const char*
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 select_error_str( int existing_error, const char* const existing_error_str, int new_error, const char* const new_error_str )
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 {
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 // Only report the first error found - any error that follows is probably just a cascading effect.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 const char* error_str = (char*)( (~(intptr_t)existing_error & (intptr_t)new_error & (intptr_t)new_error_str)
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 | ((intptr_t)existing_error & (intptr_t)existing_error_str) );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 return (error_str);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 }
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 int
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 cp_fb_open( cp_fb* const restrict fb )
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 {
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 const char* error_str = NULL;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 int error = 0;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 // Open framebuffer device
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 const int fb_fd = open( "/dev/fb0", O_RDWR );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 const int open_fb_error = (fb_fd >> ((sizeof(int)<<3)-1));
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 const char* open_fb_error_str = "Could not open /dev/fb0. Check permissions.";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 error_str = select_error_str( error, error_str, open_fb_error, open_fb_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 error = error | open_fb_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 // Check for vsync
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 struct fb_vblank vblank;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 const int get_vblank_error = ioctl(fb_fd, FBIOGET_VBLANK, (unsigned long)&vblank);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 const char* get_vblank_error_str = "Could not get vblank info (FBIOGET_VBLANK)";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 error_str = select_error_str( error, error_str, get_vblank_error, get_vblank_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 error = error | get_vblank_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 const int has_vsync = vblank.flags & FB_VBLANK_HAVE_VSYNC;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 const int has_vsync_error = (~(-has_vsync|has_vsync))>>((sizeof(int)<<3)-1);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 const char* has_vsync_error_str = "No vsync available (FB_VBLANK_HAVE_VSYNC)";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 error_str = select_error_str( error, error_str, has_vsync_error, has_vsync_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 error = error | has_vsync_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 // Get screen resolution and frame count
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 struct ps3fb_ioctl_res res;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 const int screeninfo_error = ioctl(fb_fd, PS3FB_IOCTL_SCREENINFO, (unsigned long)&res);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 const char* screeninfo_error_str = "Could not get screen info (PS3_IOCTL_SCREENINFO)";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 error_str = select_error_str( error, error_str, screeninfo_error, screeninfo_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 error = error | screeninfo_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 const int has_at_least_double_buffer = (res.num_frames - 2) >> ((sizeof(res.num_frames)<<3)-1);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 const int has_at_least_double_buffer_error = ~has_at_least_double_buffer;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 const char* has_at_least_double_buffer_error_str = "Could not get screen info (PS3_IOCTL_SCREENINFO)";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 error_str = select_error_str( error, error_str, has_at_least_double_buffer_error, has_at_least_double_buffer_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 error = error | has_at_least_double_buffer_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 const uint32_t bpp = 4; // This is fixed for PS3 fb, and there's not a test for it.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 const uint32_t frame_size = res.xres * res.yres * bpp;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 const uint32_t double_buffer_frame_size = frame_size * 2;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 // const uint32_t frame_top_margin_size = res.xres * res.yoff * bpp;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 // const uint32_t frame_bottom_margin_size = frame_top_margin_size;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 // const uint32_t frame_size = frame_full_size; /* - ( frame_top_margin_size + frame_bottom_margin_size ); */
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 // const uint32_t double_buffer_frame_size = frame_size * 2;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 const uintptr_t fb_addr = (uintptr_t)mmap(NULL, double_buffer_frame_size, PROT_READ|PROT_WRITE, MAP_SHARED, fb_fd, 0);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 const int fb_mmap_error = fb_addr >> ((sizeof(uintptr_t)<<3)-1);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 const char* fb_mmap_error_str = "Could not get mmap frame buffer";
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 error_str = select_error_str( error, error_str, fb_mmap_error, fb_mmap_error_str );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 error = error | fb_mmap_error;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 // Take control of frame buffer from kernel
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 ioctl(fb_fd, PS3FB_IOCTL_ON, 0);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 // yoff is the number of lines that cannot be copied to the CRT before the vblank. For the most part this represents
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 // unusable frame buffer space. While it is possible to draw to the area if you draw in the opposite frame buffer's
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 // offset space, which will (due to poor draw timing by ps3fb) be the thing that is actually drawn, it's very
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 // difficult to work with in practice. So:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 // (1) The y offset area will be treated as "off limits".
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 // (2) An equivalent border will be created at the bottom, so the frame looks balanced even though it is
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 // not entirely full screen.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 // xoff is the number of lines that cannot be copied to the CRT before the hblank.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 // Similar to the y offset space, the x offset space is displayed on the wrong (previous) line. So:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 // (1) The x offset area will be treated as "off limits".
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 // (2) An equivalent border will be created at the right, so the frame looks balanced even though it is
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 // not entirely full screen.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 uintptr_t draw_start_addr = fb_addr;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 uintptr_t draw_next_addr = draw_start_addr + ( res.yres * res.xres * bpp );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 uintptr_t drawable_h = res.yres - ( 2 * res.yoff );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 uintptr_t drawable_w = res.xres - ( 2 * res.xoff );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 // xoff is the number of lines that cannot be copied to the CRT before the hblank. This area is much easier to use.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 // Similar to the y offset space, the x offset space is displayed on the wrong (previous) line. So:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 // In principle, it is possible to steal back the x offset space by shifting back the line address to the
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 // start of the border of the previous line. Like so:
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 // (1) One additional line will be taken from the height so the a complete horizontal line can be started
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 // early.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 // (2) The frame buffer address returned in cp_fb will be offset by (xres-xoff) in order for the remaining
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 // space to represent a rectangular area of drawable memory.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 // i.e.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 // uintptr_t draw_start_addr = fb_addr + ( ( res.xres - res.xoff ) * bpp );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 // uintptr_t draw_next_addr = draw_start_addr + ( res.yres * res.xres * bpp );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 // uintptr_t drawable_h = res.yres - 1 - ( 2 * res.yoff );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 // uintptr_t drawable_w = res.xres;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 //
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 // But I wouldn't recommend it, since on some CRTs the effect of this would be that the frame does not appear
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 // square.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 fb->stride = res.xres;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166 fb->w = drawable_w;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 fb->h = drawable_h;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 fb->fd = fb_fd;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 fb->start_addr = fb_addr;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 fb->size = double_buffer_frame_size;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 fb->draw_addr[0] = draw_start_addr;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 fb->draw_addr[1] = draw_next_addr;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 // Clear out the whole buffer. Any unused space is black. It's also convinient to start with a cleared frame
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 // buffer for the user.
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 memset((void*)fb_addr, 0x00, double_buffer_frame_size );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 return (error);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180 }
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 void
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 cp_fb_close( const cp_fb* const restrict fb )
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184 {
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 // Give frame buffer control back to the kernel
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 ioctl(fb->fd, PS3FB_IOCTL_OFF, 0);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 munmap( (void*)fb->start_addr, fb->size );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 close(fb->fd);
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 }
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 void
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 cp_fb_wait_vsync( cp_fb* const restrict fb )
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 {
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 unsigned long crt = 0;
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 ioctl(fb->fd, FBIO_WAITFORVSYNC, &crt );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 }
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 void
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 cp_fb_flip( cp_fb* const restrict fb, unsigned long field_ndx )
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 {
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 ioctl(fb->fd, PS3FB_IOCTL_FSEL, &field_ndx );
04e28d8d3c6f first commit
Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 }