Support turbo2.
[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
6 #include <lib/gdi/accel.h>
7
8 #include <time.h>
9 #ifdef USE_LIBVUGLES2
10 #include <vuplus_gles.h>
11 #endif
12
13 gFBDC::gFBDC()
14 {
15         fb=new fbClass;
16
17         if (!fb->Available())
18                 eFatal("no framebuffer available");
19
20         surface.clut.data = 0;
21         setResolution(720, 576); // default res
22
23         reloadSettings();
24 }
25
26 gFBDC::~gFBDC()
27 {
28         delete fb;
29         delete[] surface.clut.data;
30 }
31
32 void gFBDC::calcRamp()
33 {
34 #if 0
35         float fgamma=gamma ? gamma : 1;
36         fgamma/=10.0;
37         fgamma=1/log(fgamma);
38         for (int i=0; i<256; i++)
39         {
40                 float raw=i/255.0; // IIH, float.
41                 float corr=pow(raw, fgamma) * 256.0;
42
43                 int d=corr * (float)(256-brightness) / 256 + brightness;
44                 if (d < 0)
45                         d=0;
46                 if (d > 255)
47                         d=255;
48                 ramp[i]=d;
49
50                 rampalpha[i]=i*alpha/256;
51         }
52 #endif
53         for (int i=0; i<256; i++)
54         {
55                 int d;
56                 d=i;
57                 d=(d-128)*(gamma+64)/(128+64)+128;
58                 d+=brightness-128; // brightness correction
59                 if (d<0)
60                         d=0;
61                 if (d>255)
62                         d=255;
63                 ramp[i]=d;
64
65                 rampalpha[i]=i*alpha/256;
66         }
67
68         rampalpha[255]=255; // transparent BLEIBT bitte so.
69 }
70
71 void gFBDC::setPalette()
72 {
73         if (!surface.clut.data)
74                 return;
75
76         for (int i=0; i<256; ++i)
77         {
78                 fb->CMAP()->red[i]=ramp[surface.clut.data[i].r]<<8;
79                 fb->CMAP()->green[i]=ramp[surface.clut.data[i].g]<<8;
80                 fb->CMAP()->blue[i]=ramp[surface.clut.data[i].b]<<8;
81                 fb->CMAP()->transp[i]=rampalpha[surface.clut.data[i].a]<<8;
82         }
83         fb->PutCMAP();
84 }
85
86 void gFBDC::exec(const gOpcode *o)
87 {
88         switch (o->opcode)
89         {
90         case gOpcode::setPalette:
91         {
92                 gDC::exec(o);
93                 setPalette();
94                 break;
95         }
96         case gOpcode::flip:
97         {
98                 if (m_enable_double_buffering)
99                 {
100                         gSurface s(surface);
101                         surface = surface_back;
102                         surface_back = s;
103
104                         fb->setOffset(surface_back.offset);
105                 }
106                 break;
107         }
108         case gOpcode::waitVSync:
109         {
110                 static timeval l;
111                 static int t;
112                 timeval now;
113
114                 if (t == 1000)
115                 {
116                         gettimeofday(&now, 0);
117
118                         int diff = (now.tv_sec - l.tv_sec) * 1000 + (now.tv_usec - l.tv_usec) / 1000;
119                         eDebug("%d ms latency (%d fps)", diff, t * 1000 / (diff ? diff : 1));
120                         l = now;
121                         t = 0;
122                 }
123
124                 ++t;
125
126                 fb->blit();
127                 fb->waitVSync();
128                 break;
129         }
130         case gOpcode::flush:
131 #ifdef USE_LIBVUGLES2
132                 if (gles_is_animation())
133                         gles_do_animation();
134                 else
135                         fb->blit();
136
137                 gles_flush();
138 #else
139                 fb->blit();
140 #endif
141                 break;
142         case gOpcode::sendShow:
143         {
144 #ifdef USE_LIBVUGLES2
145                 gles_set_buffer((unsigned int *)surface.data);
146                 gles_set_animation(1, o->parm.setShowHideInfo->point.x(), o->parm.setShowHideInfo->point.y(), o->parm.setShowHideInfo->size.width(), o->parm.setShowHideInfo->size.height());
147 #endif
148                 delete o->parm.setShowHideInfo;
149                 break;
150         }
151         case gOpcode::sendHide:
152         {
153 #ifdef USE_LIBVUGLES2
154                 gles_set_buffer((unsigned int *)surface.data);
155                 gles_set_animation(0, o->parm.setShowHideInfo->point.x(), o->parm.setShowHideInfo->point.y(), o->parm.setShowHideInfo->size.width(), o->parm.setShowHideInfo->size.height());
156 #endif
157                 delete o->parm.setShowHideInfo;
158                 break;
159         }
160 #ifdef USE_LIBVUGLES2
161         case gOpcode::sendShowItem:
162         {
163                 gles_set_buffer((unsigned int *)surface.data);
164                 gles_set_animation_listbox(o->parm.setShowItemInfo->dir, o->parm.setShowItemInfo->point.x(), o->parm.setShowItemInfo->point.y(), o->parm.setShowItemInfo->size.width(), o->parm.setShowItemInfo->size.height());
165                 delete o->parm.setShowItemInfo;
166                 break;
167         }
168         case gOpcode::setFlush:
169         {
170                 gles_set_flush(o->parm.setFlush->enable);
171                 delete o->parm.setFlush;
172                 break;
173         }
174         case gOpcode::setView:
175         {
176                 gles_viewport(o->parm.setViewInfo->size.width(), o->parm.setViewInfo->size.height(), fb->Stride());
177                 delete o->parm.setViewInfo;
178                 break;
179         }
180 #endif
181         default:
182                 gDC::exec(o);
183                 break;
184         }
185 }
186
187 void gFBDC::setAlpha(int a)
188 {
189         alpha=a;
190
191         calcRamp();
192         setPalette();
193 }
194
195 void gFBDC::setBrightness(int b)
196 {
197         brightness=b;
198
199         calcRamp();
200         setPalette();
201 }
202
203 void gFBDC::setGamma(int g)
204 {
205         gamma=g;
206
207         calcRamp();
208         setPalette();
209 }
210
211 void gFBDC::setResolution(int xres, int yres)
212 {
213         if ((m_xres == xres) && (m_yres == yres))
214                 return;
215
216         m_xres = xres; m_yres = yres;
217
218         fb->SetMode(m_xres, m_yres, 32);
219
220         for (int y=0; y<m_yres; y++)    // make whole screen transparent
221                 memset(fb->lfb+y*fb->Stride(), 0x00, fb->Stride());
222
223         surface.type = 0;
224         surface.x = m_xres;
225         surface.y = m_yres;
226         surface.bpp = 32;
227         surface.bypp = 4;
228         surface.stride = fb->Stride();
229         surface.data = fb->lfb;
230         surface.offset = 0;
231
232         surface.data_phys = fb->getPhysAddr();
233
234         int fb_size = surface.stride * surface.y;
235
236         if (fb->getNumPages() > 1)
237         {
238                 m_enable_double_buffering = 1;
239                 surface_back.type = 0;
240                 surface_back.x = m_xres;
241                 surface_back.y = m_yres;
242                 surface_back.bpp = 32;
243                 surface_back.bypp = 4;
244                 surface_back.stride = fb->Stride();
245                 surface_back.offset = surface.y;
246                 surface_back.data = fb->lfb + fb_size;
247                 surface_back.data_phys = surface.data_phys + fb_size;
248
249                 fb_size *= 2;
250         } else
251                 m_enable_double_buffering = 0;
252
253         eDebug("%dkB available for acceleration surfaces.", (fb->Available() - fb_size)/1024);
254         eDebug("resolution: %d x %d x %d (stride: %d)", surface.x, surface.y, surface.bpp, fb->Stride());
255
256         if (gAccel::getInstance())
257                 gAccel::getInstance()->setAccelMemorySpace(fb->lfb + fb_size, surface.data_phys + fb_size, fb->Available() - fb_size);
258
259         if (!surface.clut.data)
260         {
261                 surface.clut.colors = 256;
262                 surface.clut.data = new gRGB[surface.clut.colors];
263                 memset(surface.clut.data, 0, sizeof(*surface.clut.data)*surface.clut.colors);
264         }
265
266         surface_back.clut = surface.clut;
267
268         m_pixmap = new gPixmap(&surface);
269 }
270
271 void gFBDC::saveSettings()
272 {
273 }
274
275 void gFBDC::reloadSettings()
276 {
277         alpha=255;
278         gamma=128;
279         brightness=128;
280
281         calcRamp();
282         setPalette();
283 }
284
285 eAutoInitPtr<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");