- fixes to use moving infobar non non-accel hardware.
[vuplus_dvbapp] / lib / gdi / gfbdc.cpp
1 #include <lib/gdi/gfbdc.h>
2
3 #include <lib/base/init.h>
4 #include <lib/base/init_num.h>
5 #include <lib/base/econfig.h>
6
7 #include <lib/gdi/accel.h>
8
9 #include <time.h>
10
11 gFBDC *gFBDC::instance;
12
13 gFBDC::gFBDC()
14 {
15         instance=this;
16         fb=new fbClass;
17
18         if (!fb->Available())
19                 eFatal("no framebuffer available");
20
21         fb->SetMode(720, 576, 32);
22
23         for (int y=0; y<576; y++)                                                                                                                                                // make whole screen transparent
24                 memset(fb->lfb+y*fb->Stride(), 0x00, fb->Stride());
25
26         surface.type = 0;
27         surface.x = 720;
28         surface.y = 576;
29         surface.bpp = 32;
30         surface.bypp = 4;
31         surface.stride = fb->Stride();
32         surface.data = fb->lfb;
33         surface.offset = 0;
34         
35         surface.data_phys = 50*1024*1024; // FIXME
36         
37         surface_back.type = 0;
38         surface_back.x = 720;
39         surface_back.y = 576;
40         surface_back.bpp = 32;
41         surface_back.bypp = 4;
42         surface_back.stride = fb->Stride();
43         surface_back.offset = surface.y;
44
45         int fb_size = surface.stride * surface.y;
46
47         surface_back.data = fb->lfb + fb_size;
48         surface_back.data_phys = surface.data_phys + fb_size;
49         
50         fb_size *= 2;
51         
52         eDebug("%dkB available for acceleration surfaces.", (fb->Available() - fb_size)/1024);
53         
54         if (gAccel::getInstance())
55                 gAccel::getInstance()->setAccelMemorySpace(fb->lfb + fb_size, surface.data_phys + fb_size, fb->Available() - fb_size);
56         
57         surface.clut.colors = 256;
58         surface.clut.data = new gRGB[surface.clut.colors];
59         
60         surface_back.clut = surface.clut;
61         
62         m_pixmap = new gPixmap(&surface);
63         
64         memset(surface.clut.data, 0, sizeof(*surface.clut.data)*surface.clut.colors);
65         reloadSettings();
66 }
67
68 gFBDC::~gFBDC()
69 {
70         delete fb;
71         
72         delete[] surface.clut.data;
73         instance=0;
74 }
75
76 void gFBDC::calcRamp()
77 {
78 #if 0
79         float fgamma=gamma ? gamma : 1;
80         fgamma/=10.0;
81         fgamma=1/log(fgamma);
82         for (int i=0; i<256; i++)
83         {
84                 float raw=i/255.0; // IIH, float.
85                 float corr=pow(raw, fgamma) * 256.0;
86
87                 int d=corr * (float)(256-brightness) / 256 + brightness;
88                 if (d < 0)
89                         d=0;
90                 if (d > 255)
91                         d=255;
92                 ramp[i]=d;
93                 
94                 rampalpha[i]=i*alpha/256;
95         }
96 #endif
97         for (int i=0; i<256; i++)
98         {
99                 int d;
100                 d=i;
101                 d=(d-128)*(gamma+64)/(128+64)+128;
102                 d+=brightness-128; // brightness correction
103                 if (d<0)
104                         d=0;
105                 if (d>255)
106                         d=255;
107                 ramp[i]=d;
108
109                 rampalpha[i]=i*alpha/256;
110         }
111
112         rampalpha[255]=255; // transparent BLEIBT bitte so.
113 }
114
115 void gFBDC::setPalette()
116 {
117         if (!surface.clut.data)
118                 return;
119         
120         for (int i=0; i<256; ++i)
121         {
122                 fb->CMAP()->red[i]=ramp[surface.clut.data[i].r]<<8;
123                 fb->CMAP()->green[i]=ramp[surface.clut.data[i].g]<<8;
124                 fb->CMAP()->blue[i]=ramp[surface.clut.data[i].b]<<8;
125                 fb->CMAP()->transp[i]=rampalpha[surface.clut.data[i].a]<<8;
126         }
127         fb->PutCMAP();
128 }
129
130 void gFBDC::exec(gOpcode *o)
131 {
132         switch (o->opcode)
133         {
134         case gOpcode::setPalette:
135         {
136                 gDC::exec(o);
137                 setPalette();
138                 break;
139         }
140         case gOpcode::flip:
141         {
142                 gSurface s(surface);
143                 surface = surface_back;
144                 surface_back = s;
145                 
146                 fb->setOffset(surface_back.offset);
147                 break;
148         }
149         case gOpcode::waitVSync:
150         {
151                 static timeval l;
152                 static int t;
153                 timeval now;
154                 
155                 if (t == 1000)
156                 {
157                         gettimeofday(&now, 0);
158                 
159                         int diff = (now.tv_sec - l.tv_sec) * 1000 + (now.tv_usec - l.tv_usec) / 1000;
160                         eDebug("%d ms latency (%d fps)", diff, t * 1000 / (diff ? diff : 1));
161                         l = now;
162                         t = 0;
163                 }
164                 
165                 ++t;
166                 
167                 fb->waitVSync();
168                 break;
169         }
170         default:
171                 gDC::exec(o);
172                 break;
173         }
174 }
175
176 void gFBDC::setAlpha(int a)
177 {
178         alpha=a;
179
180         calcRamp();
181         setPalette();
182 }
183
184 void gFBDC::setBrightness(int b)
185 {
186         brightness=b;
187
188         calcRamp();
189         setPalette();
190 }
191
192 void gFBDC::setGamma(int g)
193 {
194         gamma=g;
195
196         calcRamp();
197         setPalette();
198 }
199
200 void gFBDC::saveSettings()
201 {
202         eConfig::getInstance()->setKey("/ezap/osd/alpha", alpha);
203         eConfig::getInstance()->setKey("/ezap/osd/gamma", gamma);
204         eConfig::getInstance()->setKey("/ezap/osd/brightness", brightness);
205 }
206
207 void gFBDC::reloadSettings()
208 {
209         if (eConfig::getInstance()->getKey("/ezap/osd/alpha", alpha))
210                 alpha=255;
211         if (eConfig::getInstance()->getKey("/ezap/osd/gamma", gamma))
212                 gamma=128;
213         if (eConfig::getInstance()->getKey("/ezap/osd/brightness", brightness))
214                 brightness=128;
215
216         calcRamp();
217         setPalette();
218 }
219
220 // eAutoInitPtr<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");
221 #ifndef SDLDC
222 eAutoInitPtr<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");
223 #endif