~ogre-team/testogre/soc09-samples

« back to all changes in this revision

Viewing changes to RenderSystems/Direct3D9/src/OgreD3D9Device.cpp

  • Committer: sinbad
  • Date: 2009-09-27 16:23:50 UTC
  • Revision ID: svn-v4:8631bf8a-c64b-0410-883c-f3eb003322f7:branches/soc09-samples:9126
Merged trunk changes to r9109 into soc09-samples so that we can perform platform tests & refine
Once again a staged commit because of crappy server performance

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
(Object-oriented Graphics Rendering Engine)
5
5
For the latest info, see http://www.ogre3d.org/
6
6
 
7
 
Copyright (c) 2000-2006 Torus Knot Software Ltd
8
 
Also see acknowledgements in Readme.html
9
 
 
10
 
This program is free software; you can redistribute it and/or modify it under
11
 
the terms of the GNU Lesser General Public License as published by the Free Software
12
 
Foundation; either version 2 of the License, or (at your option) any later
13
 
version.
14
 
 
15
 
This program is distributed in the hope that it will be useful, but WITHOUT
16
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
 
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
 
 
19
 
You should have received a copy of the GNU Lesser General Public License along with
20
 
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21
 
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22
 
http://www.gnu.org/copyleft/lesser.txt.
23
 
 
24
 
You may alternatively use this source under the terms of a specific version of
25
 
the OGRE Unrestricted License provided you have obtained such a license from
26
 
Torus Knot Software Ltd.
 
7
Copyright (c) 2000-2009 Torus Knot Software Ltd
 
8
 
 
9
Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
of this software and associated documentation files (the "Software"), to deal
 
11
in the Software without restriction, including without limitation the rights
 
12
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
copies of the Software, and to permit persons to whom the Software is
 
14
furnished to do so, subject to the following conditions:
 
15
 
 
16
The above copyright notice and this permission notice shall be included in
 
17
all copies or substantial portions of the Software.
 
18
 
 
19
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
THE SOFTWARE.
27
26
-----------------------------------------------------------------------------
28
27
*/
29
28
#include "OgreD3D9Device.h"
54
53
                mFocusWindow                            = NULL;
55
54
                mBehaviorFlags                          = behaviorFlags;        
56
55
                mD3D9DeviceCapsValid            = false;
 
56
                mDeviceLost                                     = false;
57
57
                mPresentationParamsCount        = 0;
58
 
                mPresentationParams                     = NULL; 
59
 
                mDeviceInvalidated                      = false;
60
 
                mDeviceValid                            = false;
 
58
                mPresentationParams                     = NULL;
61
59
                memset(&mD3D9DeviceCaps, 0, sizeof(mD3D9DeviceCaps));
62
60
                memset(&mCreationParams, 0, sizeof(mCreationParams));           
63
61
        }
93
91
                {
94
92
                        RenderWindowResources* renderWindowResources = new RenderWindowResources;
95
93
 
96
 
                        memset(renderWindowResources, 0, sizeof(RenderWindowResources));
97
 
                                                
 
94
                        memset(renderWindowResources, 0, sizeof(RenderWindowResources));                                                
98
95
                        renderWindowResources->adapterOrdinalInGroupIndex = 0;                                  
99
 
                        mMapRenderWindowToResoruces[renderWindow] = renderWindowResources;
100
 
 
101
 
                        // invalidate this device.
102
 
                        invalidate();
 
96
                        renderWindowResources->acquired = false;
 
97
                        mMapRenderWindowToResoruces[renderWindow] = renderWindowResources;                      
103
98
                }
104
99
                updateRenderWindowsIndices();
105
100
        }
137
132
        bool D3D9Device::acquire()
138
133
        {       
139
134
                updatePresentationParameters();
 
135
 
 
136
                bool resetDevice = false;
140
137
                        
141
138
                // Create device if need to.
142
139
                if (mpDevice == NULL)
143
140
                {                       
144
141
                        createD3D9Device();
145
142
                }
 
143
 
 
144
                // Case device already exists.
 
145
                else
 
146
                {
 
147
                        RenderWindowToResorucesIterator itPrimary = getRenderWindowIterator(getPrimaryWindow());
 
148
 
 
149
                        if (itPrimary->second->swapChain != NULL)
 
150
                        {
 
151
                                D3DPRESENT_PARAMETERS currentPresentParams;
 
152
                                HRESULT hr;
 
153
 
 
154
                                hr = itPrimary->second->swapChain->GetPresentParameters(&currentPresentParams);
 
155
                                if (FAILED(hr))
 
156
                                {
 
157
                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
 
158
                                                "GetPresentParameters failed", 
 
159
                                                "D3D9RenderWindow::acquire");
 
160
                                }
 
161
                                
 
162
                                // Desired parameters are different then current parameters.
 
163
                                // Possible scenario is that primary window resized and in the mean while another
 
164
                                // window attached to this device.
 
165
                                if (memcmp(&currentPresentParams, &mPresentationParams[0], sizeof(D3DPRESENT_PARAMETERS)) != 0)
 
166
                                {
 
167
                                        resetDevice = true;                                     
 
168
                                }                               
 
169
                        }
 
170
 
 
171
                        // Make sure depth stencil is set to valid surface. It is going to be
 
172
                        // grabbed by the primary window using the GetDepthStencilSurface method.
 
173
                        if (resetDevice == false)
 
174
                        {
 
175
                                mpDevice->SetDepthStencilSurface(itPrimary->second->depthBuffer);
 
176
                        }
146
177
                        
147
 
                // Update resources of each window.
148
 
                RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
149
 
 
150
 
                while (it != mMapRenderWindowToResoruces.end())
151
 
                {
152
 
                        acquireRenderWindowResources(it);
153
 
                        ++it;
154
 
                }
155
 
                
 
178
                }
 
179
 
 
180
                // Reset device will update all render window resources.
 
181
                if (resetDevice)
 
182
                {
 
183
                        reset();
 
184
                }
 
185
 
 
186
                // No need to reset -> just acquire resources.
 
187
                else
 
188
                {
 
189
                        // Update resources of each window.
 
190
                        RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
 
191
 
 
192
                        while (it != mMapRenderWindowToResoruces.end())
 
193
                        {
 
194
                                acquireRenderWindowResources(it);
 
195
                                ++it;
 
196
                        }
 
197
                }
 
198
                                                                        
156
199
                return true;
157
200
        }
158
201
 
193
236
        //--------------------------------------------------------------------- 
194
237
        void D3D9Device::notifyDeviceLost()
195
238
        {
196
 
                // Case this device is already in invalid rendering state.
197
 
                if (mDeviceValid == false)
 
239
                // Case this device is already in lost state.
 
240
                if (mDeviceLost)
198
241
                        return;
199
242
 
200
 
                // Case we just moved from valid state to invalid state.
201
 
                mDeviceValid = false;   
 
243
                // Case we just moved from valid state to lost state.
 
244
                mDeviceLost = true;     
202
245
                
203
246
                D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
204
247
                
264
307
        //---------------------------------------------------------------------
265
308
        void D3D9Device::destroy()
266
309
        {       
 
310
                // Lock access to rendering device.
 
311
                D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
312
                
267
313
                release();
268
314
                
269
315
                RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
286
332
 
287
333
                // Notify the device manager on this instance destruction.      
288
334
                mpDeviceManager->notifyOnDeviceDestroy(this);
 
335
 
 
336
                // UnLock access to rendering device.
 
337
                D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
289
338
        }       
290
339
        
291
340
        //---------------------------------------------------------------------
307
356
        //---------------------------------------------------------------------
308
357
        bool D3D9Device::reset()
309
358
        {
310
 
                updatePresentationParameters();
311
 
 
312
 
                RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
313
 
 
314
 
                while (it != mMapRenderWindowToResoruces.end())
315
 
                {
316
 
                        RenderWindowResources* renderWindowResources = it->second;
317
 
 
318
 
                        releaseRenderWindowResources(renderWindowResources);
319
 
                        ++it;
320
 
                }
321
 
 
322
 
                clearDeviceStreams();
323
 
 
324
 
                // Reset the device
325
359
                HRESULT hr;
326
360
 
327
 
                
328
361
                // Check that device is in valid state for reset.
329
362
                hr = mpDevice->TestCooperativeLevel();
330
363
                if (hr == D3DERR_DEVICELOST ||
333
366
                        return false;
334
367
                }
335
368
 
 
369
                // Lock access to rendering device.
 
370
                D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
371
                                                                
336
372
                D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
337
373
 
 
374
                // Inform all resources that device lost.
 
375
                D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mpDevice);
 
376
 
338
377
 
339
378
                // Release all automatic temporary buffers and free unused
340
379
                // temporary buffers, so we doesn't need to recreate them,
347
386
                // Cleanup depth stencils surfaces.
348
387
                renderSystem->_cleanupDepthStencils(mpDevice);
349
388
 
350
 
 
351
 
 
352
 
                // Inform all resources that device lost.
353
 
                D3D9RenderSystem::getResourceManager()->notifyOnDeviceLost(mpDevice);
354
 
                
 
389
                updatePresentationParameters();
 
390
 
 
391
                RenderWindowToResorucesIterator it = mMapRenderWindowToResoruces.begin();
 
392
 
 
393
                while (it != mMapRenderWindowToResoruces.end())
 
394
                {
 
395
                        RenderWindowResources* renderWindowResources = it->second;
 
396
 
 
397
                        releaseRenderWindowResources(renderWindowResources);
 
398
                        ++it;
 
399
                }
 
400
 
 
401
                clearDeviceStreams();
 
402
 
355
403
 
356
404
                // Reset the device using the presentation parameters.
357
405
                hr = mpDevice->Reset(mPresentationParams);
358
406
        
359
407
                if (hr == D3DERR_DEVICELOST)
360
408
                {
 
409
                        // UnLock access to rendering device.
 
410
                        D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
 
411
 
361
412
                        // Don't continue
362
413
                        return false;
363
414
                }
368
419
                                "D3D9RenderWindow::reset");
369
420
                }
370
421
 
371
 
                mDeviceInvalidated = false;
372
 
                mDeviceValid = true;
 
422
                mDeviceLost = false;
373
423
 
374
424
                // Initialize device states.
375
425
                setupDeviceStates();
381
431
                {
382
432
                        acquireRenderWindowResources(it);
383
433
                        ++it;
384
 
                }                               
 
434
                }               
 
435
 
 
436
                D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
 
437
 
 
438
                mpDeviceManager->setActiveDevice(this);
385
439
 
386
440
                // Inform all resources that device has been reset.
387
441
                D3D9RenderSystem::getResourceManager()->notifyOnDeviceReset(mpDevice);
388
442
 
389
 
        
 
443
                mpDeviceManager->setActiveDevice(pCurActiveDevice);
 
444
                
390
445
                renderSystem->notifyOnDeviceReset(this);
 
446
 
 
447
                // UnLock access to rendering device.
 
448
                D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
391
449
        
392
450
                return true;
393
451
        }
396
454
        bool D3D9Device::isAutoDepthStencil() const
397
455
        {
398
456
                const D3DPRESENT_PARAMETERS& primaryPresentationParams = mPresentationParams[0];
399
 
 
 
457
                
400
458
                // Check if auto depth stencil can be used.
401
459
                for (unsigned int i = 1; i < mPresentationParamsCount; i++)
402
460
                {                       
404
462
                        if(primaryPresentationParams.BackBufferHeight != mPresentationParams[i].BackBufferHeight || 
405
463
                                primaryPresentationParams.BackBufferWidth != mPresentationParams[i].BackBufferWidth     || 
406
464
                                primaryPresentationParams.BackBufferFormat != mPresentationParams[i].BackBufferFormat || 
407
 
                                primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat)
 
465
                                primaryPresentationParams.AutoDepthStencilFormat != mPresentationParams[i].AutoDepthStencilFormat ||
 
466
                                primaryPresentationParams.MultiSampleQuality != mPresentationParams[i].MultiSampleQuality ||
 
467
                                primaryPresentationParams.MultiSampleType != mPresentationParams[i].MultiSampleType)
408
468
                        {
409
469
                                return false;
410
470
                        }
428
488
 
429
489
        //---------------------------------------------------------------------
430
490
        D3DFORMAT D3D9Device::getBackBufferFormat() const
431
 
        {
 
491
        {               
432
492
                if (mPresentationParams == NULL || mPresentationParamsCount == 0)
433
493
                {
434
494
                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, 
447
507
 
448
508
        //---------------------------------------------------------------------
449
509
        void D3D9Device::updatePresentationParameters()
450
 
        {
 
510
        {               
451
511
                // Clear old presentation parameters.
452
512
                SAFE_DELETE_ARRAY(mPresentationParams);
453
513
                mPresentationParamsCount = 0;           
531
591
        //---------------------------------------------------------------------
532
592
        void D3D9Device::clearDeviceStreams()
533
593
        {
 
594
                D3D9RenderSystem* renderSystem = static_cast<D3D9RenderSystem*>(Root::getSingleton().getRenderSystem());
 
595
 
534
596
                // Set all texture units to nothing to release texture surfaces
535
597
                for (DWORD stage = 0; stage < mD3D9DeviceCaps.MaxSimultaneousTextures; ++stage)
536
598
                {
537
 
                        mpDevice->SetTexture(stage, NULL);
 
599
                        DWORD   dwCurValue = D3DTOP_FORCE_DWORD;
 
600
                        HRESULT hr;
 
601
 
 
602
                        hr = mpDevice->SetTexture(stage, NULL);
 
603
                        if( hr != S_OK )
 
604
                        {
 
605
                                String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9";
 
606
                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" );
 
607
                        }
 
608
                
 
609
                        mpDevice->GetTextureStageState(static_cast<DWORD>(stage), D3DTSS_COLOROP, &dwCurValue);
 
610
 
 
611
                        if (dwCurValue != D3DTOP_DISABLE)
 
612
                        {
 
613
                                hr = mpDevice->SetTextureStageState(static_cast<DWORD>(stage), D3DTSS_COLOROP, D3DTOP_DISABLE);
 
614
                                if( hr != S_OK )
 
615
                                {
 
616
                                        String str = "Unable to disable texture '" + StringConverter::toString(stage) + "' in D3D9";
 
617
                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, str, "D3D9Device::clearDeviceStreams" );
 
618
                                }
 
619
                        }                       
 
620
                
 
621
 
 
622
                        // set stage desc. to defaults
 
623
                        renderSystem->mTexStageDesc[stage].pTex = 0;
 
624
                        renderSystem->mTexStageDesc[stage].autoTexCoordType = TEXCALC_NONE;
 
625
                        renderSystem->mTexStageDesc[stage].coordIndex = 0;
 
626
                        renderSystem->mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL;
538
627
                }
539
628
 
540
629
                // Unbind any vertex streams to avoid memory leaks                              
636
725
                }
637
726
 
638
727
                mD3D9DeviceCapsValid = true;
639
 
                mDeviceValid = true;
 
728
                        
 
729
                // Initialize device states.
 
730
                setupDeviceStates();
 
731
 
 
732
                // Lock access to rendering device.
 
733
                D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
734
 
 
735
                D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
 
736
 
 
737
                mpDeviceManager->setActiveDevice(this);
640
738
 
641
739
                // Inform all resources that new device created.
642
740
                D3D9RenderSystem::getResourceManager()->notifyOnDeviceCreate(mpDevice);
643
741
 
644
 
                // Initialize device states.
645
 
                setupDeviceStates();
 
742
                mpDeviceManager->setActiveDevice(pCurActiveDevice);
 
743
 
 
744
                // UnLock access to rendering device.
 
745
                D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
646
746
        }
647
747
 
648
748
        //---------------------------------------------------------------------
650
750
        {
651
751
                if (mpDevice != NULL)
652
752
                {
 
753
                        // Lock access to rendering device.
 
754
                        D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
755
 
 
756
                        D3D9Device* pCurActiveDevice = mpDeviceManager->getActiveDevice();
 
757
 
 
758
                        mpDeviceManager->setActiveDevice(this);
 
759
 
653
760
                        // Inform all resources that device is going to be destroyed.
654
761
                        D3D9RenderSystem::getResourceManager()->notifyOnDeviceDestroy(mpDevice);
655
762
 
656
 
                        clearDeviceStreams();
 
763
                        mpDeviceManager->setActiveDevice(pCurActiveDevice);
 
764
                        
 
765
                        clearDeviceStreams();           
657
766
 
658
767
                        // Release device.
659
768
                        SAFE_RELEASE(mpDevice); 
 
769
                        
 
770
                        // UnLock access to rendering device.
 
771
                        D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
660
772
                }
661
773
        }
662
774
 
666
778
                SAFE_RELEASE(renderWindowResources->backBuffer);
667
779
                SAFE_RELEASE(renderWindowResources->depthBuffer);
668
780
                SAFE_RELEASE(renderWindowResources->swapChain);
 
781
                renderWindowResources->acquired = false;
669
782
        }
670
783
 
671
784
        //---------------------------------------------------------------------
672
 
        void D3D9Device::invalidate()
 
785
        void D3D9Device::invalidate(D3D9RenderWindow* renderWindow)
673
786
        {
674
 
                mDeviceInvalidated = true;
 
787
                RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 
788
 
 
789
                it->second->acquired = false;           
675
790
        }
676
791
 
677
792
        //---------------------------------------------------------------------
678
793
        bool D3D9Device::validate(D3D9RenderWindow* renderWindow)
679
794
        {
 
795
                // Validate that the render window should run on this device.
 
796
                if (false == validateDisplayMonitor(renderWindow))
 
797
                        return false;
 
798
                
680
799
                // Validate that this device created on the correct target focus window handle          
681
800
                validateFocusWindow();          
682
801
                
683
802
                // Validate that the render window dimensions matches to back buffer dimensions.
684
803
                validateBackBufferSize(renderWindow);
685
804
 
686
 
                // Validate that the render window should run on this device.
687
 
                if (false == validateDisplayMonitor(renderWindow))
688
 
                        return false;
689
 
                        
690
805
                // Validate that this device is in valid rendering state.
691
806
                if (false == validateDeviceState(renderWindow))
692
807
                        return false;
697
812
        //---------------------------------------------------------------------
698
813
        void D3D9Device::validateFocusWindow()
699
814
        {
 
815
                // Focus window changed -> device should be re-acquired.
700
816
                if ((msSharedFocusWindow != NULL && mCreationParams.hFocusWindow != msSharedFocusWindow) ||
701
817
                        (msSharedFocusWindow == NULL && mCreationParams.hFocusWindow != getPrimaryWindow()->getWindowHandle()))
702
818
                {
 
819
                        // Lock access to rendering device.
 
820
                        D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
821
 
703
822
                        release();
704
823
                        acquire();
 
824
 
 
825
                        // UnLock access to rendering device.
 
826
                        D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
705
827
                }
706
828
        }
707
829
 
708
830
        //---------------------------------------------------------------------
709
831
        bool D3D9Device::validateDeviceState(D3D9RenderWindow* renderWindow)
710
832
        {
 
833
                RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);             
 
834
                RenderWindowResources* renderWindowResources =  it->second;
711
835
                HRESULT hr;
712
836
 
713
837
                hr = mpDevice->TestCooperativeLevel();  
714
838
 
715
839
                // Case device is not valid for rendering. 
716
 
                if (mDeviceInvalidated || FAILED(hr))
 
840
                if (FAILED(hr))
717
841
                {                                       
718
 
                        RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);             
719
 
                        RenderWindowResources* renderWindowResources =  it->second;
720
 
 
721
842
                        // device lost, and we can't reset
722
843
                        // can't do anything about it here, wait until we get 
723
844
                        // D3DERR_DEVICENOTRESET; rendering calls will silently fail until 
724
845
                        // then (except Present, but we ignore device lost there too)
725
846
                        if (hr == D3DERR_DEVICELOST)
726
 
                        {                       
727
 
                                SAFE_RELEASE(renderWindowResources->backBuffer);
728
 
                                SAFE_RELEASE (renderWindowResources->depthBuffer);
729
 
                                Sleep(50);
730
 
 
731
 
                                mDeviceValid = false;
732
 
 
 
847
                        {                                               
 
848
                                releaseRenderWindowResources(renderWindowResources);
 
849
                                notifyDeviceLost();                                                     
733
850
                                return false;
734
851
                        }
735
852
 
736
853
                        // device lost, and we can reset
737
 
                        else if (hr == D3DERR_DEVICENOTRESET || mDeviceInvalidated)
738
 
                        {                                                                                               
739
 
                                bool deviceRestored = reset();
740
 
 
741
 
                                // Still lost?
742
 
                                if (deviceRestored == false)
743
 
                                {
744
 
                                        // Wait a while
745
 
                                        Sleep(50);
746
 
 
747
 
                                        mDeviceValid = false;
748
 
 
749
 
                                        return false;
750
 
                                }                               
 
854
                        else if (hr == D3DERR_DEVICENOTRESET)
 
855
                        {                                       
 
856
                                bool deviceRestored = reset();
 
857
 
 
858
                                // Device was not restored yet.
 
859
                                if (deviceRestored == false)
 
860
                                {
 
861
                                        // Wait a while
 
862
                                        Sleep(50);                                      
 
863
                                        return false;
 
864
                                }                                                                                                                                                                                               
 
865
                        }                                               
 
866
                }
 
867
 
 
868
                // Render window resources explicitly invalidated. (Resize or window mode switch) 
 
869
                if (renderWindowResources->acquired == false)
 
870
                {
 
871
                        if (getPrimaryWindow() == renderWindow)
 
872
                        {
 
873
                                bool deviceRestored = reset();
 
874
 
 
875
                                // Device was not restored yet.
 
876
                                if (deviceRestored == false)
 
877
                                {
 
878
                                        // Wait a while
 
879
                                        Sleep(50);                                      
 
880
                                        return false;
 
881
                                }       
 
882
                        }
 
883
                        else
 
884
                        {
 
885
                                acquire(renderWindow);
751
886
                        }
752
887
                }
753
888
 
772
907
                        if (renderWindow->getHeight() > 0)
773
908
                                renderWindowResources->presentParameters.BackBufferHeight = renderWindow->getHeight();
774
909
 
775
 
                        invalidate();
 
910
                        invalidate(renderWindow);
776
911
                }                               
777
912
        }
778
913
 
798
933
 
799
934
                // Case this window changed monitor.
800
935
                if (hRenderWindowMonitor != mMonitor)
801
 
                {                       
 
936
                {       
 
937
                        // Lock access to rendering device.
 
938
                        D3D9RenderSystem::getResourceManager()->lockDeviceAccess();
 
939
 
802
940
                        mpDeviceManager->linkRenderWindow(renderWindow);
 
941
 
 
942
                        // UnLock access to rendering device.
 
943
                        D3D9RenderSystem::getResourceManager()->unlockDeviceAccess();
 
944
 
803
945
                        return false;
804
946
                }
805
947
 
808
950
 
809
951
        //---------------------------------------------------------------------
810
952
        void D3D9Device::present(D3D9RenderWindow* renderWindow)
811
 
        {
812
 
                if (mDeviceValid == false || isDeviceLost())            
 
953
        {               
 
954
                RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
 
955
                RenderWindowResources*  renderWindowResources = it->second;                             
 
956
 
 
957
 
 
958
                // Skip present while current device state is invalid.
 
959
                if (mDeviceLost || 
 
960
                        renderWindowResources->acquired == false || 
 
961
                        isDeviceLost())         
813
962
                        return;         
814
 
                
815
 
                RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
816
 
                RenderWindowResources*  renderWindowResources = it->second;                                     
 
963
 
 
964
 
817
965
                HRESULT hr;
818
966
 
819
967
                if (isMultihead())
831
979
                }
832
980
 
833
981
 
834
 
                if( D3DERR_DEVICELOST == hr || mDeviceInvalidated)
 
982
                if( D3DERR_DEVICELOST == hr)
835
983
                {
836
 
                        SAFE_RELEASE(renderWindowResources->depthBuffer);
837
 
                        SAFE_RELEASE(renderWindowResources->backBuffer);
838
 
                        SAFE_RELEASE(renderWindowResources->swapChain);
839
 
 
 
984
                        releaseRenderWindowResources(renderWindowResources);
840
985
                        notifyDeviceLost();
841
986
                }
842
987
                else if( FAILED(hr) )
857
1002
                
858
1003
                releaseRenderWindowResources(renderWindowResources);
859
1004
 
860
 
                // No need to create resources for invisible windows.
861
 
                if (renderWindow->getWidth() == 0 || 
862
 
                        renderWindow->getHeight() == 0)
863
 
                {
864
 
                        return;
865
 
                }
866
 
 
867
1005
                // Create additional swap chain
868
1006
                if (isSwapChainWindow(renderWindow) && !isMultihead())
869
1007
                {
917
1055
                        }
918
1056
                        else
919
1057
                        {
 
1058
                                uint targetWidth  = renderWindow->getWidth();
 
1059
                                uint targetHeight = renderWindow->getHeight();
 
1060
 
 
1061
                                if (targetWidth == 0)
 
1062
                                        targetWidth = 1;
 
1063
 
 
1064
                                if (targetHeight == 0)
 
1065
                                        targetHeight = 1;
 
1066
 
920
1067
                                HRESULT hr = mpDevice->CreateDepthStencilSurface(
921
 
                                        renderWindow->getWidth(), renderWindow->getHeight(),
 
1068
                                        targetWidth, targetHeight,
922
1069
                                        renderWindowResources->presentParameters.AutoDepthStencilFormat,
923
1070
                                        renderWindowResources->presentParameters.MultiSampleType,
924
1071
                                        renderWindowResources->presentParameters.MultiSampleQuality, 
938
1085
                                        mpDevice->SetDepthStencilSurface(renderWindowResources->depthBuffer);
939
1086
                                }
940
1087
                        }
941
 
                }               
 
1088
                }
 
1089
 
 
1090
                renderWindowResources->acquired = true; 
942
1091
        }
943
1092
 
944
1093
        //---------------------------------------------------------------------
1287
1436
 
1288
1437
 
1289
1438
        }
1290
 
 
1291
 
 
1292
1439
}