]> git.vomp.tv Git - vompclient.git/blob - surfacewin.cc
*** empty log message ***
[vompclient.git] / surfacewin.cc
1 /*\r
2     Copyright 2006 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 */\r
20 \r
21 #include "surfacewin.h"\r
22 #include "osdwin.h"\r
23 #include <d3dx9tex.h>\r
24 \r
25 SurfaceWin::SurfaceWin(int id)\r
26 : Surface(id)\r
27 {\r
28   d3dtexture=NULL;\r
29   d3dsurface=NULL;\r
30   sheight=swidth=0;\r
31   event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);\r
32 }\r
33 \r
34 SurfaceWin::~SurfaceWin()\r
35 {\r
36   if (d3dsurface) d3dsurface->Release();\r
37   if (d3dtexture) d3dtexture->Release();\r
38   CloseHandle(event);\r
39 }\r
40 \r
41 int SurfaceWin::create(UINT width, UINT height)\r
42 {\r
43   LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();\r
44   while (true) {\r
45     if (screen==this) {\r
46       if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,\r
47         // Does every adapter with alpha blending support this?\r
48         D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {\r
49           MILLISLEEP(50);//wait maybe next time it will work\r
50           continue;\r
51       }\r
52       if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {\r
53         d3dtexture->Release();\r
54         d3dtexture=NULL;\r
55         MILLISLEEP(50);\r
56         continue;\r
57       }\r
58     } else {\r
59       HRESULT hres;\r
60       if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,\r
61         D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {\r
62           MILLISLEEP(50);//wait maybe next time it will work\r
63           continue;\r
64       }\r
65 \r
66     }\r
67     sheight=height;\r
68     swidth=width;\r
69     /* If someone does high performance Animations on the OSD, we have to change the types\r
70      of surface in order to address these performance issues, if we have only very few updates\r
71      per second this would be fast enough !*/\r
72     break;\r
73   }\r
74   SetEvent(event);\r
75   return 1;\r
76 }\r
77 \r
78 void SurfaceWin::display()\r
79 {\r
80 }\r
81 \r
82 int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)\r
83 {\r
84   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
85   //allocation we will wait in this case, hopefully without deadlocks\r
86   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
87 \r
88   if (!d3dsurface) {\r
89     return 0; //why does this happen\r
90   }\r
91 \r
92   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
93 \r
94   if (screen==this) {\r
95     //This should not happen!\r
96     return 0;\r
97 \r
98   } else {\r
99     osd->BeginPainting();\r
100     D3DLOCKED_RECT lockrect;\r
101     int cx,cy,cwidth,cheight;\r
102     cx=min(max(x,0),swidth);\r
103     cy=min(max(y,0),sheight);\r
104     cwidth=min(width,swidth-x);\r
105     cheight=min(height,sheight-y);\r
106     RECT rect={cx,cy,cwidth,cheight};\r
107 \r
108     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {\r
109       return 0;\r
110     }\r
111     unsigned int line;\r
112     unsigned int column;\r
113     for (line=0;line<cheight;line++) {\r
114       unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));\r
115       for (column=0;column<cwidth;column++) {\r
116         row[column]=c;\r
117       }\r
118     }\r
119 \r
120     if (d3dsurface->UnlockRect()!=D3D_OK) {\r
121       osd->EndPainting();\r
122       return 0;\r
123     }\r
124     osd->EndPainting();\r
125   }\r
126 \r
127   return 0;\r
128 }\r
129 \r
130 void SurfaceWin::drawPixel(int x, int y, unsigned int c)\r
131 {\r
132   //FixMe: locking for every single Pixel will be painfully slow\r
133   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
134   //allocation we will wait in this case, hopefully without deadlocks\r
135   if (!d3dsurface) {\r
136     return; //why does this happen\r
137   }\r
138   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
139   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
140   if (x>swidth || y>sheight) return; //do not draw outside the surface\r
141   if (screen==this) {\r
142     //This should not happen!\r
143     return ;\r
144 \r
145   } else {\r
146     osd->BeginPainting();\r
147     D3DLOCKED_RECT lockrect;\r
148     RECT rect={x,y,x+1,y+1};\r
149     if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {\r
150       osd->EndPainting();\r
151       return ;\r
152     }\r
153     unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));\r
154     row[0]=c;\r
155     if (d3dsurface->UnlockRect()!=D3D_OK) {\r
156       osd->EndPainting();\r
157       return ;\r
158     }\r
159     osd->EndPainting();\r
160   }\r
161 \r
162 }\r
163 \r
164 void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)\r
165 {\r
166    fillblt(x1, y, x2-x1, 1, c);\r
167 }\r
168 \r
169 void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)\r
170 {\r
171   fillblt(x, y1, 1, y2-y1, c);\r
172 }\r
173 \r
174 int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME\r
175 {\r
176   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
177   //allocation we will wait in this case, hopefully without deadlocks\r
178   if (!d3dsurface) {\r
179     return 0; //why does this happen\r
180   }\r
181   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
182   LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();\r
183     LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();\r
184   if (!screensurface) return 0;\r
185   RECT sourcerect={sx,sy,sx+w,sy+h};\r
186   POINT destpoint={dx,dy};\r
187   osd->BeginPainting();\r
188   if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {\r
189     Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");\r
190     osd->EndPainting();\r
191     return 0;\r
192   }\r
193   osd->EndPainting();\r
194   return 0;\r
195 }\r
196 \r
197 int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)\r
198 {\r
199   //I don't see code using this function, so I skip it, since it is a MVP specific interface\r
200   return 0;\r
201 }\r
202 \r
203 void SurfaceWin::screenShot(char* fileName)\r
204 {\r
205   //Isn't this for debugging only, so I won't implement it yet\r
206 }\r
207 \r
208 void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)\r
209 {\r
210   //Isn't this for debugging only, so I won't implement it yet\r
211 }\r
212 void SurfaceWin::ReleaseSurface()\r
213 {\r
214   ResetEvent(event);\r
215   LPDIRECT3DSURFACE9 temp_surf=d3dsurface;\r
216   LPDIRECT3DTEXTURE9 temp_text=d3dtexture;\r
217   d3dsurface=NULL;\r
218   d3dtexture=NULL;\r
219   sheight=swidth=0;\r
220   if (temp_surf) temp_surf->Release();\r
221   if (temp_text) temp_text->Release();\r
222 }\r
223 \r
224 void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){\r
225   WaitForSingleObject(event,INFINITE); //since this might be called before surface\r
226   //allocation we will wait in this case, hopefully without deadlocks\r
227   if (!d3dsurface) {\r
228     return ; //why does this happen\r
229   }\r
230   OsdWin* osd=((OsdWin*)(Osd::getInstance()));\r
231 \r
232 \r
233   D3DXIMAGE_INFO image_inf;\r
234   osd->BeginPainting();\r
235 //  D3DXGetImageInfoFromFile(fileName,&image_inf);\r
236   D3DXGetImageInfoFromResource(NULL,fileName,&image_inf);\r
237   RECT dest_rec={x,y,x+image_inf.Width,\r
238     y+image_inf.Height};\r
239 /*  if (D3DXLoadSurfaceFromFile(\r
240     d3dsurface,\r
241     NULL,\r
242     &dest_rec,\r
243     fileName,\r
244     NULL,\r
245     D3DX_FILTER_NONE,\r
246     0,\r
247     &image_inf)!=D3D_OK) {\r
248       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
249 \r
250   }*/\r
251   if (D3DXLoadSurfaceFromResource(\r
252     d3dsurface,\r
253     NULL,\r
254     &dest_rec,\r
255     NULL,\r
256     fileName,\r
257     NULL,\r
258     D3DX_FILTER_NONE,\r
259     0,\r
260     &image_inf)!=D3D_OK) {\r
261       Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");\r
262 \r
263   }\r
264   osd->EndPainting();\r
265   *width=image_inf.Width;\r
266   *height=image_inf.Height;\r
267 \r
268 }\r
269 \r