1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 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.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreD3D11VideoModeList.h"
29 #include "OgreException.h"
30 #include "OgreD3D11Driver.h"
31 #include "OgreD3D11VideoMode.h"
32 
33 namespace Ogre
34 {
35     //---------------------------------------------------------------------
D3D11VideoModeList(IDXGIAdapterN * pAdapter)36     D3D11VideoModeList::D3D11VideoModeList(IDXGIAdapterN* pAdapter)
37     {
38         if( NULL == pAdapter)
39             OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "pAdapter parameter is NULL", "D3D11VideoModeList::D3D11VideoModeList" );
40 
41         for( int iOutput = 0; ; ++iOutput )
42         {
43             //AIZTODO: one output for a single monitor ,to be handled for mulimon
44             ComPtr<IDXGIOutput> pOutput;
45             HRESULT hr = pAdapter->EnumOutputs( iOutput, pOutput.ReleaseAndGetAddressOf());
46             if( DXGI_ERROR_NOT_FOUND == hr )
47                 break;
48             else if (FAILED(hr))
49             {
50                 break;   //Something bad happened.
51             }
52             else //Success!
53             {
54 				DXGI_OUTPUT_DESC OutputDesc;
55 				pOutput->GetDesc(&OutputDesc);
56 
57 				UINT NumModes = 0;
58 				hr = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,
59 					0,
60 					&NumModes,
61 					NULL);
62 
63 				// If working over a terminal session, for example using the Simulator for deployment/development, display modes cannot be obtained.
64 				if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE)
65 				{
66 					DXGI_MODE_DESC fullScreenMode;
67 					fullScreenMode.Width = OutputDesc.DesktopCoordinates.right - OutputDesc.DesktopCoordinates.left;
68 					fullScreenMode.Height = OutputDesc.DesktopCoordinates.bottom - OutputDesc.DesktopCoordinates.top;
69 					fullScreenMode.RefreshRate.Numerator = 60;
70 					fullScreenMode.RefreshRate.Denominator = 1;
71 					fullScreenMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
72 					fullScreenMode.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
73 					fullScreenMode.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
74 
75 					mModeList.push_back(D3D11VideoMode(OutputDesc, fullScreenMode));
76 				}
77 				else if (hr == S_OK)
78 				{
79 					if (NumModes > 0)
80 					{
81 						// Create an array to store Display Mode information
82 						std::vector<DXGI_MODE_DESC> modes;
83 						modes.resize(NumModes);
84 
85 						// Populate our array with information
86 						hr = pOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,
87 							0,
88 							&NumModes,
89 							modes.data());
90 
91 						for (UINT m = 0; m < NumModes; m++)
92 						{
93 							DXGI_MODE_DESC displayMode = modes[m];
94 							// Filter out low-resolutions
95 							if (displayMode.Width < 640 || displayMode.Height < 400)
96 								continue;
97 
98 							// Check to see if it is already in the list (to filter out refresh rates)
99 							BOOL found = FALSE;
100 							std::vector<D3D11VideoMode>::iterator it;
101 							for (it = mModeList.begin(); it != mModeList.end(); it++)
102 							{
103 								DXGI_OUTPUT_DESC oldOutput = it->getDisplayMode();
104 								DXGI_MODE_DESC oldDisp = it->getModeDesc();
105 								if (//oldOutput.Monitor==OutputDesc.Monitor &&
106 									oldDisp.Width == displayMode.Width &&
107 									oldDisp.Height == displayMode.Height// &&
108 									//oldDisp.Format == displayMode.Format
109 									)
110 								{
111 									// Check refresh rate and favour higher if poss
112 									//if (oldDisp.RefreshRate < displayMode.RefreshRate)
113 									//  it->increaseRefreshRate(displayMode.RefreshRate);
114 									found = TRUE;
115 									break;
116 								}
117 							}
118 
119 							if (!found)
120 								mModeList.push_back(D3D11VideoMode(OutputDesc, displayMode));
121 
122 						}
123 					}
124 				}
125             }
126         }
127     }
128     //---------------------------------------------------------------------
count()129     size_t D3D11VideoModeList::count()
130     {
131         return mModeList.size();
132     }
133     //---------------------------------------------------------------------
item(size_t index)134     D3D11VideoMode* D3D11VideoModeList::item( size_t index )
135     {
136         std::vector<D3D11VideoMode>::iterator p = mModeList.begin();
137 
138         return &p[index];
139     }
140     //---------------------------------------------------------------------
item(const String & name)141     D3D11VideoMode* D3D11VideoModeList::item( const String &name )
142     {
143         std::vector<D3D11VideoMode>::iterator it = mModeList.begin();
144         if (it == mModeList.end())
145             return NULL;
146 
147         for (;it != mModeList.end(); ++it)
148         {
149             if (it->getDescription() == name)
150                 return &(*it);
151         }
152 
153         return NULL;
154     }
155     //---------------------------------------------------------------------
156 }
157