missing commit
[enigma2.git] / lib / gdi / accel.cpp
1 #include <lib/base/init.h>
2 #include <lib/base/init_num.h>
3 #include <lib/gdi/accel.h>
4 #include <lib/base/eerror.h>
5 #include <lib/gdi/esize.h>
6 #include <lib/gdi/epoint.h>
7 #include <lib/gdi/erect.h>
8 #include <lib/gdi/gpixmap.h>
9
10 gAccel *gAccel::instance;
11
12 extern int ati_accel_init(void);
13 extern void ati_accel_close(void);
14 extern void ati_accel_blit(
15                 int src_addr, int src_width, int src_height, int src_stride,
16                 int dst_addr, int dst_width, int dst_height, int dst_stride,
17                 int src_x, int src_y, int width, int height,
18                 int dst_x, int dst_y);
19 extern void ati_accel_fill(
20                 int dst_addr, int dst_width, int dst_height, int dst_stride,
21                 int x, int y, int width, int height,
22                 unsigned long color);
23
24 gAccel::gAccel()
25 {
26         m_accel_addr = 0;
27         m_accel_phys_addr = 0;
28         m_accel_size = 0;
29         m_accel_allocation = 0;
30         instance = this;
31
32 #ifdef ATI_ACCEL        
33         ati_accel_init();
34 #endif
35 }
36
37 gAccel::~gAccel()
38 {
39 #ifdef ATI_ACCEL
40         ati_accel_close();
41 #endif
42         instance = 0;
43 }
44
45 gAccel *gAccel::getInstance()
46 {
47         return instance;
48 }
49  
50 void gAccel::setAccelMemorySpace(void *addr, int phys_addr, int size)
51 {
52         if (m_accel_allocation)
53                 delete[] m_accel_allocation;
54         
55         m_accel_size = size >> 12;
56         
57         m_accel_allocation = new int[m_accel_size];
58         memset(m_accel_allocation, 0, sizeof(int)*m_accel_size);
59         
60         m_accel_addr = addr;
61         m_accel_phys_addr = phys_addr;
62 }
63
64 int gAccel::blit(gSurface *dst, const gSurface *src, const ePoint &p, const eRect &area, int flags)
65 {
66 #ifdef ATI_ACCEL
67         ati_accel_blit(
68                 src->data_phys, src->x, src->y, src->stride,
69                 dst->data_phys, dst->x, dst->y, dst->stride, 
70                 area.left(), area.top(), area.width(), area.height(),
71                 p.x(), p.y());
72         return 0;
73 #endif
74         return -1;
75 }
76
77 int gAccel::fill(gSurface *dst, const eRect &area, unsigned long col)
78 {
79 #ifdef ATI_ACCEL
80         ati_accel_fill(
81                 dst->data_phys, dst->x, dst->y, dst->stride, 
82                 area.left(), area.top(), area.width(), area.height(),
83                 col);
84         return 0;
85 #endif
86         return -1;
87 }
88
89 int gAccel::accelAlloc(void *&addr, int &phys_addr, int size)
90 {
91         if ((!size) || (!m_accel_allocation))
92         {
93                 eDebug("size: %d, alloc %p", m_accel_allocation);
94                 addr = 0;
95                 phys_addr = 0;
96                 return -1;
97         }
98         
99         size += 4095; size >>= 12;
100         int i;
101
102         for (i=0; i < m_accel_size - size; ++i)
103         {
104                 int a;
105                 for (a=0; a<size; ++a)
106                         if (m_accel_allocation[i+a])
107                                 break;
108                 if (a == size)
109                 {
110                         m_accel_allocation[i+a] = size;
111                         for (a=1; a<size; ++a)
112                                 m_accel_allocation[i+a] = -1;
113                         addr = ((unsigned char*)m_accel_addr) + (i << 12);
114                         phys_addr = m_accel_phys_addr + (i << 12);
115                         return 0;
116                 }
117         }
118         return -1;
119 }
120
121 void gAccel::accelFree(int phys_addr)
122 {
123         phys_addr -= m_accel_phys_addr;
124         phys_addr >>= 12;
125         
126         int size = m_accel_allocation[phys_addr];
127         
128         ASSERT(size > 0);
129         
130         while (size--)
131                 m_accel_allocation[phys_addr++] = 0;
132 }
133
134 eAutoInitP0<gAccel> init_gAccel(eAutoInitNumbers::graphic-2, "graphics acceleration manager");