]> git.vomp.tv Git - vompclient-marten.git/blob - surfaceopengl.cc
FFMPEG decoding in color at 7 fps
[vompclient-marten.git] / surfaceopengl.cc
1 /*\r
2     Copyright 2006 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include <stdlib.h>\r
22 \r
23 #include "surfaceopengl.h"\r
24 #include "osdopengl.h"\r
25 #include "bitmap.h"\r
26 #include "log.h"\r
27 #include "mutex.h"\r
28 \r
29 inline unsigned int InternalColour(unsigned int c){\r
30         return (c &0x000000FF)<<16 |\r
31                                           (c &0x0000FF00) |\r
32                                           (c &0x00FF0000)>>16 |\r
33                                           (c &0xFF000000);\r
34 }\r
35 \r
36 SurfaceOpenGL::SurfaceOpenGL(int id)\r
37 : Surface(id)\r
38 {\r
39         gltexture=0;\r
40   data=NULL;\r
41   sheight=swidth=0;\r
42 //  fastdraw=false;\r
43   srf_mutex.Lock();\r
44 }\r
45 \r
46 SurfaceOpenGL::~SurfaceOpenGL()\r
47 {\r
48         srf_mutex.Lock();\r
49         if (data) {\r
50                 free(data);\r
51                 data=NULL;\r
52         } else {\r
53                 glDeleteTextures(1,&gltexture);\r
54         }\r
55         srf_mutex.Unlock();\r
56 }\r
57 \r
58 int SurfaceOpenGL::create(UINT width, UINT height)\r
59 {\r
60         OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));\r
61         //osd->BeginPainting();\r
62 \r
63 \r
64         if (this == screen) { // We do not need locking here, since the osd calls this\r
65 \r
66                 swidth=width;\r
67                 sheight=height;\r
68                 glGenTextures(1, &gltexture);\r
69 \r
70                 glBindTexture(GL_TEXTURE_2D, gltexture);\r
71 \r
72                 void *image = malloc(sheight * swidth * 4);\r
73                 memset(image, 0, sheight * swidth * 4);\r
74         /*      for (int i=0;i< sheight * swidth * 4; i++) { //fill it with garbage, useful for debugging\r
75                         ((char*)image)[i]=i%255;\r
76                 }*/\r
77                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, swidth, sheight, 0, GL_RGBA,\r
78                                 GL_UNSIGNED_BYTE, image);\r
79 \r
80         } else {\r
81                 sheight = height;\r
82                 swidth = width;\r
83                 data=(char*)malloc(sizeof(uint32_t)*width*height);\r
84         }\r
85 \r
86 \r
87         //osd->EndPainting();\r
88         srf_mutex.Unlock();\r
89         return 1;\r
90 }\r
91 \r
92 void SurfaceOpenGL::display()\r
93 {\r
94 }\r
95 \r
96 int SurfaceOpenGL::fillblt(int x, int y, int width, int height, unsigned int c) {\r
97         srf_mutex.Lock();\r
98         //since this might be called before surface\r
99         //allocation we will wait in this case, hopefully without deadlocks\r
100         if (screen == this || !data ) {\r
101                 //This should not happen!\r
102                 srf_mutex.Unlock();\r
103                 return 0;\r
104 \r
105         }\r
106         /*   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
107 \r
108          osd->BeginPainting();\r
109 \r
110          glViewport(0,0,swidth,sheight);*/\r
111 \r
112         //osd->EndPainting();\r
113         srf_mutex.Unlock();\r
114 \r
115         unsigned int my_c=InternalColour(c);\r
116 \r
117         int iheight=height;\r
118         if (height+y>sheight) iheight=sheight-y;\r
119         int iwidth=width;\r
120     if (width+x>swidth) iwidth=swidth-y;\r
121 \r
122         unsigned int line;\r
123         unsigned int column;\r
124         for (line = y; line < (iheight + y); line++) {\r
125                 uint32_t *row = ((unsigned int*) (((char*) data) + (swidth * line + x)\r
126                                 * sizeof(uint32_t)));\r
127                 for (column = 0; column < iwidth; column++) {\r
128                         row[column] = my_c;\r
129                 }\r
130         }\r
131 \r
132 /*      if (d3dsurface->UnlockRect() != D3D_OK) {\r
133                 osd->EndPainting();\r
134                 return 0;\r
135         }\r
136         osd->EndPainting();*/\r
137 \r
138         return 0;\r
139 }\r
140 \r
141 \r
142 void SurfaceOpenGL::startFastDraw(){\r
143         srf_mutex.Lock();\r
144 \r
145 }\r
146 void SurfaceOpenGL::endFastDraw(){\r
147         srf_mutex.Unlock();\r
148  }\r
149 \r
150 void SurfaceOpenGL::drawPixel(int x, int y, Colour & colour, bool fastdraw) {\r
151   int c = (  (0xFF000000         )\r
152              | (colour.red    << 16)\r
153              | (colour.green  <<  8)\r
154              | (colour.blue        ) );\r
155 \r
156     drawPixel(x, y, c, fastdraw);\r
157   }\r
158 \r
159 void SurfaceOpenGL::drawPixel(int x, int y, unsigned int c, bool fastdraw) {\r
160         //FixMe: locking for every single Pixel will be painfully slow\r
161         if (screen == this) {\r
162                 //This should not happen!\r
163                 return ;\r
164         }\r
165         if (!data) {\r
166                 return; //why does this happen\r
167         }\r
168         //OsdWin* osd;\r
169         if (!fastdraw) {\r
170                 srf_mutex.Lock(); //since this might be called before surface\r
171         }\r
172         //allocation we will wait in this case, hopefully without deadlocks\r
173 \r
174         //osd = ((OsdWin*) (Osd::getInstance()));\r
175 \r
176         if (x >= swidth || y >= sheight)\r
177                 return; //do not draw outside the surface\r
178 \r
179         unsigned int my_c=InternalColour(c);\r
180 \r
181         unsigned int*row = (unsigned int*) (((char*) data + (swidth * y + x)\r
182                         * sizeof(uint32_t)));\r
183         row[0] = my_c;\r
184 \r
185         if (!fastdraw) {\r
186                 srf_mutex.Unlock(); //since this might be called before surface\r
187         }\r
188 \r
189 }\r
190 \r
191 void SurfaceOpenGL::drawHorzLine(int x1, int x2, int y, unsigned int c)\r
192 {\r
193    fillblt(x1, y, x2-x1, 1, c);\r
194 }\r
195 \r
196 void SurfaceOpenGL::drawVertLine(int x, int y1, int y2, unsigned int c)\r
197 {\r
198   fillblt(x, y1, 1, y2-y1, c);\r
199 }\r
200 \r
201 void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm)\r
202 {\r
203   // Temporary code? Draw one pixel at a time using drawPixel()\r
204   startFastDraw();\r
205   for (UINT j = 0; j < bm.getHeight(); ++j)\r
206     for (UINT i = 0; i < bm.getWidth(); ++i)\r
207       drawPixel(x+i, y+j, bm.getColour(i,j),true);\r
208   endFastDraw();\r
209 }\r
210 \r
211 int SurfaceOpenGL::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME\r
212 {\r
213         srf_mutex.Lock();//since this might be called before surface\r
214   //allocation we will wait in this case, hopefully without deadlocks\r
215  /* if (!d3dsurface) {\r
216     return 0; //why does this happen\r
217   }*/\r
218   OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));\r
219 \r
220   GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture();\r
221 \r
222   osd->BeginPainting();\r
223   glBindTexture(GL_TEXTURE_2D, screengltexture);\r
224   //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3 %d",glGetError());\r
225 \r
226   for (int y=0;y<h;y++) { //hopefully this is not too slow\r
227           glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE,\r
228                           data+((y+sy)*swidth+sx)*sizeof(uint32_t));\r
229          // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark43 %d",glGetError());\r
230 \r
231   }\r
232   //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError());\r
233   osd->EndPainting();\r
234   srf_mutex.Unlock();\r
235   return 0;\r
236 }\r
237 \r
238 int SurfaceOpenGL::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
239 {\r
240   //I don't see code using this function, so I skip it, since it is a MVP specific interface\r
241   return 0;\r
242 }\r
243 \r
244 void SurfaceOpenGL::screenShot(const char* fileName)\r
245 {\r
246   //Isn't this for debugging only, so I won't implement it yet\r
247 }\r
248 \r
249 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
250 {\r
251   //Isn't this for debugging only, so I won't implement it yet\r
252 }\r
253 \r
254 \r
255 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){\r
256 }/*\r
257   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
258   //allocation we will wait in this case, hopefully without deadlocks\r
259   if (!d3dsurface) {\r
260     return ; //why does this happen\r
261   }\r
262   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
263 \r
264 \r
265   D3DXIMAGE_INFO image_inf;\r
266   osd->BeginPainting();\r
267 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
268   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);\r
269   RECT dest_rec={x,y,x+image_inf.Width,\r
270     y+image_inf.Height};\r
271 /*  if (D3DXLoadSurfaceFromFile(\r
272     d3dsurface,\r
273     NULL,\r
274     &dest_rec,\r
275     fileName,\r
276     NULL,\r
277     D3DX_FILTER_NONE,\r
278     0,\r
279     &image_inf)!=D3D_OK) {\r
280       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
281 \r
282   }*\r
283   if (D3DXLoadSurfaceFromResource(\r
284     d3dsurface,\r
285     NULL,\r
286     &dest_rec,\r
287     NULL,\r
288     fileName,\r
289     NULL,\r
290     D3DX_FILTER_NONE,\r
291     0,\r
292     &image_inf)!=D3D_OK) {\r
293       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
294 \r
295   }\r
296   osd->EndPainting();\r
297   *width=image_inf.Width;\r
298   *height=image_inf.Height;\r
299 \r
300 }*/\r
301 \r
302 /*\r
303 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){\r
304   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
305   //allocation we will wait in this case, hopefully without deadlocks\r
306   if (!d3dsurface) {\r
307     return ; //why does this happen\r
308   }\r
309   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
310 \r
311 \r
312   D3DXIMAGE_INFO image_inf;\r
313   osd->BeginPainting();\r
314 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
315   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);\r
316   RECT dest_rec={x,y,x+image_inf.Width,\r
317     y+image_inf.Height};\r
318 /*  if (D3DXLoadSurfaceFromFile(\r
319     d3dsurface,\r
320     NULL,\r
321     &dest_rec,\r
322     fileName,\r
323     NULL,\r
324     D3DX_FILTER_NONE,\r
325     0,\r
326     &image_inf)!=D3D_OK) {\r
327       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
328 \r
329   }*/\r
330 /*  if (D3DXLoadSurfaceFromResource(\r
331     d3dsurface,\r
332     NULL,\r
333     &dest_rec,\r
334     NULL,\r
335     fileName,\r
336     NULL,\r
337     D3DX_FILTER_NONE,\r
338     0,\r
339     &image_inf)!=D3D_OK) {\r
340       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
341 \r
342   }*\r
343   if (D3DXLoadSurfaceFromFileInMemory(\r
344     d3dsurface,\r
345     NULL,\r
346     &dest_rec,\r
347     (void*)buffer,\r
348     buflength,\r
349     NULL,\r
350     D3DX_FILTER_NONE,\r
351     0,\r
352     &image_inf)!=D3D_OK) {\r
353       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
354 \r
355   }\r
356   osd->EndPainting();\r
357   *width=image_inf.Width;\r
358   *height=image_inf.Height;\r
359 \r
360 }*/\r
361 \r