]> git.vomp.tv Git - vompclient.git/blob - surfacewin.cc
Vogel Media Player 2008-11-28
[vompclient.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 "bitmap.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 void SurfaceWin::drawPixel(int x, int y, Colour & colour) {
167   int c = (  (0xFF000000         )
168              | (colour.red    << 16)
169              | (colour.green  <<  8)
170              | (colour.blue        ) );
171
172     drawPixel(x, y, c);
173   }
174
175 void SurfaceWin::drawPixel(int x, int y, unsigned int c)
176 {
177   //FixMe: locking for every single Pixel will be painfully slow
178     OsdWin* osd;
179     if (!fastdraw) {
180   WaitForSingleObject(event,INFINITE); //since this might be called before surface
181   //allocation we will wait in this case, hopefully without deadlocks
182   if (!d3dsurface) {
183     return; //why does this happen
184   }
185          osd=((OsdWin*)(Osd::getInstance()));
186     }
187   if (x>=swidth || y>=sheight) return; //do not draw outside the surface
188   if (screen==this) {
189     //This should not happen!
190     return ;
191
192   } else {
193       if (!fastdraw) {
194     osd->BeginPainting();
195 //        D3DLOCKED_RECT lockrect;
196     RECT rect={x,y,x+1,y+1};
197     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
198       osd->EndPainting();
199       return ;
200     }
201     unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
202     row[0]=c;
203     if (d3dsurface->UnlockRect()!=D3D_OK) {
204       osd->EndPainting();
205       return ;
206     }
207     osd->EndPainting();
208       } else {
209           unsigned int*row=(unsigned int*)(((char*)lockrect.pBits+lockrect.Pitch*y+4*x));
210           row[0]=c;
211       }
212
213   }
214
215 }
216
217 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
218 {
219    fillblt(x1, y, x2-x1, 1, c);
220 }
221
222 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
223 {
224   fillblt(x, y1, 1, y2-y1, c);
225 }
226
227 void SurfaceWin::drawBitmap(int x, int y, const Bitmap& bm)
228 {
229   // Temporary code? Draw one pixel at a time using drawPixel()
230   startFastDraw();
231   for (UINT j = 0; j < bm.getHeight(); ++j)
232     for (UINT i = 0; i < bm.getWidth(); ++i)
233       drawPixel(x+i, y+j, bm.getColour(i,j));
234   endFastDraw();
235 }
236
237 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
238 {
239   WaitForSingleObject(event,INFINITE); //since this might be called before surface
240   //allocation we will wait in this case, hopefully without deadlocks
241   if (!d3dsurface) {
242     return 0; //why does this happen
243   }
244   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
245   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
246     LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
247   if (!screensurface) return 0;
248   RECT sourcerect={sx,sy,sx+w,sy+h};
249   POINT destpoint={dx,dy};
250   osd->BeginPainting();
251   if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
252     Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
253     osd->EndPainting();
254     return 0;
255   }
256   osd->EndPainting();
257   return 0;
258 }
259
260 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
261 {
262   //I don't see code using this function, so I skip it, since it is a MVP specific interface
263   return 0;
264 }
265
266 void SurfaceWin::screenShot(char* fileName)
267 {
268   //Isn't this for debugging only, so I won't implement it yet
269 }
270
271 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
272 {
273   //Isn't this for debugging only, so I won't implement it yet
274 }
275 void SurfaceWin::ReleaseSurface()
276 {
277   ResetEvent(event);
278   LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
279   LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
280   d3dsurface=NULL;
281   d3dtexture=NULL;
282   sheight=swidth=0;
283   if (temp_surf) temp_surf->Release();
284   if (temp_text) temp_text->Release();
285 }
286 /*
287 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
288   WaitForSingleObject(event,INFINITE); //since this might be called before surface
289   //allocation we will wait in this case, hopefully without deadlocks
290   if (!d3dsurface) {
291     return ; //why does this happen
292   }
293   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
294
295
296   D3DXIMAGE_INFO image_inf;
297   osd->BeginPainting();
298 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
299   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);
300   RECT dest_rec={x,y,x+image_inf.Width,
301     y+image_inf.Height};
302 /*  if (D3DXLoadSurfaceFromFile(
303     d3dsurface,
304     NULL,
305     &dest_rec,
306     fileName,
307     NULL,
308     D3DX_FILTER_NONE,
309     0,
310     &image_inf)!=D3D_OK) {
311       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
312
313   }*
314   if (D3DXLoadSurfaceFromResource(
315     d3dsurface,
316     NULL,
317     &dest_rec,
318     NULL,
319     fileName,
320     NULL,
321     D3DX_FILTER_NONE,
322     0,
323     &image_inf)!=D3D_OK) {
324       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
325
326   }
327   osd->EndPainting();
328   *width=image_inf.Width;
329   *height=image_inf.Height;
330
331 }
332
333 void SurfaceWin::drawJpeg(char *buffer,ULONG buflength,DWORD x, DWORD y,DWORD *width, DWORD *height){
334   WaitForSingleObject(event,INFINITE); //since this might be called before surface
335   //allocation we will wait in this case, hopefully without deadlocks
336   if (!d3dsurface) {
337     return ; //why does this happen
338   }
339   OsdWin* osd=((OsdWin*)(Osd::getInstance()));
340
341
342   D3DXIMAGE_INFO image_inf;
343   osd->BeginPainting();
344 //  D3DXGetImageInfoFromFile(fileName,&image_inf);
345   D3DXGetImageInfoFromFileInMemory((void*)buffer,buflength,&image_inf);
346   RECT dest_rec={x,y,x+image_inf.Width,
347     y+image_inf.Height};
348 /*  if (D3DXLoadSurfaceFromFile(
349     d3dsurface,
350     NULL,
351     &dest_rec,
352     fileName,
353     NULL,
354     D3DX_FILTER_NONE,
355     0,
356     &image_inf)!=D3D_OK) {
357       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
358
359   }*/
360 /*  if (D3DXLoadSurfaceFromResource(
361     d3dsurface,
362     NULL,
363     &dest_rec,
364     NULL,
365     fileName,
366     NULL,
367     D3DX_FILTER_NONE,
368     0,
369     &image_inf)!=D3D_OK) {
370       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
371
372   }*
373   if (D3DXLoadSurfaceFromFileInMemory(
374     d3dsurface,
375     NULL,
376     &dest_rec,
377     (void*)buffer,
378     buflength,
379     NULL,
380     D3DX_FILTER_NONE,
381     0,
382     &image_inf)!=D3D_OK) {
383       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
384
385   }
386   osd->EndPainting();
387   *width=image_inf.Width;
388   *height=image_inf.Height;
389
390 }*/
391