Add SwapChain::recreate for dealing with certain cases of lost devices.

See https://code.google.com/p/angleproject/source/detail?r=1993 TRAC #22826 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@2036 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent df304e7a
......@@ -18,6 +18,7 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/renderer/SwapChain.h"
#include "libEGL/main.h"
#include "libEGL/Surface.h"
......@@ -441,6 +442,14 @@ void Display::notifyDeviceLost()
egl::error(EGL_CONTEXT_LOST);
}
void Display::recreateSwapChains()
{
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
(*surface)->getSwapChain()->recreate();
}
}
bool Display::isInitialized() const
{
return mRenderer != NULL && mConfigSet.size() > 0;
......
......@@ -55,7 +55,9 @@ class Display
rx::Renderer *getRenderer() { return mRenderer; };
// exported methods must be virtual
virtual void notifyDeviceLost();
virtual void recreateSwapChains();
const char *getExtensionString() const;
......
......@@ -2050,6 +2050,9 @@ bool Renderer9::testDeviceLost(bool notify)
D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
mDeviceEx->Reset(&presentParameters);
// Existing swap chains sometimes crash on the next present after a reset.
mDisplay->recreateSwapChains();
// Reset will not always cause the device loss to be reported so issue a dummy present.
mDeviceEx->Present(NULL, NULL, NULL, NULL);
......
......@@ -28,6 +28,7 @@ class SwapChain
virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
virtual void recreate() = 0;
virtual HANDLE getShareHandle() {return mShareHandle;};
......
......@@ -759,4 +759,9 @@ SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
return static_cast<rx::SwapChain11*>(swapChain);
}
void SwapChain11::recreate()
{
// possibly should use this method instead of reset
}
}
......@@ -26,6 +26,7 @@ class SwapChain11 : public SwapChain
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual ID3D11Texture2D *getOffscreenTexture();
virtual ID3D11RenderTargetView *getRenderTarget();
......
......@@ -399,4 +399,36 @@ SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
return static_cast<rx::SwapChain9*>(swapChain);
}
void SwapChain9::recreate()
{
if (!mSwapChain)
{
return;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
if (device == NULL)
{
return;
}
D3DPRESENT_PARAMETERS presentParameters;
HRESULT result = mSwapChain->GetPresentParameters(&presentParameters);
ASSERT(SUCCEEDED(result));
IDirect3DSwapChain9* newSwapChain = NULL;
result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain);
if (FAILED(result))
{
return;
}
mSwapChain->Release();
mSwapChain = newSwapChain;
mBackBuffer->Release();
result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
ASSERT(SUCCEEDED(result));
}
}
......@@ -26,6 +26,7 @@ class SwapChain9 : public SwapChain
EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
virtual void recreate();
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment