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