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