]> git.vomp.tv Git - vompclient.git/blob - surfaceopengl.cc
Bitmap and VPictureBanner CWFs
[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 bool SurfaceOpenGL::screenShot(const char* fileName)
247 {
248   //Isn't this for debugging only, so I won't implement it yet
249   return false;  
250 }
251
252 void SurfaceOpenGL::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
253 {
254   //Isn't this for debugging only, so I won't implement it yet
255 }
256
257
258 void SurfaceOpenGL::drawJpeg(const char *fileName,int x, int y,int *width, int *height){
259 }/*
260   WaitForSingleObject(event,INFINITE); //since this might be called before surface
261   //allocation we will wait in this case, hopefully without deadlocks
262   if (!d3dsurface) {
263     return ; //why does this happen
264   }
265   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
266
267
268   D3DXIMAGE_INFO image_inf;
269   osd->BeginPainting();
270 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
271   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
272   RECT dest_rec={x,y,x+image_inf.Width,
273     y+image_inf.Height};
274 /*  if (D3DXLoadSurfaceFromFile(
275     d3dsurface,
276     NULL,
277     &dest_rec,
278     fileName,
279     NULL,
280     D3DX_FILTER_NONE,
281     0,
282     &image_inf)!=D3D_OK) {
283       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
284
285   }*
286   if (D3DXLoadSurfaceFromResource(
287     d3dsurface,
288     NULL,
289     &dest_rec,
290     NULL,
291     fileName,
292     NULL,
293     D3DX_FILTER_NONE,
294     0,
295     &image_inf)!=D3D_OK) {
296       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
297
298   }
299   osd->EndPainting();
300   *width=image_inf.Width;
301   *height=image_inf.Height;
302
303 }*/
304
305 /*
306 void SurfaceOpenGL::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
307   WaitForSingleObject(event,INFINITE); //since this might be called before surface
308   //allocation we will wait in this case, hopefully without deadlocks
309   if (!d3dsurface) {
310     return ; //why does this happen
311   }
312   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
313
314
315   D3DXIMAGE_INFO image_inf;
316   osd->BeginPainting();
317 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
318   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
319   RECT dest_rec={x,y,x+image_inf.Width,
320     y+image_inf.Height};
321 /*  if (D3DXLoadSurfaceFromFile(
322     d3dsurface,
323     NULL,
324     &dest_rec,
325     fileName,
326     NULL,
327     D3DX_FILTER_NONE,
328     0,
329     &image_inf)!=D3D_OK) {
330       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
331
332   }*/
333 /*  if (D3DXLoadSurfaceFromResource(
334     d3dsurface,
335     NULL,
336     &dest_rec,
337     NULL,
338     fileName,
339     NULL,
340     D3DX_FILTER_NONE,
341     0,
342     &image_inf)!=D3D_OK) {
343       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
344
345   }*
346   if (D3DXLoadSurfaceFromFileInMemory(
347     d3dsurface,
348     NULL,
349     &dest_rec,
350     (void*)buffer,
351     buflength,
352     NULL,
353     D3DX_FILTER_NONE,
354     0,
355     &image_inf)!=D3D_OK) {
356       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
357
358   }
359   osd->EndPainting();
360   *width=image_inf.Width;
361   *height=image_inf.Height;
362
363 }*/
364