]> git.vomp.tv Git - vompclient.git/blob - surfaceopengl.cc
Preparations for dynamic mode switching
[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 \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, const DrawStyle& 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.rgba());\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, const DrawStyle& 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, const DrawStyle& 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,const DisplayRegion & region) //region should not matter for SD\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 //      Log::getInstance()->log("Surface", Log::WARN, "UTS Mark1");\r
214         srf_mutex.Lock();//since this might be called before surface\r
215   //allocation we will wait in this case, hopefully without deadlocks\r
216 \r
217   OsdOpenGL* osd=((OsdOpenGL*)(Osd::getInstance()));\r
218  // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark2");\r
219   GLuint screengltexture=((SurfaceOpenGL*)screen)->getTexture();\r
220 \r
221   osd->BeginPainting();\r
222  // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark3");\r
223   glBindTexture(GL_TEXTURE_2D, screengltexture);\r
224 //  Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4 %d",glGetError());\r
225 \r
226   for (int y=0;y<h;y++) { //hopefully this is not too slow\r
227          // Log::getInstance()->log("Surface", Log::WARN, "UTS Mark4a %d %d %d %d %d %d",sx,sy,w,h,dx,dy);\r
228           glTexSubImage2D(GL_TEXTURE_2D,0,dx,(dy+y),w,1,GL_RGBA,GL_UNSIGNED_BYTE,\r
229                           data+((y+sy)*swidth+sx)*sizeof(uint32_t));\r
230 \r
231 \r
232   }\r
233 \r
234   osd->EndPainting();\r
235 \r
236   srf_mutex.Unlock();\r
237 \r
238   return 0;\r
239 }\r
240 \r
241 int SurfaceOpenGL::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
242 {\r
243   //I don't see code using this function, so I skip it, since it is a MVP specific interface\r
244   return 0;\r
245 }\r
246 \r
247 void SurfaceOpenGL::screenShot(const char* fileName)\r
248 {\r
249   //Isn't this for debugging only, so I won't implement it yet\r
250 }\r
251 \r
252 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
253 {\r
254   //Isn't this for debugging only, so I won't implement it yet\r
255 }\r
256 \r
257 \r
258 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){\r
259 }/*\r
260   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
261   //allocation we will wait in this case, hopefully without deadlocks\r
262   if (!d3dsurface) {\r
263     return ; //why does this happen\r
264   }\r
265   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
266 \r
267 \r
268   D3DXIMAGE_INFO image_inf;\r
269   osd->BeginPainting();\r
270 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
271   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);\r
272   RECT dest_rec={x,y,x+image_inf.Width,\r
273     y+image_inf.Height};\r
274 /*  if (D3DXLoadSurfaceFromFile(\r
275     d3dsurface,\r
276     NULL,\r
277     &dest_rec,\r
278     fileName,\r
279     NULL,\r
280     D3DX_FILTER_NONE,\r
281     0,\r
282     &image_inf)!=D3D_OK) {\r
283       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
284 \r
285   }*\r
286   if (D3DXLoadSurfaceFromResource(\r
287     d3dsurface,\r
288     NULL,\r
289     &dest_rec,\r
290     NULL,\r
291     fileName,\r
292     NULL,\r
293     D3DX_FILTER_NONE,\r
294     0,\r
295     &image_inf)!=D3D_OK) {\r
296       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
297 \r
298   }\r
299   osd->EndPainting();\r
300   *width=image_inf.Width;\r
301   *height=image_inf.Height;\r
302 \r
303 }*/\r
304 \r
305 /*\r
306 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){\r
307   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
308   //allocation we will wait in this case, hopefully without deadlocks\r
309   if (!d3dsurface) {\r
310     return ; //why does this happen\r
311   }\r
312   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
313 \r
314 \r
315   D3DXIMAGE_INFO image_inf;\r
316   osd->BeginPainting();\r
317 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
318   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);\r
319   RECT dest_rec={x,y,x+image_inf.Width,\r
320     y+image_inf.Height};\r
321 /*  if (D3DXLoadSurfaceFromFile(\r
322     d3dsurface,\r
323     NULL,\r
324     &dest_rec,\r
325     fileName,\r
326     NULL,\r
327     D3DX_FILTER_NONE,\r
328     0,\r
329     &image_inf)!=D3D_OK) {\r
330       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
331 \r
332   }*/\r
333 /*  if (D3DXLoadSurfaceFromResource(\r
334     d3dsurface,\r
335     NULL,\r
336     &dest_rec,\r
337     NULL,\r
338     fileName,\r
339     NULL,\r
340     D3DX_FILTER_NONE,\r
341     0,\r
342     &image_inf)!=D3D_OK) {\r
343       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
344 \r
345   }*\r
346   if (D3DXLoadSurfaceFromFileInMemory(\r
347     d3dsurface,\r
348     NULL,\r
349     &dest_rec,\r
350     (void*)buffer,\r
351     buflength,\r
352     NULL,\r
353     D3DX_FILTER_NONE,\r
354     0,\r
355     &image_inf)!=D3D_OK) {\r
356       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
357 \r
358   }\r
359   osd->EndPainting();\r
360   *width=image_inf.Width;\r
361   *height=image_inf.Height;\r
362 \r
363 }*/\r
364 \r