[RecordTimer] fix repeat timer issue.
[vuplus_dvbapp] / 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, int src_format,
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                 int pal_addr, int flags);
36 extern void bcm_accel_fill(
37                 int dst_addr, int dst_width, int dst_height, int dst_stride,
38                 int x, int y, int width, int height,
39                 unsigned long color);
40 #endif
41
42 gAccel::gAccel()
43 {
44         m_accel_addr = 0;
45         m_accel_phys_addr = 0;
46         m_accel_size = 0;
47         m_accel_allocation = 0;
48         instance = this;
49
50 #ifdef ATI_ACCEL        
51         ati_accel_init();
52 #endif
53 #ifdef BCM_ACCEL        
54         m_bcm_accel_state = bcm_accel_init();
55 #endif
56 }
57
58 gAccel::~gAccel()
59 {
60 #ifdef ATI_ACCEL
61         ati_accel_close();
62 #endif
63 #ifdef BCM_ACCEL
64         bcm_accel_close();
65 #endif
66         instance = 0;
67 }
68
69 gAccel *gAccel::getInstance()
70 {
71         return instance;
72 }
73  
74 void gAccel::setAccelMemorySpace(void *addr, int phys_addr, int size)
75 {
76         if (m_accel_allocation)
77                 delete[] m_accel_allocation;
78         
79         m_accel_size = size >> 12;
80         
81         m_accel_allocation = new int[m_accel_size];
82         memset(m_accel_allocation, 0, sizeof(int)*m_accel_size);
83         
84         m_accel_addr = addr;
85         m_accel_phys_addr = phys_addr;
86 }
87
88 int gAccel::blit(gSurface *dst, const gSurface *src, const eRect &p, const eRect &area, int flags)
89 {
90 #ifdef ATI_ACCEL
91         ati_accel_blit(
92                 src->data_phys, src->x, src->y, src->stride,
93                 dst->data_phys, dst->x, dst->y, dst->stride, 
94                 area.left(), area.top(), area.width(), area.height(),
95                 p.x(), p.y());
96         return 0;
97 #endif
98 #ifdef BCM_ACCEL
99         if (!m_bcm_accel_state)
100         {
101                 if (flags & (gPixmap::blitAlphaTest|gPixmap::blitAlphaBlend)) /* unsupported flags */
102                         return -1;
103                 unsigned long pal_addr = 0;
104                 int src_format = 0;
105                 if (src->bpp == 32)
106                         src_format = 0;
107                 else if ((src->bpp == 8) && src->clut.data)
108                 {
109                         src_format = 1;
110                         /* sync pal */
111                         int i;
112                         pal_addr = src->stride * src->y;
113                         unsigned long *pal = (unsigned long*)(((unsigned char*)src->data) + pal_addr);
114                         pal_addr += src->data_phys;
115                         for (i = 0; i < src->clut.colors; ++i)
116                                 *pal++ = src->clut.data[i].argb() ^ 0xFF000000;
117                 } else
118                         return -1; /* unsupported source format */
119
120                 bcm_accel_blit(
121                         src->data_phys, src->x, src->y, src->stride, src_format,
122                         dst->data_phys, dst->x, dst->y, dst->stride, 
123                         area.left(), area.top(), area.width(), area.height(),
124                         p.x(), p.y(), p.width(), p.height(),
125                         pal_addr, flags);
126                 return 0;
127         }
128 #endif
129         return -1;
130 }
131
132 int gAccel::fill(gSurface *dst, const eRect &area, unsigned long col)
133 {
134 #ifdef ATI_ACCEL
135         ati_accel_fill(
136                 dst->data_phys, dst->x, dst->y, dst->stride, 
137                 area.left(), area.top(), area.width(), area.height(),
138                 col);
139         return 0;
140 #endif
141 #ifdef BCM_ACCEL
142         if (!m_bcm_accel_state) {
143                 bcm_accel_fill(
144                         dst->data_phys, dst->x, dst->y, dst->stride,
145                         area.left(), area.top(), area.width(), area.height(),
146                         col);
147                 return 0;
148         }
149 #endif
150         return -1;
151 }
152
153 int gAccel::accelAlloc(void *&addr, int &phys_addr, int size)
154 {
155         eDebug("accel %d bytes", size);
156         if ((!size) || (!m_accel_allocation))
157         {
158                 eDebug("size: %d, alloc %p", size, m_accel_allocation);
159                 addr = 0;
160                 phys_addr = 0;
161                 return -1;
162         }
163         
164         size += 4095; size >>= 12;
165         int i;
166         
167         int used = 0, free = 0, s = 0;
168         for (i=0; i < m_accel_size; ++i)
169         {
170                 if (m_accel_allocation[i] == 0)
171                         free++;
172                 else if (m_accel_allocation[i] == -1)
173                         used++;
174                 else
175                 {
176                         used++;
177                         s += m_accel_allocation[i];
178                 }
179         }
180         eDebug("accel memstat: used=%d kB, free %d kB, s %d kB", used * 4, free * 4, s * 4);
181
182         for (i=0; i < m_accel_size - size; ++i)
183         {
184                 int a;
185                 for (a=0; a<size; ++a)
186                         if (m_accel_allocation[i+a])
187                                 break;
188                 if (a == size)
189                 {
190                         m_accel_allocation[i] = size;
191                         for (a=1; a<size; ++a)
192                                 m_accel_allocation[i+a] = -1;
193                         addr = ((unsigned char*)m_accel_addr) + (i << 12);
194                         phys_addr = m_accel_phys_addr + (i << 12);
195                         return 0;
196                 }
197         }
198         eDebug("accel alloc failed\n");
199         return -1;
200 }
201
202 void gAccel::accelFree(int phys_addr)
203 {
204         phys_addr -= m_accel_phys_addr;
205         phys_addr >>= 12;
206         
207         int size = m_accel_allocation[phys_addr];
208         
209         ASSERT(size > 0);
210         
211         while (size--)
212                 m_accel_allocation[phys_addr++] = 0;
213 }
214
215 eAutoInitP0<gAccel> init_gAccel(eAutoInitNumbers::graphic-2, "graphics acceleration manager");