Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Recover full screen device, procedurally from other process.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 CrescentFresh   Members   -  Reputation: 141

Like
0Likes
Like

Posted 26 February 2013 - 03:38 PM

I have a multi-monitor, multi-full screen dx9 device setup that need to work hand-in-hand with another process. This other process can make the dx9 app minimize so it can take the active foreground window... and when it's done, it signals the dx9 app (via local telnet) to recover itself and become active again. 

 

My finished product needs to accomplish this procedurally, as in I cannot use any input devices to either alt-tab or click the dx9 app in taskbar with mouse. When I try to do it procedurally, the different recovery code I've tried has managed to create two different outcomes.

 

  • The dx9 app does maximize, and recovers... but when I click the screen, if any windows are behind the game it immediately loses focus, as if the dx9 app is only rendering overtop the other windows but not actually there.
  • Or, the game comes back up, but shows only a white screen and the device is reports 'D3DERR_DEVICELOST', and never makes it to 'D3DERR_DEVICENOTRESET'... but if you actually click the screen it receives the input properly and plays the game.

 

I'm almost certain I'm freeing all the dx resources that I need to be, and that it's got to be some sort of focus issue.

 

I'm also aware that AllowSetForegroundWindow(), needs to present in the other process to be able to give up focus, and it is being called.

 

The dx9 app is a fairly large engine, so posting the code is a concise matter will be difficult, below is the general idea of things:

 

 All code is from dx9 app:

//
// A message comes in whether to minimize/maximize
if(m_bMinimize)
{
    LOG("minimize!");
    ShowWindow(deviceRef.GetWnd(), SW_MINIMIZE);//SW_HIDE);
}
else
{
    LOG("MAXIMIZE!");
    ShowWindow(deviceRef.GetWnd(), SW_SHOWNORMAL);
    SetForegroundWindow(deviceRef.GetWnd());
}

 

The below function CheckDevice() is called at the beginning of the render thread loop. It returns whether or not the device is okay.

// Returns true if it's okay to render
bool LtGRenderThread::CheckDevice()
{
    if(m_bLostDevice)
    {
        int j = 0;
	for(j = 0; j < m_iNumDevices; j++) //for(int j = m_iNumDevices-1; j >= 0; --j)
	{
	    HRESULT result = m_pDevices[j].m_pD3DDevice->TestCooperativeLevel();
	    if(FAILED(result))
	    {
	        if(D3DERR_DEVICENOTRESET == result)
		{
		    HRESULT result2 = m_pDevices[j].m_pD3DDevice->Reset(&m_pDevices[j].m_tPresentParams);

		    if(FAILED(result2))
		    {
			LOGF("Device %i: reset failed: %u", LOG_NORMAL, j, result2);			                                              }
		    else
		    {
			LOGF("Device %i: Reset successful...", LOG_NORMAL, j);
		    }
		}
                    break;
		
            }
	    else
	        LOGF("DEVICE %i has recovered!", LOG_TODO, j);
	}

	if(j == m_iNumDevices)
	{
	    LOG("Reloading all vRAM...");

	    for(j = 0; j < m_iNumDevices; j++)
	    {
	        m_pDevices[j].OnResetDevice();
	    }
	
	    // Tell Update thread that we need to reset the device
	    m_MsgManRef.MarkFlag(MSGMAN_ResetDevice);

	    m_bLostDevice = false;
        }
    }
    else
    {
	for(int j = 0; j < m_iNumDevices; j++)
	{
            HRESULT result = m_pDevices[j].m_pD3DDevice->TestCooperativeLevel();
	    if(FAILED(result) || m_pDevices[j].IsForceReset())
	    {
		LOG("A device has been lost! (Or forced to reset)");

		m_bLostDevice = true;
				
		// Clear out all DX resources
		for(int i = 0; i < m_iNumDevices; i++)
		    m_pDevices[i].OnLostDevice();

		m_MsgManRef.MarkFlag(MSGMAN_LostDevice);

	        break;
	    }
        }
    }
	
    return !m_bLostDevice;
}

 

 

I'm pretty sure no one is going to respond to this mess. But I'll just try to be hopeful that someone has some experience in doing something similar to this. Thanks for reading.


Can I play with madness?


Sponsor:

#2 Seabolt   Members   -  Reputation: 633

Like
1Likes
Like

Posted 26 February 2013 - 03:43 PM

Are you releasing all of your device resources, including textures, vertex buffers, essentially anything created by D3D? I'm only seeing the device currently, and it can't reset properly until all resources have been released.


Perception is when one imagination clashes with another

#3 CrescentFresh   Members   -  Reputation: 141

Like
0Likes
Like

Posted 26 February 2013 - 04:13 PM

Are you releasing all of your device resources, including textures, vertex buffers, essentially anything created by D3D? I'm only seeing the device currently, and it can't reset properly until all resources have been released.

Yeah, the m_pDevices[j].OnLostDevice(); is handling all of that within. I am able to have it recover properly when I use the mouse and keyboard to select the minimized application. That's why I'm pretty certain it's some sort of focus issue.

 

void LtGDevice::OnLostDevice()
{
	m_pD3DSprite->OnLostDevice();

	SAFE_RELEASE(m_pBackBuffer);
	SAFE_RELEASE(m_swapChain);

	// Kill all the tasks... they will be repopulated upon DeviceReset
	for(unsigned int i = 0; i < m_vScheduledTasks.size(); i++)
	{
		SAFE_DELETE(m_vScheduledTasks[i]);
	}
	m_vScheduledTasks.clear();

	for(map<int, LPDIRECT3DTEXTURE9>::iterator iter = m_mapTextures.begin(); iter != m_mapTextures.end(); ++iter)
	{
		SAFE_RELEASE(iter->second);
	}

	for(map<FONT_HANDLE, LPD3DXFONT>::iterator iter = m_mapFonts.begin(); iter != m_mapFonts.end(); ++iter)
	{
		iter->second->OnLostDevice();
	}

	m_bForceReset = false;
}

Edited by CrescentFresh, 26 February 2013 - 04:15 PM.

Can I play with madness?


#4 Seabolt   Members   -  Reputation: 633

Like
0Likes
Like

Posted 26 February 2013 - 04:27 PM

Hmm... this is a shot in the dark, but with your first case, is it possible you're using DirectInput and are not resetting it? I believe there was some shenanigans with the HWND when the device is lost, but honestly, I haven't had to deal with OnLost and OnReset in two years or so.


Perception is when one imagination clashes with another

#5 CrescentFresh   Members   -  Reputation: 141

Like
0Likes
Like

Posted 27 February 2013 - 08:33 AM

I'm handling all the input through the traditional WndProc message callbacks. I have a feeling I might be incorrectly using AllowSetForegroundWindow in the process that is supposed to give up focus when its done to the dx9 app, and that is what's causing the weird "rending on top, but input falls through to the windows behind".

 

Thanks, for helping tho!


Can I play with madness?





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS