]> git.vomp.tv Git - vompclient.git/blob - surfacedirectfb.cc
Preparations for dynamic mode switching
[vompclient.git] / surfacedirectfb.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon, 2009 Marten Richter\r
3     Portions copyright 2008 Jon Gettler\r
4 \r
5     This file is part of VOMP.\r
6 \r
7     VOMP is free software; you can redistribute it and/or modify\r
8     it under the terms of the GNU General Public License as published by\r
9     the Free Software Foundation; either version 2 of the License, or\r
10     (at your option) any later version.\r
11 \r
12     VOMP is distributed in the hope that it will be useful,\r
13     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15     GNU General Public License for more details.\r
16 \r
17     You should have received a copy of the GNU General Public License\r
18     along with VOMP; if not, write to the Free Software\r
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
20 */\r
21 \r
22 #include "surfacedirectfb.h"\r
23 \r
24 #include "osd.h"\r
25 #include "bitmap.h"\r
26 #include "log.h"\r
27 \r
28 #include "osddirectfb.h"\r
29 \r
30 \r
31 \r
32 SurfaceDirectFB::SurfaceDirectFB(int id)\r
33 : Surface(id)\r
34 {\r
35    surface=NULL;\r
36 }\r
37 \r
38 SurfaceDirectFB::~SurfaceDirectFB()\r
39 {\r
40    if (surface) surface->Release(surface);\r
41 \r
42 }\r
43 \r
44 int SurfaceDirectFB::create(UINT width, UINT height)\r
45 {\r
46   int counter=0;\r
47   while (!Osd::getInstance()->isInitted() && counter<2000) {\r
48     MILLISLEEP(50); //Wait for Grafiksystem initialization\r
49     counter++;\r
50   }\r
51   if (!Osd::getInstance()->isInitted()) return -1;\r
52   \r
53   IDirectFB*dfb=((OsdDirectFB*)Osd::getInstance())->getDfb();\r
54 printf("ich bin doof");fflush(stdout);  \r
55   if (screen == this) \r
56   {\r
57     IDirectFBDisplayLayer *osd_layer=((OsdDirectFB*)Osd::getInstance())->getOsdLayer();\r
58     if (osd_layer->GetSurface(osd_layer,&surface)!=DFB_OK) \r
59     {\r
60 \r
61         return 0;\r
62     }\r
63     surface->Clear(surface,0x0,0x0,0x0,0xFF);\r
64   } else {\r
65     DFBSurfaceDescription dsc;\r
66     memset(&dsc,0,sizeof(dsc));\r
67     *((int*)&dsc.flags)=DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;\r
68     \r
69     dsc.width=width;\r
70     dsc.height=height;\r
71     dsc.caps= DSCAPS_NONE;\r
72     if (dfb->CreateSurface(dfb,&dsc,&surface)!=DFB_OK) \r
73     {\r
74         return 0;\r
75     }\r
76   }\r
77   return 1;\r
78 }\r
79 \r
80 void SurfaceDirectFB::display()\r
81 {\r
82 //  unsigned long fb_descriptor[2];\r
83 /*\r
84   fb_descriptor[0] = surface.sfc.handle;\r
85   fb_descriptor[1] = 1;\r
86 */\r
87 //  ioctl(fdOsd, GFX_FB_ATTACH, fb_descriptor);\r
88 }\r
89 \r
90 \r
91 // ----------------------------------------------------------------------------\r
92 \r
93 // Now for the drawing functions\r
94 \r
95 \r
96 int SurfaceDirectFB::fillblt(int x, int y, int width, int height, unsigned int c)\r
97 {\r
98     int sw,sh;\r
99     unsigned char r,g,b,a;\r
100     int nx,ny,nw,nh;\r
101     nx=x;\r
102     ny=y;\r
103     nw=width;\r
104     nh=height;\r
105     surface->GetSize(surface,&sw,&sh);\r
106     \r
107     if (nx >sw) nx=sw-1;\r
108     if (ny >sh) ny=sh-1;\r
109     \r
110     if ((nx+nw) >= sw) nw=sw-nx; \r
111     if ((ny+nh) >= sh) nh=sh-ny; \r
112 \r
113     if ((nx<0) || (ny < 0) || (nh <=0) || (nw <=0)) {\r
114         return 0;\r
115     }\r
116     \r
117     a= (c &0xff000000)>>24;\r
118     r= (c &0x00ff0000)>>16;\r
119     g= (c &0x0000ff00)>>8;\r
120     b= (c &0x000000ff);\r
121     \r
122     \r
123     surface->SetColor(surface,r,g,b,a);\r
124     surface->FillRectangle(surface,nx,ny,nw,nh);\r
125     return 0;\r
126 }\r
127 \r
128 void SurfaceDirectFB::drawPixel(int x, int y, unsigned int c, bool fastdraw)\r
129 {\r
130     int sw,sh;\r
131     unsigned char r,g,b,a;\r
132     char *dst=NULL;\r
133     int offset=0;\r
134     int pitch;\r
135     surface->GetSize(surface,&sw,&sh);\r
136     if (x>=sw) return;\r
137     if (y>=sh) return;\r
138     \r
139 \r
140     \r
141     a= (c &0xff000000)>>24;\r
142     r= (c &0x00ff0000)>>16;\r
143     g= (c &0x0000ff00)>>8;\r
144     b= (c &0x000000ff);\r
145 \r
146     //TODO Fastdraw\r
147     if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {\r
148         offset= y* pitch+x*4;\r
149         dst[offset++]=b;\r
150         dst[offset++]=g;\r
151         dst[offset++]=r;\r
152         dst[offset]=a;\r
153         surface->Unlock(surface);\r
154      }\r
155 \r
156 }\r
157 \r
158 void SurfaceDirectFB::drawPixel(int x, int y, Colour& c, bool fastdraw)\r
159 {\r
160     int sw,sh;\r
161     char *dst=NULL;\r
162     int offset=0;\r
163     int pitch;\r
164     surface->GetSize(surface,&sw,&sh);\r
165     if (x>=sw) return;\r
166     if (y>=sh) return;\r
167     \r
168     //TODO Fastdraw\r
169     if (surface->Lock(surface,DSLF_WRITE,(void**)(void*)&dst,&pitch) == DFB_OK) {\r
170         offset= y* pitch+x*4;\r
171         dst[offset++]=c.blue;\r
172         dst[offset++]=c.green;\r
173         dst[offset++]=c.red;\r
174         dst[offset]=c.alpha;\r
175         surface->Unlock(surface);\r
176      }\r
177 \r
178 }\r
179  \r
180 void SurfaceDirectFB::drawHorzLine(int x1, int x2, int y, unsigned int c)\r
181 {\r
182   fillblt(x1, y, x2-x1, 1, c);\r
183 }\r
184 \r
185 void SurfaceDirectFB::drawVertLine(int x, int y1, int y2, unsigned int c)\r
186 {\r
187   fillblt(x, y1, 1, y2-y1, c);\r
188 }\r
189 \r
190 void SurfaceDirectFB::drawBitmap(int x, int y, const Bitmap& bm)\r
191 {/*\r
192   UINT bmw = bm.getWidth(); UINT bmh = bm.getHeight();\r
193   if (bmw == 0 || bmh == 0) return;\r
194   if ((x >= (int)surface.sfc.width) || (y >= (int)surface.sfc.height)) return;\r
195   int remainder = (surface.sfc.width % 4);\r
196   UINT line;\r
197   if (remainder == 0)\r
198     line = surface.sfc.width;\r
199   else\r
200     line = surface.sfc.width + (4 - remainder);\r
201   const std::vector<UCHAR>& bmdata = bm.rawData();\r
202   const std::vector<UCHAR>& Y = bm.palette.getYVector();\r
203   const std::vector<UCHAR>& Cr = bm.palette.getCrVector();\r
204   const std::vector<UCHAR>& Cb = bm.palette.getCbVector();\r
205   const std::vector<UCHAR>& A = bm.palette.getAVector();\r
206   UINT b_offset = 0;\r
207   UINT s_offset = x + y*line;\r
208   UINT plotWidth = bmw;\r
209   UINT plotHeight = bmh;\r
210   if (x + plotWidth - 1 > surface.sfc.width)\r
211     plotWidth = surface.sfc.width - x + 1;\r
212   if (y + plotHeight - 1 > surface.sfc.height)\r
213     plotHeight = surface.sfc.height - y + 1;\r
214   for (UINT j = 0; j < plotHeight; ++j)\r
215   {\r
216     UINT i = 0;\r
217     if (x & 1) // odd x - need to plot first column separately\r
218     {\r
219       UCHAR index = bmdata[b_offset];\r
220       *(surface.base[0] + s_offset) = Y[index];\r
221       *(surface.base[1] + s_offset - 1) = Cb[index];\r
222       *(surface.base[1] + s_offset) = Cr[index];\r
223       *(surface.base[2] + s_offset) = A[index];\r
224       i = 1;\r
225     }\r
226     // Now, plot pairs of pixels with averaged chroma values\r
227     while (i < plotWidth - 1)\r
228     {\r
229       UCHAR index1 = bmdata[b_offset + i];\r
230       UCHAR index2 = bmdata[b_offset + i + 1];\r
231       *(surface.base[0] + s_offset + i) = Y[index1];\r
232       *(surface.base[0] + s_offset + i + 1) = Y[index2];\r
233       *(surface.base[1] + s_offset + i) = (Cb[index1] + Cb[index2]) / 2;\r
234       *(surface.base[1] + s_offset + i + 1) = (Cr[index1] + Cr[index2]) / 2;\r
235       *(surface.base[2] + s_offset + i) = A[index1];\r
236       *(surface.base[2] + s_offset + i + 1) = A[index2];\r
237       i += 2;\r
238     }\r
239     if (i == plotWidth - 1) // One column left to do\r
240     {\r
241       UCHAR index = bmdata[b_offset + i];\r
242       *(surface.base[0] + s_offset + i) = Y[index];\r
243       *(surface.base[1] + s_offset + i) = Cb[index];\r
244       *(surface.base[1] + s_offset + i + 1) = Cr[index];\r
245       *(surface.base[2] + s_offset + i) = A[index];\r
246     }\r
247     s_offset += line;\r
248     b_offset += bmw;\r
249   }*/\r
250 }\r
251 \r
252   /* surface update to screen needs:\r
253   source x distance into this surface\r
254   source y distance into this surface\r
255   width of update\r
256   height of update\r
257   destination x on screen\r
258   destination y on screen\r
259   */\r
260 int SurfaceDirectFB::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME\r
261 {\r
262   IDirectFBSurface* screensurf=((SurfaceDirectFB*)screen)->getSurfaceDFB();\r
263   if (!screensurf) return 0;\r
264   if (this==screen) return 0;\r
265   \r
266   DFBRectangle rect;\r
267   int sw,sh;\r
268   \r
269   screensurf->GetSize(screensurf,&sw,&sh);\r
270 //  screensurf->Clear(screensurf,0x0,0x0,0x0,0xFF);\r
271   rect.x = sx;\r
272   rect.y=sy;\r
273   rect.w=w;\r
274   rect.h=h;\r
275   \r
276   DFBRectangle drect; //TODO make osd HD\r
277   drect.x=dx*sw/720;\r
278   drect.y=dy*sh/576;\r
279   drect.w=w*sw/720;\r
280   drect.h=h*sh/576;\r
281   \r
282 //  screensurf->Blit(screensurf,surface,&rect,dx,dy);\r
283   screensurf->StretchBlit(screensurf,surface,&rect,&drect);\r
284   \r
285   return 0;//blt(fdOsd, surface.sfc.handle, sx, sy, w, h, ((SurfaceDirectFB*)screen)->getSurfaceHandle(), dx, dy);\r
286 }\r
287 \r
288 int SurfaceDirectFB::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
289 {//Skip it, noone uses this!\r
290 \r
291   return 0;\r
292 }\r
293 \r
294 void SurfaceDirectFB::screenShot(const char* fileName)\r
295 {\r
296   return;\r
297   \r
298 }\r
299 \r
300 void SurfaceDirectFB::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
301 {\r
302   \r
303 }\r
304 \r