]> git.vomp.tv Git - vompclient.git/blob - osdwin.cc
Preparations for dynamic mode switching
[vompclient.git] / osdwin.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 \r
22 #include "osdwin.h"\r
23 #include "mtd.h"\r
24 #include "videowin.h"\r
25 #include "surfacewin.h"\r
26 \r
27 #include "dsallocator.h"\r
28 #include "message.h"\r
29 #include "command.h"\r
30 \r
31 #define  BACKBUFFER_WIDTH 1280\r
32 #define  BACKBUFFER_HEIGHT 720\r
33 \r
34 \r
35 \r
36 typedef HRESULT (__stdcall *FCT_DXVA2CreateDirect3DDeviceManager9)(UINT* pResetToken, IDirect3DDeviceManager9** ppDeviceManager);\r
37 typedef HRESULT (__stdcall *FCT_MFCreateVideoSampleFromSurface)(IUnknown* pUnkSurface, IMFSample** ppSample);\r
38 \r
39 FCT_DXVA2CreateDirect3DDeviceManager9 ptrDXVA2CreateDirect3DDeviceManager9=NULL;\r
40 FCT_MFCreateVideoSampleFromSurface ptrMFCreateVideoSampleFromSurface=NULL;\r
41 \r
42 //This is stuff for rendering the OSD\r
43 \r
44 \r
45 OsdWin::OsdWin()\r
46 {\r
47   d3d=NULL;\r
48   d3ddevice=NULL;\r
49   d3drtsurf=NULL;\r
50   swappy=NULL;\r
51   swapsurf=NULL;\r
52   evrstate=EVR_pres_off;\r
53   window=NULL;\r
54 \r
55   external_driving=false;\r
56   dsallocator=NULL;\r
57   filter_type=D3DTEXF_FORCE_DWORD;\r
58   lastrendertime=timeGetTime();\r
59   event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);\r
60   d3dmutex = CreateMutex(NULL,FALSE,NULL);\r
61   /*EVR stuff*/\r
62   dxvadevicehandle=NULL;\r
63   evrsupported=true;\r
64   HMODULE hlib=NULL;\r
65   hlib=LoadLibrary("dxva2.dll");\r
66   if (!hlib) {\r
67           evrsupported=false;\r
68           return;\r
69   }\r
70   ptrDXVA2CreateDirect3DDeviceManager9=(FCT_DXVA2CreateDirect3DDeviceManager9)GetProcAddress(hlib, "DXVA2CreateDirect3DDeviceManager9");\r
71   if (!ptrDXVA2CreateDirect3DDeviceManager9){\r
72           evrsupported=false;\r
73           return;\r
74   }\r
75 \r
76   hlib=LoadLibrary("evr.dll");\r
77   if (!hlib) {\r
78           evrsupported=false;\r
79           return;\r
80   }\r
81  \r
82   ptrMFCreateVideoSampleFromSurface = (FCT_MFCreateVideoSampleFromSurface)GetProcAddress(hlib,"MFCreateVideoSampleFromSurface");\r
83   if (!ptrMFCreateVideoSampleFromSurface){\r
84           evrsupported=false;\r
85           return;\r
86   }\r
87   \r
88 }\r
89 \r
90 OsdWin::~OsdWin()\r
91 {\r
92 \r
93   if (initted) \r
94   {\r
95           threadStop();\r
96                 shutdown();\r
97   }\r
98   CloseHandle(event);\r
99   CloseHandle(d3dmutex);\r
100 }\r
101 \r
102 int OsdWin::getFD()\r
103 {\r
104   if (!initted) return 0;\r
105   return fdOsd;\r
106 }\r
107 \r
108 Surface * OsdWin::createNewSurface(){\r
109         return (Surface*)new SurfaceWin();\r
110 }\r
111 \r
112 int OsdWin::init(void* device)\r
113 {\r
114   if (initted) return 0;\r
115    Video* video = Video::getInstance();\r
116    window=*((HWND*)device);\r
117   //First Create Direct 3D Object\r
118   d3d=Direct3DCreate9(D3D_SDK_VERSION);\r
119   if (!d3d) \r
120   {\r
121     Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 object!");\r
122     return 0;\r
123   }\r
124   // then create the Device\r
125   D3DPRESENT_PARAMETERS d3dparas;\r
126   ZeroMemory(&d3dparas,sizeof(d3dparas));\r
127   d3dparas.BackBufferWidth=BACKBUFFER_WIDTH;\r
128   d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT;\r
129   d3dparas.Windowed=TRUE;\r
130   d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;\r
131   if (d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,*((HWND*) device),\r
132           D3DCREATE_SOFTWARE_VERTEXPROCESSING |D3DCREATE_MULTITHREADED,&d3dparas,&d3ddevice)!=D3D_OK) {\r
133            Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 device!");\r
134        return 0;\r
135   }\r
136   d3ddevice->GetRenderTarget(0,&d3drtsurf);\r
137 \r
138   /*\r
139   if (!InitVertexBuffer()) {\r
140            Log::getInstance()->log("OSD", Log::WARN, "Could not create Direct3D9 vertex buf!");\r
141                   return 0;\r
142   }*/\r
143   /* We have to determine which kind of filtering is supported*/\r
144   D3DCAPS9 caps;\r
145   d3ddevice->GetDeviceCaps(&caps);\r
146   if ( ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)!=0)\r
147           && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR)!=0)) {\r
148           if (filter_type==D3DTEXF_FORCE_DWORD) {\r
149                         filter_type=D3DTEXF_LINEAR;\r
150           }\r
151   } else {\r
152       if (filter_type==D3DTEXF_LINEAR)\r
153       {\r
154           filter_type=D3DTEXF_POINT;\r
155       }\r
156   }\r
157   \r
158   if ( ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MINFPOINT)!=0)\r
159           && ((caps.StretchRectFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)!=0)) {\r
160        if (filter_type==D3DTEXF_FORCE_DWORD) \r
161        {\r
162                   filter_type=D3DTEXF_POINT;\r
163    }\r
164    } else {\r
165        if (filter_type==D3DTEXF_POINT) {\r
166            filter_type=D3DTEXF_NONE;\r
167    }\r
168    }\r
169    if (filter_type==D3DTEXF_FORCE_DWORD) {\r
170        filter_type=D3DTEXF_NONE;\r
171    }\r
172 \r
173    if (evrsupported)\r
174    {\r
175            if (ptrDXVA2CreateDirect3DDeviceManager9(&dxvatoken,&d3ddevman)!=S_OK) evrsupported=false;\r
176            else {\r
177                    d3ddevman->ResetDevice(d3ddevice,dxvatoken);\r
178            }\r
179    }\r
180 \r
181 \r
182 \r
183 \r
184   //Now we will create the Screen\r
185   screen = new SurfaceWin(Surface::SCREEN);\r
186   SetEvent(event);//Now all devices are ready\r
187   screen->create(video->getScreenWidth(), video->getScreenHeight());\r
188   screen->display();\r
189   initted = 1; // must set this here or create surface won't work\r
190   threadStart(); \r
191 \r
192   return 1;\r
193 }\r
194 \r
195 void OsdWin::LockDevice()\r
196 {\r
197         if (!evrsupported) return;\r
198         if (!dxvadevicehandle) \r
199         {\r
200                 d3ddevman->OpenDeviceHandle(&dxvadevicehandle);\r
201         }\r
202         IDirect3DDevice9 *temp;\r
203         d3ddevman->LockDevice(dxvadevicehandle,&temp,TRUE);\r
204 \r
205 }\r
206 \r
207 void OsdWin::UnlockDevice()\r
208 {\r
209         if (!evrsupported) return;\r
210         if (!initted) return;\r
211         d3ddevman->UnlockDevice(dxvadevicehandle,TRUE);\r
212         if (dxvadevicehandle) \r
213         {\r
214                 d3ddevman->CloseDeviceHandle(dxvadevicehandle);\r
215                 dxvadevicehandle=NULL;\r
216         }\r
217 \r
218 }\r
219 \r
220 DWORD OsdWin::getFilterCaps()\r
221 {\r
222     if (!initted) return NULL;\r
223     D3DCAPS9 caps;\r
224     d3ddevice->GetDeviceCaps(&caps);\r
225     return caps.StretchRectFilterCaps;\r
226 }\r
227         \r
228 LPDIRECT3DVERTEXBUFFER9  OsdWin::InitVertexBuffer(DWORD width, DWORD height)\r
229 {\r
230   LPDIRECT3DVERTEXBUFFER9 ret =NULL;\r
231   Video* video=Video::getInstance();\r
232   FLOAT texx=((float)video->getScreenWidth())/1024.f;\r
233   FLOAT texy=((float)video->getScreenHeight())/1024.f;\r
234   D3DCOLOR osdcolor=D3DCOLOR_RGBA(255,255,255,255);\r
235   osdvertices[0].c=osdcolor;\r
236   osdvertices[0].x=0.f-0.5f;\r
237   osdvertices[0].y=0.f-0.5f;\r
238   osdvertices[0].z=0.5f;\r
239   osdvertices[0].rhw=1.f;\r
240   osdvertices[0].u=0.f;\r
241   osdvertices[0].v=0.f;\r
242   osdvertices[1].c=osdcolor;\r
243   osdvertices[1].x=((float)width)-0.5f;\r
244   osdvertices[1].y=0.f-0.5f;\r
245   osdvertices[1].z=0.5f;\r
246   osdvertices[1].u=texx;\r
247   osdvertices[1].v=0.f;\r
248   osdvertices[1].rhw=1.f;\r
249   osdvertices[2].c=osdcolor;\r
250   osdvertices[2].x=((float)width)-0.5f;\r
251   osdvertices[2].y=((float)height)-0.5f;\r
252   osdvertices[2].z=0.5f;\r
253   osdvertices[2].rhw=1.f;\r
254   osdvertices[2].u=texx;\r
255   osdvertices[2].v=texy;\r
256   osdvertices[3].c=osdcolor;\r
257   osdvertices[3].x=0.f-0.5f;\r
258   osdvertices[3].y=((float)height)-0.5f;\r
259   osdvertices[3].z=0.5f;\r
260   osdvertices[3].rhw=1.f;\r
261   osdvertices[3].u=0.f;\r
262   osdvertices[3].v=texy;\r
263   \r
264   if (d3ddevice->CreateVertexBuffer(4*sizeof(OSDVERTEX),0,D3DFVF_OSDVERTEX,D3DPOOL_MANAGED,\r
265           &ret,NULL)!=D3D_OK) {\r
266           return NULL;\r
267   }\r
268   void *pvertex=NULL;\r
269   if (ret->Lock(0,sizeof(osdvertices),&pvertex,0)!=D3D_OK) {\r
270           return NULL;\r
271   }\r
272   memcpy(pvertex,osdvertices,sizeof(osdvertices));\r
273   ret->Unlock();\r
274   return ret;\r
275 }\r
276 \r
277 int OsdWin::shutdown()\r
278 {\r
279   if (!initted) return 0;\r
280   initted = 0;\r
281   evrsupported=0;\r
282   if (d3ddevman) d3ddevman->Release();\r
283   d3drtsurf->Release();\r
284   d3ddevice->Release();\r
285   d3d->Release();\r
286   if (swapsurf) swapsurf->Release();\r
287   if (swappy) swappy->Release();\r
288 \r
289   return 1;\r
290 }\r
291 \r
292 void OsdWin::screenShot(const char* fileName)\r
293 {\r
294   screen->screenShot(fileName);\r
295 }\r
296 \r
297 void OsdWin::threadMethod()\r
298 {\r
299         while (true)\r
300         {\r
301                 DWORD waittime=10;\r
302                 if (initted){\r
303                         if (evrstate==EVR_pres_off || evrstate==EVR_pres_pause) \r
304                         {\r
305                                 Render();\r
306                         } else if (evrstate==EVR_pres_started)\r
307                         {\r
308                                 LPDIRECT3DSURFACE9 surf;\r
309                                 if (dsallocator) dsallocator->GetNextSurface(&surf,&waittime);\r
310                                 if (surf==NULL)\r
311                                 {\r
312                                         Render();\r
313                                 }\r
314                                 else\r
315                                 {\r
316                                         RenderDS(surf);\r
317                                         surf->Release();\r
318                                         if (dsallocator) dsallocator->DiscardSurfaceandgetWait(&waittime);\r
319                                 }\r
320                         }\r
321                 }\r
322                 threadCheckExit();\r
323                 if (waittime!=0) Sleep(min(10,waittime));\r
324                 //Sleep(1);\r
325         }\r
326 }\r
327 \r
328 \r
329 void OsdWin::threadPostStopCleanup()\r
330 {\r
331         //Doing nothing\r
332         //goo;\r
333 }\r
334 \r
335 \r
336 // This function is called from the WinMain function in order to get Screen updates\r
337 void OsdWin::Render()\r
338 {\r
339         if (!initted) return ;\r
340         if (external_driving) {\r
341         DWORD time1=timeGetTime(); //Updates the Menue\r
342                 if ((time1-lastrendertime)>200) {//5 fps for OSD updates are enough, avoids tearing\r
343                         InternalRendering(NULL);\r
344                         lastrendertime=timeGetTime();\r
345         } else {\r
346                    //Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads\r
347         }\r
348         } else {\r
349                 DWORD time1=timeGetTime();\r
350                 if ((time1-lastrendertime)>50) {//10 fps for OSD updates are enough, avoids tearing\r
351                         InternalRendering(NULL);\r
352                         lastrendertime=timeGetTime();\r
353                 } else {\r
354                         //Sleep(5);\r
355                 \r
356                 }\r
357                 \r
358         }\r
359 }\r
360 \r
361 void OsdWin::RenderDS(LPDIRECT3DSURFACE9 present){\r
362         if (!initted) return; \r
363         if (external_driving) {\r
364                 InternalRendering(present);\r
365         lastrendertime=timeGetTime();\r
366         }\r
367 }\r
368 \r
369 \r
370 void OsdWin::InternalRendering(LPDIRECT3DSURFACE9 present){\r
371     BeginPainting();\r
372     HRESULT losty=d3ddevice->TestCooperativeLevel();\r
373     if (losty==D3DERR_DEVICELOST) {\r
374         //Sleep(10);\r
375                 EndPainting();\r
376         return; //Device Lost\r
377     }\r
378     if (losty==D3DERR_DEVICENOTRESET){\r
379            EndPainting();\r
380        DoLost();\r
381        return;\r
382     }\r
383         WaitForSingleObject(event,INFINITE);\r
384         \r
385    \r
386         \r
387     \r
388     LPDIRECT3DSURFACE9 targetsurf;\r
389         if (swappy)\r
390         {\r
391                 targetsurf=swapsurf;\r
392                 d3ddevice->SetRenderTarget(0,swapsurf);//Stupid VMR manipulates the render target\r
393         } \r
394         else\r
395         {\r
396                 targetsurf=d3drtsurf;\r
397                 d3ddevice->SetRenderTarget(0,d3drtsurf);//Stupid VMR manipulates the render target\r
398         }\r
399         D3DSURFACE_DESC targetdesc;\r
400         targetsurf->GetDesc(&targetdesc);\r
401 \r
402         if (external_driving) {\r
403                 //Copy video to Backbuffer\r
404                 if (present!=NULL ) {\r
405                         VideoWin* video =(VideoWin*) Video::getInstance();\r
406                         /*calculating destination rect */\r
407                         RECT destrect={0,0,/*video->getScreenWidth()*/ targetdesc.Width,\r
408                                 /*video->getScreenHeight()*/targetdesc.Height};\r
409                         UCHAR mode=video->getMode();\r
410                         switch (mode) {\r
411                         case Video::EIGHTH:\r
412                         destrect.right=destrect.right/2;\r
413                         destrect.bottom=destrect.bottom/2;\r
414                         case Video::QUARTER:\r
415                         destrect.right=destrect.right/2+video->getPosx()*2;\r
416                         destrect.bottom=destrect.bottom/2+video->getPosy()*2;\r
417                         destrect.left=video->getPosx()*2;\r
418                         destrect.top=video->getPosy()*2;\r
419                         d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);\r
420                         break;\r
421                         };\r
422                         D3DSURFACE_DESC surf_desc;\r
423                         present->GetDesc(&surf_desc);//for chop sides\r
424                         RECT sourcerect= {0,0,surf_desc.Width,surf_desc.Height};\r
425                         if (video->getPseudoTVsize()==Video::ASPECT4X3 \r
426                                 && video->getMode()==Video::NORMAL \r
427                                 && video->getAspectRatio()==Video::ASPECT16X9) {\r
428                                         unsigned int correction=((double) (surf_desc.Width))*4.*9./3./16.;\r
429                                         sourcerect.left=(surf_desc.Width-correction)/2;\r
430                                         sourcerect.right=sourcerect.left+correction;\r
431                         }\r
432                         d3ddevice->StretchRect(present,&sourcerect,targetsurf ,&destrect,filter_type);\r
433 \r
434                 }\r
435         } else {\r
436                 VideoWin* video =(VideoWin*) Video::getInstance();\r
437                 //Clear Background\r
438                 if (!video->isVideoOn()) d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);\r
439         }\r
440         LPDIRECT3DVERTEXBUFFER9 vb=NULL;\r
441         vb=InitVertexBuffer(targetdesc.Width,targetdesc.Height);\r
442 \r
443         //Drawing the OSD\r
444         if (d3ddevice->BeginScene()==D3D_OK) {\r
445                 d3ddevice->SetStreamSource(0,vb,0,sizeof(OSDVERTEX));\r
446                 d3ddevice->SetFVF(D3DFVF_OSDVERTEX);\r
447                 d3ddevice->SetTexture(0,((SurfaceWin*)screen)->getD3dtexture());\r
448                 //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);\r
449                 d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE);\r
450 \r
451         d3ddevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);\r
452         d3ddevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);\r
453 \r
454 \r
455                 d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);\r
456                 d3ddevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);\r
457                 d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);\r
458                 d3ddevice->SetRenderState(D3DRS_LIGHTING,FALSE);\r
459 \r
460 \r
461                 d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);\r
462                 d3ddevice->EndScene();\r
463                 //Show it to the user!\r
464         HRESULT hres;\r
465                 if (swappy)\r
466                 {\r
467                         if (hres=swappy->Present(NULL,NULL,NULL,NULL,0)==D3DERR_DEVICELOST){\r
468                                 //EndPainting();\r
469                                 if (!external_driving) DoLost();\r
470                         }\r
471                 } \r
472                 else\r
473                 {\r
474                         if (hres=d3ddevice->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST){\r
475                                 //EndPainting();\r
476                                 if (!external_driving) DoLost();\r
477                         }\r
478                 }\r
479                 \r
480         }\r
481         \r
482         vb->Release();\r
483         EndPainting();\r
484 \r
485         \r
486 //      if (!external_driving) {\r
487 //              Sleep(4);//The User can wait for 4 milliseconds to see his changes\r
488 //      }\r
489 }\r
490 \r
491 bool OsdWin::DoLost(){\r
492         Log::getInstance()->log("OSD", Log::WARN, "Direct3D Device Lost! Reobtaining...");\r
493         ResetEvent(event);\r
494         if (external_driving && dsallocator!=NULL) {\r
495                 dsallocator->LostDevice(d3ddevice,d3d); //Propagate the information through DS\r
496         }\r
497         //First we free up all resources\r
498         Video* video = Video::getInstance();\r
499         ((SurfaceWin*)screen)->ReleaseSurface();\r
500         if (d3drtsurf) d3drtsurf->Release();\r
501     d3drtsurf=NULL;\r
502         D3DPRESENT_PARAMETERS d3dparas;\r
503         ZeroMemory(&d3dparas,sizeof(d3dparas));\r
504         d3dparas.BackBufferWidth=BACKBUFFER_WIDTH;\r
505         d3dparas.BackBufferHeight=BACKBUFFER_HEIGHT;\r
506         d3dparas.Windowed=TRUE;\r
507         d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;\r
508 \r
509         if (swapsurf) {swapsurf->Release();swapsurf=NULL;};\r
510         if (swappy) {swappy->Release();swappy=NULL;};\r
511 \r
512         if (d3ddevice->Reset(&d3dparas)!=D3D_OK){\r
513                 return false;\r
514         }\r
515     d3ddevice->GetRenderTarget(0,&d3drtsurf);\r
516         if (d3ddevman) d3ddevman->ResetDevice(d3ddevice,dxvatoken);\r
517         //InitVertexBuffer();\r
518     //Redraw Views, Chris could you add a member function to BoxStack, so that\r
519         // I can cause it to completely redraw the Views?\r
520         // Otherwise the OSD would be distorted after Device Lost\r
521         // FIXME\r
522         \r
523         SetEvent(event);\r
524 \r
525 \r
526         screen->create(video->getScreenWidth(), video->getScreenHeight());\r
527         screen->display();\r
528         \r
529         return true;\r
530 \r
531 }\r
532 LPDIRECT3DDEVICE9 OsdWin::getD3dDev() {\r
533         WaitForSingleObject(event,INFINITE);//We will only return if we are initted\r
534         return d3ddevice;\r
535 }\r
536 \r
537 LPDIRECT3D9 OsdWin::getD3d() {\r
538         WaitForSingleObject(event,INFINITE);//We will only return if we are initted\r
539         return d3d;\r
540 }\r
541 \r
542 void OsdWin::BeginPainting() {//We synchronize calls to d3d between different threads\r
543         WaitForSingleObject(d3dmutex,INFINITE);\r
544         LockDevice();\r
545 }\r
546 \r
547 void OsdWin::EndPainting() {\r
548         UnlockDevice();\r
549         ReleaseMutex(d3dmutex);\r
550 }\r
551 \r
552 void OsdWin::setExternalDriving(DsAllocator* dsall,DWORD width, DWORD height) {\r
553         \r
554         if (swappy)\r
555         {\r
556                 BeginPainting();\r
557                 d3ddevice->StretchRect(swapsurf,NULL,d3drtsurf,NULL,filter_type);\r
558                 LPDIRECT3DSWAPCHAIN9 temp=swappy;\r
559                 LPDIRECT3DSURFACE9 tempsurf=swapsurf;\r
560                 swappy=NULL;\r
561                 swapsurf=NULL;\r
562                 EndPainting();\r
563                 tempsurf->Release();\r
564                 temp->Release();\r
565         }\r
566 \r
567         if (dsall==NULL) {\r
568                 external_driving=false;\r
569                 dsallocator=NULL;       \r
570                 return;\r
571         }\r
572         WaitForSingleObject(event,INFINITE);//We will only return if we are initted\r
573         BeginPainting();\r
574 \r
575         if (width>BACKBUFFER_WIDTH || height>BACKBUFFER_HEIGHT) \r
576         {\r
577                 D3DPRESENT_PARAMETERS d3dparas;\r
578                 ZeroMemory(&d3dparas,sizeof(d3dparas));\r
579                 d3dparas.BackBufferWidth=width;\r
580                 d3dparas.BackBufferHeight=height;\r
581                 d3dparas.Windowed=TRUE;\r
582                 d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;\r
583                 if (d3ddevice->CreateAdditionalSwapChain(&d3dparas,&swappy)!=D3D_OK){\r
584                         Log::getInstance()->log("OSD", Log::WARN, "Could not create Swap Chain!");\r
585                         //return 0;\r
586                 } else {\r
587                         swappy->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&swapsurf);\r
588                 }\r
589         Log::getInstance()->log("OSD", Log::INFO, "Create Additional Swap Chain %d %d!",width,height);\r
590         }\r
591 \r
592         dsallocator=dsall;\r
593         external_driving=true;\r
594         \r
595         EndPainting();\r
596 }\r
597 \r
598 void OsdWin::Blank() {\r
599         WaitForSingleObject(event,INFINITE);\r
600         BeginPainting();\r
601         d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);\r
602         EndPainting();\r
603 }\r