optimize manual blits by not forcing them at gPainter::end, but instead call flush...
[enigma2.git] / 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/fb/0", O_RDWR);
27         if (fb_fd < 0)
28         {
29                 perror("/dev/fb/0");
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,
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 {
68         C(0x43); // reset source
69         C(0x53); // reset dest
70         C(0x5b);  // reset pattern
71         C(0x67); // reset blend
72         C(0x75); // reset output
73
74         P(0x0, src_addr); // set source addr
75         P(0x1, src_stride);  // set source pitch
76         P(0x2, src_width); // source width
77         P(0x3, src_height); // height
78         P(0x4, 0x7e48888); // format: ARGB 8888
79
80         C(0x5); // set source surface (based on last parameters)
81
82         P(0x2e, src_x); // define  rect
83         P(0x2f, src_y);
84         P(0x30, width);
85         P(0x31, height);
86
87         C(0x32); // set this rect as source rect
88
89         P(0x0, dst_addr); // prepare output surface
90         P(0x1, dst_stride);
91         P(0x2, dst_width);
92         P(0x3, dst_height);
93         P(0x4, 0x7e48888);
94         
95         C(0x69); // set output surface
96         
97         P(0x2e, dst_x); // prepare output rect
98         P(0x2f, dst_y);
99         P(0x30, dwidth);
100         P(0x31, dheight);
101
102         C(0x6e); // set this rect as output rect
103
104         C(0x77);  // do it
105
106         exec_list();
107 }
108
109 void bcm_accel_fill(
110                 int dst_addr, int dst_width, int dst_height, int dst_stride,
111                 int x, int y, int width, int height,
112                 unsigned long color)
113 {
114 //      printf("unimplemented bcm_accel_fill\n");
115 }
116