From 1c8b8d3a3787b064ff8fee96f49880c999c9f588 Mon Sep 17 00:00:00 2001 From: Anton Fedchin Date: Wed, 25 Jan 2017 18:45:54 +0300 Subject: [win32/dx] re-factor ID3DResource to make possible tell to a resource that device is not valid anymore. --- xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h | 2 +- .../VideoRenderers/HwDecRender/DXVAHD.h | 2 +- .../VideoPlayer/VideoRenderers/RenderCapture.cpp | 2 +- .../VideoPlayer/VideoRenderers/RenderCapture.h | 2 +- xbmc/guilib/D3DResource.cpp | 29 +++++++++++----------- xbmc/guilib/D3DResource.h | 25 +++++++++---------- xbmc/guilib/GUIFontTTFDX.cpp | 2 +- xbmc/guilib/GUIFontTTFDX.h | 18 +++++++------- xbmc/rendering/dx/RenderSystemDX.cpp | 9 ++++++- 9 files changed, 48 insertions(+), 43 deletions(-) diff --git a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h index 2170515919..da28645db0 100644 --- a/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h +++ b/xbmc/cores/VideoPlayer/DVDCodecs/Video/DXVA.h @@ -147,7 +147,7 @@ protected: // ID3DResource overrides void OnCreateDevice() override {} - void OnDestroyDevice() override { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } + void OnDestroyDevice(bool fatal) override { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } void OnLostDevice() override { CSingleLock lock(m_section); m_state = DXVA_LOST; m_event.Reset(); } void OnResetDevice() override { CSingleLock lock(m_section); m_state = DXVA_RESET; m_event.Set(); } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h index 60be0850d3..4a3dafd458 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/HwDecRender/DXVAHD.h @@ -64,7 +64,7 @@ public: // ID3DResource overrides void OnCreateDevice() override {} - void OnDestroyDevice() override { CSingleLock lock(m_section); UnInit(); } + void OnDestroyDevice(bool fatal) override { CSingleLock lock(m_section); UnInit(); } void OnLostDevice() override { CSingleLock lock(m_section); UnInit(); } void OnResetDevice() override { CSingleLock lock(m_section); Close(); } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp index a50e9b170e..9bf031095f 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.cpp @@ -507,7 +507,7 @@ void CRenderCaptureDX::OnLostDevice() SetState(CAPTURESTATE_FAILED); } -void CRenderCaptureDX::OnDestroyDevice() +void CRenderCaptureDX::OnDestroyDevice(bool fatal) { CleanupDX(); SetState(CAPTURESTATE_FAILED); diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h index 640461f353..9f9565f988 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/RenderCapture.h @@ -210,7 +210,7 @@ class CRenderCaptureDX : public CRenderCaptureBase, public ID3DResource void EndRender(); void ReadOut(); - virtual void OnDestroyDevice(); + virtual void OnDestroyDevice(bool fatal); virtual void OnLostDevice(); virtual void OnCreateDevice() {}; diff --git a/xbmc/guilib/D3DResource.cpp b/xbmc/guilib/D3DResource.cpp index a5aaab7245..8a8d5857de 100644 --- a/xbmc/guilib/D3DResource.cpp +++ b/xbmc/guilib/D3DResource.cpp @@ -383,18 +383,15 @@ void CD3DTexture::SaveTexture() } } -void CD3DTexture::OnDestroyDevice() +void CD3DTexture::OnDestroyDevice(bool fatal) { - SaveTexture(); + if (!fatal) + SaveTexture(); SAFE_RELEASE(m_texture); SAFE_RELEASE(m_textureView); SAFE_RELEASE(m_renderTarget); } -void CD3DTexture::OnLostDevice() -{ -} - void CD3DTexture::RestoreTexture() { // yay, we're back - make a new copy of the texture @@ -416,10 +413,6 @@ void CD3DTexture::OnCreateDevice() RestoreTexture(); } -void CD3DTexture::OnResetDevice() -{ -} - unsigned int CD3DTexture::GetMemoryUsage(unsigned int pitch) const { switch (m_format) @@ -533,10 +526,10 @@ bool CD3DEffect::Create(const std::string &effectString, DefinesMap* defines) void CD3DEffect::Release() { g_Windowing.Unregister(this); - OnDestroyDevice(); + OnDestroyDevice(false); } -void CD3DEffect::OnDestroyDevice() +void CD3DEffect::OnDestroyDevice(bool fatal) { SAFE_RELEASE(m_effect); m_techniquie = nullptr; @@ -790,8 +783,14 @@ bool CD3DBuffer::Unmap() return false; } -void CD3DBuffer::OnDestroyDevice() +void CD3DBuffer::OnDestroyDevice(bool fatal) { + if (fatal) + { + SAFE_RELEASE(m_buffer); + return; + } + ID3D11Device* pDevice = g_Windowing.Get3D11Device(); ID3D11DeviceContext* pContext = g_Windowing.GetImmediateContext(); @@ -1005,7 +1004,7 @@ void CD3DVertexShader::OnCreateDevice() m_inited = CreateInternal(); } -void CD3DVertexShader::OnDestroyDevice() +void CD3DVertexShader::OnDestroyDevice(bool fatal) { ReleaseShader(); } @@ -1130,7 +1129,7 @@ void CD3DPixelShader::OnCreateDevice() m_inited = CreateInternal(); } -void CD3DPixelShader::OnDestroyDevice() +void CD3DPixelShader::OnDestroyDevice(bool fatal) { ReleaseShader(); } diff --git a/xbmc/guilib/D3DResource.h b/xbmc/guilib/D3DResource.h index cf0a0b98bf..8a51efd9b4 100644 --- a/xbmc/guilib/D3DResource.h +++ b/xbmc/guilib/D3DResource.h @@ -58,10 +58,11 @@ class ID3DResource public: virtual ~ID3DResource() {}; - virtual void OnDestroyDevice()=0; + virtual void OnDestroyDevice(bool fatal)=0; virtual void OnCreateDevice()=0; virtual void OnLostDevice() {}; virtual void OnResetDevice() {}; + virtual void OnDestroyDevice() { OnDestroyDevice(false); } }; class CD3DHelper @@ -137,10 +138,8 @@ public: static void DrawQuad(const CRect &coords, color_t color, unsigned numViews, ID3D11ShaderResourceView **view, const CRect *texCoords, SHADER_METHOD options = SHADER_METHOD_RENDER_TEXTURE_BLEND); - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); - virtual void OnLostDevice(); - virtual void OnResetDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; private: unsigned int GetMemoryUsage(unsigned int pitch) const; @@ -191,8 +190,8 @@ public: ID3DX11Effect *Get() const { return m_effect; }; - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; private: bool CreateEffect(); @@ -218,8 +217,8 @@ public: DXGI_FORMAT GetFormat() { return m_format; } ID3D11Buffer* Get() const { return m_buffer; }; - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; private: bool CreateBuffer(const void *pData); D3D11_BIND_FLAG m_type; @@ -247,8 +246,8 @@ public: void Release(); bool IsInited() { return m_inited; } - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; private: bool CreateInternal(); @@ -275,8 +274,8 @@ public: void Release(); bool IsInited() { return m_inited; } - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; private: bool CreateInternal(); diff --git a/xbmc/guilib/GUIFontTTFDX.cpp b/xbmc/guilib/GUIFontTTFDX.cpp index f87abf74f0..8d2b028b26 100644 --- a/xbmc/guilib/GUIFontTTFDX.cpp +++ b/xbmc/guilib/GUIFontTTFDX.cpp @@ -348,7 +348,7 @@ void CGUIFontTTFDX::CreateStaticIndexBuffer(void) bool CGUIFontTTFDX::m_staticIndexBufferCreated = false; ID3D11Buffer* CGUIFontTTFDX::m_staticIndexBuffer = nullptr; -void CGUIFontTTFDX::OnDestroyDevice(void) +void CGUIFontTTFDX::OnDestroyDevice(bool fatal) { SAFE_RELEASE(m_staticIndexBuffer); m_staticIndexBufferCreated = false; diff --git a/xbmc/guilib/GUIFontTTFDX.h b/xbmc/guilib/GUIFontTTFDX.h index c66ce34273..4b906ae90c 100644 --- a/xbmc/guilib/GUIFontTTFDX.h +++ b/xbmc/guilib/GUIFontTTFDX.h @@ -44,21 +44,21 @@ public: CGUIFontTTFDX(const std::string& strFileName); virtual ~CGUIFontTTFDX(void); - virtual bool FirstBegin(); - virtual void LastEnd(); - virtual CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const; - virtual void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const; + bool FirstBegin() override; + void LastEnd() override; + CVertexBuffer CreateVertexBuffer(const std::vector &vertices) const override; + void DestroyVertexBuffer(CVertexBuffer &bufferHandle) const override; - virtual void OnDestroyDevice(); - virtual void OnCreateDevice(); + void OnDestroyDevice(bool fatal) override; + void OnCreateDevice() override; static void CreateStaticIndexBuffer(void); static void DestroyStaticIndexBuffer(void); protected: - virtual CBaseTexture* ReallocTexture(unsigned int& newHeight); - virtual bool CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); - virtual void DeleteHardwareTexture(); + CBaseTexture* ReallocTexture(unsigned int& newHeight) override; + bool CopyCharToTexture(FT_BitmapGlyph bitGlyph, unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) override; + void DeleteHardwareTexture() override; private: bool UpdateDynamicVertexBuffer(const SVertex* pSysMem, unsigned int count); diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp index 21c571db1d..bf072bd8d5 100644 --- a/xbmc/rendering/dx/RenderSystemDX.cpp +++ b/xbmc/rendering/dx/RenderSystemDX.cpp @@ -418,7 +418,14 @@ void CRenderSystemDX::DeleteDevice() // tell any shared resources for (std::vector::iterator i = m_resources.begin(); i != m_resources.end(); ++i) - (*i)->OnDestroyDevice(); + { + // the most of resources like textures and buffers try to + // receive and save their status from current device. + // m_nDeviceStatus contains the last device status and + // DXGI_ERROR_DEVICE_REMOVED means that we have no possibility + // to use the device anymore, tell all resouces about this. + (*i)->OnDestroyDevice(DXGI_ERROR_DEVICE_REMOVED == m_nDeviceStatus); + } if (m_pSwapChain) m_pSwapChain->SetFullscreenState(false, nullptr); -- cgit v1.2.3 From 489e82ad086c683d8e814dc8401dd36887d629ab Mon Sep 17 00:00:00 2001 From: Anton Fedchin Date: Wed, 25 Jan 2017 18:47:59 +0300 Subject: [VideoPlayer] OverlayRendererDX: "mark" overlay as invalid on destroying device in case of fatal error. --- .../VideoRenderers/OverlayRendererDX.cpp | 28 +++++++++++++++++++++- .../VideoPlayer/VideoRenderers/OverlayRendererDX.h | 6 +++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp index d5e36af13d..1d64eb4110 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.cpp @@ -151,12 +151,14 @@ COverlayQuadsDX::COverlayQuadsDX(ASS_Image* images, int width, int height) CLog::Log(LOGERROR, "%s - failed to create vertex buffer", __FUNCTION__); m_texture.Release(); } - + else + g_Windowing.Register(this); delete[] vt; } COverlayQuadsDX::~COverlayQuadsDX() { + g_Windowing.Unregister(this); } void COverlayQuadsDX::Render(SRenderState &state) @@ -204,8 +206,18 @@ void COverlayQuadsDX::Render(SRenderState &state) pGUIShader->RestoreBuffers(); } +void COverlayQuadsDX::OnDestroyDevice(bool fatal) +{ + // fatal means that we have no valid buffer anymore + // resetting m_count will cause no rendering + if (fatal) + m_count = 0; +} + + COverlayImageDX::~COverlayImageDX() { + g_Windowing.Unregister(this); } COverlayImageDX::COverlayImageDX(CDVDOverlayImage* o) @@ -271,6 +283,7 @@ COverlayImageDX::COverlayImageDX(CDVDOverlayImage* o) m_width = (float)o->width; m_height = (float)o->height; } + g_Windowing.Register(this); } COverlayImageDX::COverlayImageDX(CDVDOverlaySpu* o) @@ -292,6 +305,8 @@ COverlayImageDX::COverlayImageDX(CDVDOverlaySpu* o) m_y = (float)(min_y + o->y); m_width = (float)(max_x - min_x); m_height = (float)(max_y - min_y); + + g_Windowing.Register(this); } void COverlayImageDX::Load(uint32_t* rgba, int width, int height, int stride) @@ -329,6 +344,9 @@ void COverlayImageDX::Load(uint32_t* rgba, int width, int height, int stride) void COverlayImageDX::Render(SRenderState &state) { + if (m_type == TYPE_NONE) + return; + ID3D11DeviceContext* pContext = g_Windowing.Get3D11Context(); CGUIShaderDX* pGUIShader = g_Windowing.GetGUIShader(); @@ -369,4 +387,12 @@ void COverlayImageDX::Render(SRenderState &state) pGUIShader->RestoreBuffers(); } +void OVERLAY::COverlayImageDX::OnDestroyDevice(bool fatal) +{ + // fatal means that we have no valid texture and buffer anymore + // resetting m_type will cause no rendering + if (fatal) + m_type = TYPE_NONE; +} + #endif diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h index f5fd62bf3c..23e40839bd 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/OverlayRendererDX.h @@ -35,12 +35,15 @@ namespace OVERLAY { class COverlayQuadsDX : public COverlay + , public ID3DResource { public: COverlayQuadsDX(ASS_Image* images, int width, int height); virtual ~COverlayQuadsDX(); void Render(SRenderState& state); + void OnCreateDevice() override {} + void OnDestroyDevice(bool fatal) override; int m_count; DWORD m_fvf; @@ -50,6 +53,7 @@ namespace OVERLAY { class COverlayImageDX : public COverlay + , public ID3DResource { public: COverlayImageDX(CDVDOverlayImage* o); @@ -58,6 +62,8 @@ namespace OVERLAY { void Load(uint32_t* rgba, int width, int height, int stride); void Render(SRenderState& state); + void OnCreateDevice() override {} + void OnDestroyDevice(bool fatal) override; DWORD m_fvf; CD3DTexture m_texture; -- cgit v1.2.3 From 402862f24eb91ce14099961473b410b883782847 Mon Sep 17 00:00:00 2001 From: Anton Fedchin Date: Mon, 16 Jan 2017 16:47:54 +0300 Subject: [RenderSystemDX] reload skin on a driver failure. --- xbmc/rendering/dx/RenderSystemDX.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xbmc/rendering/dx/RenderSystemDX.cpp b/xbmc/rendering/dx/RenderSystemDX.cpp index bf072bd8d5..f83d21298d 100644 --- a/xbmc/rendering/dx/RenderSystemDX.cpp +++ b/xbmc/rendering/dx/RenderSystemDX.cpp @@ -29,6 +29,7 @@ #include "guilib/GUIShaderDX.h" #include "guilib/GUITextureD3D.h" #include "guilib/GUIWindowManager.h" +#include "messaging/ApplicationMessenger.h" #include "settings/AdvancedSettings.h" #include "threads/SingleLock.h" #include "utils/MathUtils.h" @@ -1291,6 +1292,8 @@ bool CRenderSystemDX::BeginRender() { OnDeviceLost(); OnDeviceReset(); + if (m_bRenderCreated) + KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, "ReloadSkin"); } return false; } -- cgit v1.2.3