Merge branch 'obi/master' into experimental
[vuplus_dvbapp] / lib / gdi / bcm.cpp
1 /*
2   Interface to the Dreambox dm800/dm8000 proprietary accel interface.
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <linux/fb.h>
10 #include <sys/mman.h>
11 #include <sys/ioctl.h>
12
13 #define FBIO_ACCEL  0x23
14
15 static unsigned int displaylist[1024];
16 static int ptr;
17
18 #define P(x, y) do { displaylist[ptr++] = x; displaylist[ptr++] = y; } while (0)
19 #define C(x) P(x, 0)
20
21 static int fb_fd;
22 static int exec_list(void);
23
24 int bcm_accel_init(void)
25 {
26         fb_fd = open("/dev/fb0", O_RDWR);
27         if (fb_fd < 0)
28         {
29                 perror("/dev/fb0");
30                 return 1;
31         }
32         if (exec_list())
33         {
34                 fprintf(stderr, "BCM accel interface not available - %m\n");
35                 close(fb_fd);
36                 return 1;
37         }
38         return 0;
39 }
40
41 void bcm_accel_close(void)
42 {
43         close(fb_fd);
44 }
45
46 static int exec_list(void)
47 {
48         int ret;
49         struct
50         {
51                 void *ptr;
52                 int len;
53         } l;
54
55         l.ptr = displaylist;
56         l.len = ptr;
57         ret = ioctl(fb_fd, FBIO_ACCEL, &l);
58         ptr = 0;
59         return ret;
60 }
61
62 void bcm_accel_blit(
63                 int src_addr, int src_width, int src_height, int src_stride, int src_format,
64                 int dst_addr, int dst_width, int dst_height, int dst_stride,
65                 int src_x, int src_y, int width, int height,
66                 int dst_x, int dst_y, int dwidth, int dheight,
67                 int pal_addr, int flags)
68 {
69         C(0x43); // reset source
70         C(0x53); // reset dest
71         C(0x5b);  // reset pattern
72         C(0x67); // reset blend
73         C(0x75); // reset output
74
75         P(0x0, src_addr); // set source addr
76         P(0x1, src_stride);  // set source pitch
77         P(0x2, src_width); // source width
78         P(0x3, src_height); // height
79         switch (src_format)
80         {
81         case 0:
82                 P(0x4, 0x7e48888); // format: ARGB 8888
83                 break;
84         case 1:
85                 P(0x4, 0x12e40008); // indexed 8bit
86                 P(0x78, 256);
87                 P(0x79, pal_addr);
88                 P(0x7a, 0x7e48888);
89                 break;
90         }
91
92         C(0x5); // set source surface (based on last parameters)
93
94         P(0x2e, src_x); // define  rect
95         P(0x2f, src_y);
96         P(0x30, width);
97         P(0x31, height);
98
99         C(0x32); // set this rect as source rect
100
101         P(0x0, dst_addr); // prepare output surface
102         P(0x1, dst_stride);
103         P(0x2, dst_width);
104         P(0x3, dst_height);
105         P(0x4, 0x7e48888);
106         
107         C(0x69); // set output surface
108         
109         P(0x2e, dst_x); // prepare output rect
110         P(0x2f, dst_y);
111         P(0x30, dwidth);
112         P(0x31, dheight);
113
114         C(0x6e); // set this rect as output rect
115
116         C(0x77);  // do it
117
118         exec_list();
119 }
120
121 void bcm_accel_fill(
122                 int dst_addr, int dst_width, int dst_height, int dst_stride,
123                 int x, int y, int width, int height,
124                 unsigned long color)
125 {
126         C(0x43); // reset source
127         C(0x53); // reset dest
128         C(0x5b); // reset pattern
129         C(0x67); // reset blend
130         C(0x75); // reset output
131
132         // clear dest surface
133         P(0x0, 0);
134         P(0x1, 0);
135         P(0x2, 0);
136         P(0x3, 0);
137         P(0x4, 0);
138         C(0x45);
139
140         // clear src surface
141         P(0x0, 0);
142         P(0x1, 0);
143         P(0x2, 0);
144         P(0x3, 0);
145         P(0x4, 0);
146         C(0x5);
147
148         P(0x2d, color);
149
150         P(0x2e, x); // prepare output rect
151         P(0x2f, y);
152         P(0x30, width);
153         P(0x31, height);
154         C(0x6e); // set this rect as output rect
155
156         P(0x0, dst_addr); // prepare output surface
157         P(0x1, dst_stride);
158         P(0x2, dst_width);
159         P(0x3, dst_height);
160         P(0x4, 0x7e48888);
161         C(0x69); // set output surface
162
163         P(0x6f, 0);
164         P(0x70, 0);
165         P(0x71, 2);
166         P(0x72, 2);
167         C(0x73); // select color keying
168
169         C(0x77);  // do it
170
171         exec_list();
172 }
173