@@ -128,23 +128,10 @@ bool DDuplGrabber::init()
128128 if (!m_createDXGIFactory1Func || !m_D3D11CreateDeviceFunc)
129129 return false ;
130130
131- IDXGIFactory1Ptr factory;
132- HRESULT hr = ((CreateDXGIFactory1Func)m_createDXGIFactory1Func)(__uuidof (IDXGIFactory1), (void **)&factory);
133- if (FAILED (hr))
134- {
135- qCritical (Q_FUNC_INFO " Failed to CreateDXGIFactory1: 0x%X" , hr);
131+ if (!recreateAdapters ()) {
136132 return false ;
137133 }
138134
139- IDXGIAdapter1Ptr adapter;
140- for (int i = 0 ; factory->EnumAdapters1 (i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
141- {
142- DXGI_ADAPTER_DESC1 desc;
143- adapter->GetDesc1 (&desc);
144- DEBUG_LOW_LEVEL << Q_FUNC_INFO << " Found Adapter: " << QString::fromWCharArray (desc.Description );
145- m_adapters.push_back (adapter);
146- }
147-
148135 if (NULL == (m_threadEvent = CreateEventW (NULL , false , false , DDUPL_THREAD_EVENT_NAME))) {
149136 qCritical (Q_FUNC_INFO " unable to create threadEvent" );
150137 return false ;
@@ -164,6 +151,29 @@ bool DDuplGrabber::init()
164151 return true ;
165152}
166153
154+ bool DDuplGrabber::recreateAdapters () {
155+ m_adapters.clear ();
156+
157+ IDXGIFactory1Ptr factory;
158+ HRESULT hr = ((CreateDXGIFactory1Func)m_createDXGIFactory1Func)(__uuidof (IDXGIFactory1), (void **)&factory);
159+ if (FAILED (hr))
160+ {
161+ qCritical (Q_FUNC_INFO " Failed to CreateDXGIFactory1: 0x%X" , hr);
162+ return false ;
163+ }
164+
165+ IDXGIAdapter1Ptr adapter;
166+ for (int i = 0 ; factory->EnumAdapters1 (i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
167+ {
168+ DXGI_ADAPTER_DESC1 desc;
169+ adapter->GetDesc1 (&desc);
170+ DEBUG_LOW_LEVEL << Q_FUNC_INFO << " Found Adapter: " << QString::fromWCharArray (desc.Description );
171+ m_adapters.push_back (adapter);
172+ }
173+
174+ return true ;
175+ }
176+
167177DWORD WINAPI DDuplGrabberThreadProc (LPVOID arg) {
168178 DDuplGrabber* _this = (DDuplGrabber*)arg;
169179 DWORD errorcode;
@@ -320,7 +330,7 @@ bool DDuplGrabber::reallocate(const QList< ScreenInfo > &grabScreens)
320330}
321331
322332// Must be called from DDuplGrabberThreadProc !
323- bool DDuplGrabber::_reallocate (const QList< ScreenInfo > &grabScreens)
333+ bool DDuplGrabber::_reallocate (const QList< ScreenInfo > &grabScreens, bool noRecursion )
324334{
325335 if (m_state == Uninitialized)
326336 {
@@ -397,6 +407,18 @@ bool DDuplGrabber::_reallocate(const QList< ScreenInfo > &grabScreens)
397407 qCritical (Q_FUNC_INFO " Desktop Duplication not available on this system / in this configuration (desktop 0x%X, 0x%X)" , screenInfo.handle , hr);
398408 return false ;
399409 }
410+ else if (hr == DXGI_ERROR_MODE_CHANGE_IN_PROGRESS) {
411+ if (!noRecursion) {
412+ qWarning (Q_FUNC_INFO " DXGI mode change in progress. Recreating adapters" );
413+ if (!recreateAdapters ()) {
414+ return false ;
415+ }
416+ return _reallocate (grabScreens, true );
417+ } else {
418+ qCritical (Q_FUNC_INFO " Failed to reallocate: DXGI mode change in progress (after recreation)" );
419+ return false ;
420+ }
421+ }
400422 else if (FAILED (hr))
401423 {
402424 qCritical (Q_FUNC_INFO " Failed to duplicate output: 0x%X" , hr);
0 commit comments