]> git.vomp.tv Git - vompclient.git/blob - surfaceopengl.cc
Add files specific for raspberry pi
[vompclient.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                 sheight = 64;\r
66                 swidth = 64;\r
67                 while (sheight < height) { // should be a power of 2\r
68                         sheight *= 2;\r
69                 }\r
70                 while (swidth < width) { // should be a power of 2\r
71                         swidth *= 2;\r
72                 }\r
73                 glGenTextures(1, &gltexture);\r
74 \r
75                 glBindTexture(GL_TEXTURE_2D, gltexture);\r
76 \r
77                 void *image = malloc(sheight * swidth * 4);\r
78                 memset(image, 0, sheight * swidth * 4);\r
79         /*      for (int i=0;i< sheight * swidth * 4; i++) { //fill it with garbage, useful for debugging\r
80                         ((char*)image)[i]=i%255;\r
81                 }*/\r
82                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, swidth, sheight, 0, GL_RGBA,\r
83                                 GL_UNSIGNED_BYTE, image);\r
84 \r
85         } else {\r
86                 sheight = height;\r
87                 swidth = width;\r
88                 data=(char*)malloc(sizeof(uint32_t)*width*height);\r
89         }\r
90 \r
91 \r
92         //osd->EndPainting();\r
93         srf_mutex.Unlock();\r
94         return 1;\r
95 }\r
96 \r
97 void SurfaceOpenGL::display()\r
98 {\r
99 }\r
100 \r
101 int SurfaceOpenGL::fillblt(int x, int y, int width, int height, unsigned int c) {\r
102         srf_mutex.Lock();\r
103         //since this might be called before surface\r
104         //allocation we will wait in this case, hopefully without deadlocks\r
105         if (screen == this || !data ) {\r
106                 //This should not happen!\r
107                 srf_mutex.Unlock();\r
108                 return 0;\r
109 \r
110         }\r
111         /*   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
112 \r
113          osd->BeginPainting();\r
114 \r
115          glViewport(0,0,swidth,sheight);*/\r
116 \r
117         //osd->EndPainting();\r
118         srf_mutex.Unlock();\r
119 \r
120         unsigned int my_c=InternalColour(c);\r
121 \r
122         int iheight=height;\r
123         if (height+y>sheight) iheight=sheight-y;\r
124         int iwidth=width;\r
125     if (width+x>swidth) iwidth=swidth-y;\r
126 \r
127         unsigned int line;\r
128         unsigned int column;\r
129         for (line = y; line < (iheight + y); line++) {\r
130                 uint32_t *row = ((unsigned int*) (((char*) data) + (swidth * line + x)\r
131                                 * sizeof(uint32_t)));\r
132                 for (column = 0; column < iwidth; column++) {\r
133                         row[column] = my_c;\r
134                 }\r
135         }\r
136 \r
137 /*      if (d3dsurface->UnlockRect() != D3D_OK) {\r
138                 osd->EndPainting();\r
139                 return 0;\r
140         }\r
141         osd->EndPainting();*/\r
142 \r
143         return 0;\r
144 }\r
145 \r
146 \r
147 void SurfaceOpenGL::startFastDraw(){\r
148         srf_mutex.Lock();\r
149 \r
150 }\r
151 void SurfaceOpenGL::endFastDraw(){\r
152         srf_mutex.Unlock();\r
153  }\r
154 \r
155 void SurfaceOpenGL::drawPixel(int x, int y, Colour & colour, bool fastdraw) {\r
156   int c = (  (0xFF000000         )\r
157              | (colour.red    << 16)\r
158              | (colour.green  <<  8)\r
159              | (colour.blue        ) );\r
160 \r
161     drawPixel(x, y, c, fastdraw);\r
162   }\r
163 \r
164 void SurfaceOpenGL::drawPixel(int x, int y, unsigned int c, bool fastdraw) {\r
165         //FixMe: locking for every single Pixel will be painfully slow\r
166         if (screen == this) {\r
167                 //This should not happen!\r
168                 return ;\r
169         }\r
170         if (!data) {\r
171                 return; //why does this happen\r
172         }\r
173         //OsdWin* osd;\r
174         if (!fastdraw) {\r
175                 srf_mutex.Lock(); //since this might be called before surface\r
176         }\r
177         //allocation we will wait in this case, hopefully without deadlocks\r
178 \r
179         //osd = ((OsdWin*) (Osd::getInstance()));\r
180 \r
181         if (x >= swidth || y >= sheight)\r
182                 return; //do not draw outside the surface\r
183 \r
184         unsigned int my_c=InternalColour(c);\r
185 \r
186         unsigned int*row = (unsigned int*) (((char*) data + (swidth * y + x)\r
187                         * sizeof(uint32_t)));\r
188         row[0] = my_c;\r
189 \r
190         if (!fastdraw) {\r
191                 srf_mutex.Unlock(); //since this might be called before surface\r
192         }\r
193 \r
194 }\r
195 \r
196 void SurfaceOpenGL::drawHorzLine(int x1, int x2, int y, unsigned int c)\r
197 {\r
198    fillblt(x1, y, x2-x1, 1, c);\r
199 }\r
200 \r
201 void SurfaceOpenGL::drawVertLine(int x, int y1, int y2, unsigned int c)\r
202 {\r
203   fillblt(x, y1, 1, y2-y1, c);\r
204 }\r
205 \r
206 void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm)\r
207 {\r
208   // Temporary code? Draw one pixel at a time using drawPixel()\r
209   startFastDraw();\r
210   for (UINT j = 0; j < bm.getHeight(); ++j)\r
211     for (UINT i = 0; i < bm.getWidth(); ++i)\r
212       drawPixel(x+i, y+j, bm.getColour(i,j),true);\r
213   endFastDraw();\r
214 }\r
215 \r
216 int SurfaceOpenGL::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME\r
217 {\r
218         srf_mutex.Lock();//since this might be called before surface\r
219   //allocation we will wait in this case, hopefully without deadlocks\r
220  /* if (!d3dsurface) {\r
221     return 0; //why does this happen\r
222   }*/\r
223   OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));\r
224 \r
225   GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture();\r
226 \r
227   osd->BeginPainting();\r
228   glBindTexture(GL_TEXTURE_2D, screengltexture);\r
229   //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3 %d",glGetError());\r
230 \r
231   for (int y=0;y<h;y++) { //hopefully this is not too slow\r
232           glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE,\r
233                           data+((y+sy)*swidth+sx)*sizeof(uint32_t));\r
234          // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark43 %d",glGetError());\r
235 \r
236   }\r
237   //Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError());\r
238   osd->EndPainting();\r
239   srf_mutex.Unlock();\r
240   return 0;\r
241 }\r
242 \r
243 int SurfaceOpenGL::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
244 {\r
245   //I don't see code using this function, so I skip it, since it is a MVP specific interface\r
246   return 0;\r
247 }\r
248 \r
249 void SurfaceOpenGL::screenShot(const char* fileName)\r
250 {\r
251   //Isn't this for debugging only, so I won't implement it yet\r
252 }\r
253 \r
254 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
255 {\r
256   //Isn't this for debugging only, so I won't implement it yet\r
257 }\r
258 \r
259 \r
260 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){\r
261 }/*\r
262   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
263   //allocation we will wait in this case, hopefully without deadlocks\r
264   if (!d3dsurface) {\r
265     return ; //why does this happen\r
266   }\r
267   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
268 \r
269 \r
270   D3DXIMAGE_INFO image_inf;\r
271   osd->BeginPainting();\r
272 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
273   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);\r
274   RECT dest_rec={x,y,x+image_inf.Width,\r
275     y+image_inf.Height};\r
276 /*  if (D3DXLoadSurfaceFromFile(\r
277     d3dsurface,\r
278     NULL,\r
279     &dest_rec,\r
280     fileName,\r
281     NULL,\r
282     D3DX_FILTER_NONE,\r
283     0,\r
284     &image_inf)!=D3D_OK) {\r
285       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
286 \r
287   }*\r
288   if (D3DXLoadSurfaceFromResource(\r
289     d3dsurface,\r
290     NULL,\r
291     &dest_rec,\r
292     NULL,\r
293     fileName,\r
294     NULL,\r
295     D3DX_FILTER_NONE,\r
296     0,\r
297     &image_inf)!=D3D_OK) {\r
298       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
299 \r
300   }\r
301   osd->EndPainting();\r
302   *width=image_inf.Width;\r
303   *height=image_inf.Height;\r
304 \r
305 }*/\r
306 \r
307 /*\r
308 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){\r
309   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
310   //allocation we will wait in this case, hopefully without deadlocks\r
311   if (!d3dsurface) {\r
312     return ; //why does this happen\r
313   }\r
314   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
315 \r
316 \r
317   D3DXIMAGE_INFO image_inf;\r
318   osd->BeginPainting();\r
319 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
320   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);\r
321   RECT dest_rec={x,y,x+image_inf.Width,\r
322     y+image_inf.Height};\r
323 /*  if (D3DXLoadSurfaceFromFile(\r
324     d3dsurface,\r
325     NULL,\r
326     &dest_rec,\r
327     fileName,\r
328     NULL,\r
329     D3DX_FILTER_NONE,\r
330     0,\r
331     &image_inf)!=D3D_OK) {\r
332       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
333 \r
334   }*/\r
335 /*  if (D3DXLoadSurfaceFromResource(\r
336     d3dsurface,\r
337     NULL,\r
338     &dest_rec,\r
339     NULL,\r
340     fileName,\r
341     NULL,\r
342     D3DX_FILTER_NONE,\r
343     0,\r
344     &image_inf)!=D3D_OK) {\r
345       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
346 \r
347   }*\r
348   if (D3DXLoadSurfaceFromFileInMemory(\r
349     d3dsurface,\r
350     NULL,\r
351     &dest_rec,\r
352     (void*)buffer,\r
353     buflength,\r
354     NULL,\r
355     D3DX_FILTER_NONE,\r
356     0,\r
357     &image_inf)!=D3D_OK) {\r
358       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
359 \r
360   }\r
361   osd->EndPainting();\r
362   *width=image_inf.Width;\r
363   *height=image_inf.Height;\r
364 \r
365 }*/\r
366 \r