dvb.cpp: detect boxtype via /proc/stb/info/model for demux policy
[enigma2.git] / lib / gdi / accel.cpp
1 #include <cstring>
2 #include <lib/base/init.h>
3 #include <lib/base/init_num.h>
4 #include <lib/gdi/accel.h>
5 #include <lib/base/eerror.h>
6 #include <lib/gdi/esize.h>
7 #include <lib/gdi/epoint.h>
8 #include <lib/gdi/erect.h>
9 #include <lib/gdi/gpixmap.h>
10
11 gAccel *gAccel::instance;
12 #define BCM_ACCEL
13
14 #ifdef ATI_ACCEL
15 extern int ati_accel_init(void);
16 extern void ati_accel_close(void);
17 extern void ati_accel_blit(
18                 int src_addr, int src_width, int src_height, int src_stride,
19                 int dst_addr, int dst_width, int dst_height, int dst_stride,
20                 int src_x, int src_y, int width, int height,
21                 int dst_x, int dst_y);
22 extern void ati_accel_fill(
23                 int dst_addr, int dst_width, int dst_height, int dst_stride,
24                 int x, int y, int width, int height,
25                 unsigned long color);
26 #endif
27 #ifdef BCM_ACCEL
28 extern int bcm_accel_init(void);
29 extern void bcm_accel_close(void);
30 extern void bcm_accel_blit(
31                 int src_addr, int src_width, int src_height, int src_stride,
32                 int dst_addr, int dst_width, int dst_height, int dst_stride,
33                 int src_x, int src_y, int width, int height,
34                 int dst_x, int dst_y, int dwidth, int dheight);
35 extern void bcm_accel_fill(
36                 int dst_addr, int dst_width, int dst_height, int dst_stride,
37                 int x, int y, int width, int height,
38                 unsigned long color);
39 #endif
40
41 gAccel::gAccel()
42 {
43         m_accel_addr = 0;
44         m_accel_phys_addr = 0;
45         m_accel_size = 0;
46         m_accel_allocation = 0;
47         instance = this;
48
49 #ifdef ATI_ACCEL        
50         ati_accel_init();
51 #endif
52 #ifdef BCM_ACCEL        
53         m_bcm_accel_state = bcm_accel_init();
54 #endif
55 }
56
57 gAccel::~gAccel()
58 {
59 #ifdef ATI_ACCEL
60         ati_accel_close();
61 #endif
62 #ifdef BCM_ACCEL
63         bcm_accel_close();
64 #endif
65         instance = 0;
66 }
67
68 gAccel *gAccel::getInstance()
69 {
70         return instance;
71 }
72  
73 void gAccel::setAccelMemorySpace(void *addr, int phys_addr, int size)
74 {
75         if (m_accel_allocation)
76                 delete[] m_accel_allocation;
77         
78         m_accel_size = size >> 12;
79         
80         m_accel_allocation = new int[m_accel_size];
81         memset(m_accel_allocation, 0, sizeof(int)*m_accel_size);
82         
83         m_accel_addr = addr;
84         m_accel_phys_addr = phys_addr;
85 }
86
87 int gAccel::blit(gSurface *dst, const gSurface *src, const eRect &p, const eRect &area, int flags)
88 {
89 #ifdef ATI_ACCEL
90         ati_accel_blit(
91                 src->data_phys, src->x, src->y, src->stride,
92                 dst->data_phys, dst->x, dst->y, dst->stride, 
93                 area.left(), area.top(), area.width(), area.height(),
94                 p.x(), p.y());
95         return 0;
96 #endif
97 #ifdef BCM_ACCEL
98         if (!m_bcm_accel_state)
99         {
100                 bcm_accel_blit(
101                         src->data_phys, src->x, src->y, src->stride,
102                         dst->data_phys, dst->x, dst->y, dst->stride, 
103                         area.left(), area.top(), area.width(), area.height(),
104                         p.x(), p.y(), p.width(), p.height());
105                 return 0;
106         }
107 #endif
108         return -1;
109 }
110
111 int gAccel::fill(gSurface *dst, const eRect &area, unsigned long col)
112 {
113 #ifdef ATI_ACCEL
114         ati_accel_fill(
115                 dst->data_phys, dst->x, dst->y, dst->stride, 
116                 area.left(), area.top(), area.width(), area.height(),
117                 col);
118         return 0;
119 #endif
120 #if 0 // def BCM_ACCEL
121         bcm_accel_fill(
122                 dst->data_phys, dst->x, dst->y, dst->stride, 
123                 area.left(), area.top(), area.width(), area.height(),
124                 col);
125         return 0;
126 #endif
127         return -1;
128 }
129
130 int gAccel::accelAlloc(void *&addr, int &phys_addr, int size)
131 {
132         eDebug("accel %d bytes", size);
133         if ((!size) || (!m_accel_allocation))
134         {
135                 eDebug("size: %d, alloc %p", size, m_accel_allocation);
136                 addr = 0;
137                 phys_addr = 0;
138                 return -1;
139         }
140         
141         size += 4095; size >>= 12;
142         int i;
143         
144         int used = 0, free = 0, s = 0;
145         for (i=0; i < m_accel_size; ++i)
146         {
147                 if (m_accel_allocation[i] == 0)
148                         free++;
149                 else if (m_accel_allocation[i] == -1)
150                         used++;
151                 else
152                 {
153                         used++;
154                         s += m_accel_allocation[i];
155                 }
156         }
157         eDebug("accel memstat: used=%d kB, free %d kB, s %d kB", used * 4, free * 4, s * 4);
158
159         for (i=0; i < m_accel_size - size; ++i)
160         {
161                 int a;
162                 for (a=0; a<size; ++a)
163                         if (m_accel_allocation[i+a])
164                                 break;
165                 if (a == size)
166                 {
167                         m_accel_allocation[i] = size;
168                         for (a=1; a<size; ++a)
169                                 m_accel_allocation[i+a] = -1;
170                         addr = ((unsigned char*)m_accel_addr) + (i << 12);
171                         phys_addr = m_accel_phys_addr + (i << 12);
172                         return 0;
173                 }
174         }
175         eDebug("accel alloc failed\n");
176         return -1;
177 }
178
179 void gAccel::accelFree(int phys_addr)
180 {
181         phys_addr -= m_accel_phys_addr;
182         phys_addr >>= 12;
183         
184         int size = m_accel_allocation[phys_addr];
185         
186         ASSERT(size > 0);
187         
188         while (size--)
189                 m_accel_allocation[phys_addr++] = 0;
190 }
191
192 eAutoInitP0<gAccel> init_gAccel(eAutoInitNumbers::graphic-2, "graphics acceleration manager");