support scale attribute for epixmap
[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         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         bcm_accel_blit(
99                 src->data_phys, src->x, src->y, src->stride,
100                 dst->data_phys, dst->x, dst->y, dst->stride, 
101                 area.left(), area.top(), area.width(), area.height(),
102                 p.x(), p.y(), p.width(), p.height());
103         return 0;
104 #endif
105         return -1;
106 }
107
108 int gAccel::fill(gSurface *dst, const eRect &area, unsigned long col)
109 {
110 #ifdef ATI_ACCEL
111         ati_accel_fill(
112                 dst->data_phys, dst->x, dst->y, dst->stride, 
113                 area.left(), area.top(), area.width(), area.height(),
114                 col);
115         return 0;
116 #endif
117 #if 0 // def BCM_ACCEL
118         bcm_accel_fill(
119                 dst->data_phys, dst->x, dst->y, dst->stride, 
120                 area.left(), area.top(), area.width(), area.height(),
121                 col);
122         return 0;
123 #endif
124         return -1;
125 }
126
127 int gAccel::accelAlloc(void *&addr, int &phys_addr, int size)
128 {
129         eDebug("accel %d bytes", size);
130         if ((!size) || (!m_accel_allocation))
131         {
132                 eDebug("size: %d, alloc %p", size, m_accel_allocation);
133                 addr = 0;
134                 phys_addr = 0;
135                 return -1;
136         }
137         
138         size += 4095; size >>= 12;
139         int i;
140         
141         int used = 0, free = 0, s = 0;
142         for (i=0; i < m_accel_size; ++i)
143         {
144                 if (m_accel_allocation[i] == 0)
145                         free++;
146                 else if (m_accel_allocation[i] == -1)
147                         used++;
148                 else
149                 {
150                         used++;
151                         s += m_accel_allocation[i];
152                 }
153         }
154         eDebug("accel memstat: used=%d kB, free %d kB, s %d kB", used * 4, free * 4, s * 4);
155
156         for (i=0; i < m_accel_size - size; ++i)
157         {
158                 int a;
159                 for (a=0; a<size; ++a)
160                         if (m_accel_allocation[i+a])
161                                 break;
162                 if (a == size)
163                 {
164                         m_accel_allocation[i] = size;
165                         for (a=1; a<size; ++a)
166                                 m_accel_allocation[i+a] = -1;
167                         addr = ((unsigned char*)m_accel_addr) + (i << 12);
168                         phys_addr = m_accel_phys_addr + (i << 12);
169                         return 0;
170                 }
171         }
172         eDebug("accel alloc failed\n");
173         return -1;
174 }
175
176 void gAccel::accelFree(int phys_addr)
177 {
178         phys_addr -= m_accel_phys_addr;
179         phys_addr >>= 12;
180         
181         int size = m_accel_allocation[phys_addr];
182         
183         ASSERT(size > 0);
184         
185         while (size--)
186                 m_accel_allocation[phys_addr++] = 0;
187 }
188
189 eAutoInitP0<gAccel> init_gAccel(eAutoInitNumbers::graphic-2, "graphics acceleration manager");