]> git.vomp.tv Git - vompclient-marten.git/blob - surfacewin.cc
Live radio prebuffering display - code upgrades for connection lost handling
[vompclient-marten.git] / surfacewin.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, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "surfacewin.h"
22 #include "osdwin.h"
23 #include "log.h"
24
25 SurfaceWin::SurfaceWin(int id)
26 : Surface(id)
27 {
28   d3dtexture=NULL;
29   d3dsurface=NULL;
30   sheight=swidth=0;
31   fastdraw=false;
32   event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
33 }
34
35 SurfaceWin::~SurfaceWin()
36 {
37   if (d3dsurface) d3dsurface->Release();
38   if (d3dtexture) d3dtexture->Release();
39   CloseHandle(event);
40 }
41
42 int SurfaceWin::create(UINT width, UINT height)
43 {
44   LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();
45   while (true) {
46     if (screen==this) {
47       if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
48         // Does every adapter with alpha blending support this?
49         D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
50           MILLISLEEP(50);//wait maybe next time it will work
51           continue;
52       }
53       if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
54         d3dtexture->Release();
55         d3dtexture=NULL;
56         MILLISLEEP(50);
57         continue;
58       }
59     } else {
60       HRESULT hres;
61       if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
62         D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
63           MILLISLEEP(50);//wait maybe next time it will work
64           continue;
65       }
66
67     }
68     sheight=height;
69     swidth=width;
70     /* If someone does high performance Animations on the OSD, we have to change the types
71      of surface in order to address these performance issues, if we have only very few updates
72      per second this would be fast enough !*/
73     break;
74   }
75   SetEvent(event);
76   return 1;
77 }
78
79 void SurfaceWin::display()
80 {
81 }
82
83 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
84 {
85   WaitForSingleObject(event,INFINITE); //since this might be called before surface
86   //allocation we will wait in this case, hopefully without deadlocks
87   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
88
89   if (!d3dsurface) {
90     return 0; //why does this happen
91   }
92
93   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
94
95   if (screen==this) {
96     //This should not happen!
97     return 0;
98
99   } else {
100     osd->BeginPainting();
101     D3DLOCKED_RECT lockrect;
102     int cx,cy,cwidth,cheight;
103     cx=min(max(x,0),swidth-1);
104     cy=min(max(y,0),sheight-1);
105     cwidth=min(width,swidth-x);
106     cheight=min(height,sheight-y);
107     RECT rect={cx,cy,cwidth,cheight};
108
109     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
110       return 0;
111     }
112     unsigned int line;
113     unsigned int column;
114     for (line=0;line<cheight;line++) {
115       unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
116       for (column=0;column<cwidth;column++) {
117         row[column]=c;
118       }
119     }
120
121     if (d3dsurface->UnlockRect()!=D3D_OK) {
122       osd->EndPainting();
123       return 0;
124     }
125     osd->EndPainting();
126   }
127
128   return 0;
129 }
130
131
132 void SurfaceWin::startFastDraw(){
133     WaitForSingleObject(event,INFINITE); //since this might be called before surface
134   //allocation we will wait in this case, hopefully without deadlocks
135   if (!d3dsurface) {
136     return; //why does this happen
137   }
138   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
139   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
140   if (screen==this) {
141     //This should not happen!
142     return ;
143
144   } else {
145     osd->BeginPainting();
146 //    D3DLOCKED_RECT lockrect;
147     RECT rect={0,0,swidth,sheight};
148     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
149       osd->EndPainting();
150       return ;
151     }
152   }
153   fastdraw=true;
154 }
155 void SurfaceWin::endFastDraw(){
156     OsdWin* osd=((OsdWin*)(Osd::getInstance()));
157     if (d3dsurface->UnlockRect()!=D3D_OK) {
158       osd->EndPainting();
159       return ;
160     }
161     osd->EndPainting();
162     fastdraw=false;
163  }
164
165
166 void SurfaceWin::drawPixel(int x, int y, unsigned int c)
167 {
168   //FixMe: locking for every single Pixel will be painfully slow
169     OsdWin* osd;
170     if (!fastdraw) {
171   WaitForSingleObject(event,INFINITE); //since this might be called before surface
172   //allocation we will wait in this case, hopefully without deadlocks
173   if (!d3dsurface) {
174     return; //why does this happen
175   }
176          osd=((OsdWin*)(Osd::getInstance()));
177     }
178   if (x>=swidth || y>=sheight) return; //do not draw outside the surface
179   if (screen==this) {
180     //This should not happen!
181     return ;
182
183   } else {
184       if (!fastdraw) {
185     osd->BeginPainting();
186 //        D3DLOCKED_RECT lockrect;
187     RECT rect={x,y,x+1,y+1};
188     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
189       osd->EndPainting();
190       return ;
191     }
192     unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
193     row[0]=c;
194     if (d3dsurface->UnlockRect()!=D3D_OK) {
195       osd->EndPainting();
196       return ;
197     }
198     osd->EndPainting();
199       } else {
200           unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
201           row[0]=c;
202       }
203
204   }
205
206 }
207
208 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
209 {
210    fillblt(x1, y, x2-x1, 1, c);
211 }
212
213 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
214 {
215   fillblt(x, y1, 1, y2-y1, c);
216 }
217
218 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
219 {
220   WaitForSingleObject(event,INFINITE); //since this might be called before surface
221   //allocation we will wait in this case, hopefully without deadlocks
222   if (!d3dsurface) {
223     return 0; //why does this happen
224   }
225   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
226   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
227     LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
228   if (!screensurface) return 0;
229   RECT sourcerect={sx,sy,sx+w,sy+h};
230   POINT destpoint={dx,dy};
231   osd->BeginPainting();
232   if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
233     Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
234     osd->EndPainting();
235     return 0;
236   }
237   osd->EndPainting();
238   return 0;
239 }
240
241 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
242 {
243   //I don't see code using this function, so I skip it, since it is a MVP specific interface
244   return 0;
245 }
246
247 void SurfaceWin::screenShot(char* fileName)
248 {
249   //Isn't this for debugging only, so I won't implement it yet
250 }
251
252 void SurfaceWin::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 void SurfaceWin::ReleaseSurface()
257 {
258   ResetEvent(event);
259   LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
260   LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
261   d3dsurface=NULL;
262   d3dtexture=NULL;
263   sheight=swidth=0;
264   if (temp_surf) temp_surf->Release();
265   if (temp_text) temp_text->Release();
266 }
267 /*
268 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
269   WaitForSingleObject(event,INFINITE); //since this might be called before surface
270   //allocation we will wait in this case, hopefully without deadlocks
271   if (!d3dsurface) {
272     return ; //why does this happen
273   }
274   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
275
276
277   D3DXIMAGE_INFO image_inf;
278   osd->BeginPainting();
279 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
280   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
281   RECT dest_rec={x,y,x+image_inf.Width,
282     y+image_inf.Height};
283 /*  if (D3DXLoadSurfaceFromFile(
284     d3dsurface,
285     NULL,
286     &dest_rec,
287     fileName,
288     NULL,
289     D3DX_FILTER_NONE,
290     0,
291     &image_inf)!=D3D_OK) {
292       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
293
294   }*
295   if (D3DXLoadSurfaceFromResource(
296     d3dsurface,
297     NULL,
298     &dest_rec,
299     NULL,
300     fileName,
301     NULL,
302     D3DX_FILTER_NONE,
303     0,
304     &image_inf)!=D3D_OK) {
305       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
306
307   }
308   osd->EndPainting();
309   *width=image_inf.Width;
310   *height=image_inf.Height;
311
312 }
313
314 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
315   WaitForSingleObject(event,INFINITE); //since this might be called before surface
316   //allocation we will wait in this case, hopefully without deadlocks
317   if (!d3dsurface) {
318     return ; //why does this happen
319   }
320   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
321
322
323   D3DXIMAGE_INFO image_inf;
324   osd->BeginPainting();
325 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
326   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
327   RECT dest_rec={x,y,x+image_inf.Width,
328     y+image_inf.Height};
329 /*  if (D3DXLoadSurfaceFromFile(
330     d3dsurface,
331     NULL,
332     &dest_rec,
333     fileName,
334     NULL,
335     D3DX_FILTER_NONE,
336     0,
337     &image_inf)!=D3D_OK) {
338       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
339
340   }*/
341 /*  if (D3DXLoadSurfaceFromResource(
342     d3dsurface,
343     NULL,
344     &dest_rec,
345     NULL,
346     fileName,
347     NULL,
348     D3DX_FILTER_NONE,
349     0,
350     &image_inf)!=D3D_OK) {
351       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
352
353   }*
354   if (D3DXLoadSurfaceFromFileInMemory(
355     d3dsurface,
356     NULL,
357     &dest_rec,
358     (void*)buffer,
359     buflength,
360     NULL,
361     D3DX_FILTER_NONE,
362     0,
363     &image_inf)!=D3D_OK) {
364       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
365
366   }
367   osd->EndPainting();
368   *width=image_inf.Width;
369   *height=image_inf.Height;
370
371 }*/
372