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