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