mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-09-20 22:21:57 +00:00
Fix synchronization issues between render and overlay update threads in DXVA2
This commit is contained in:
parent
8031ed7fe1
commit
6a54fb649c
2 changed files with 62 additions and 32 deletions
|
@ -32,6 +32,7 @@ DXVA2Renderer::DXVA2Renderer() :
|
||||||
m_Decoder(nullptr),
|
m_Decoder(nullptr),
|
||||||
m_SurfacesUsed(0),
|
m_SurfacesUsed(0),
|
||||||
m_Pool(nullptr),
|
m_Pool(nullptr),
|
||||||
|
m_OverlayLock(0),
|
||||||
m_Device(nullptr),
|
m_Device(nullptr),
|
||||||
m_RenderTarget(nullptr),
|
m_RenderTarget(nullptr),
|
||||||
m_ProcService(nullptr),
|
m_ProcService(nullptr),
|
||||||
|
@ -779,14 +780,20 @@ void DXVA2Renderer::notifyOverlayUpdated(Overlay::OverlayType type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DTexture9* oldTexture = (IDirect3DTexture9*)SDL_AtomicSetPtr((void**)&m_OverlayTextures[type], nullptr);
|
SDL_AtomicLock(&m_OverlayLock);
|
||||||
SAFE_COM_RELEASE(oldTexture);
|
IDirect3DTexture9* oldTexture = m_OverlayTextures[type];
|
||||||
|
m_OverlayTextures[type] = nullptr;
|
||||||
|
|
||||||
IDirect3DVertexBuffer9* oldVertexBuffer = (IDirect3DVertexBuffer9*)SDL_AtomicSetPtr((void**)&m_OverlayVertexBuffers[type], nullptr);
|
IDirect3DVertexBuffer9* oldVertexBuffer = m_OverlayVertexBuffers[type];
|
||||||
|
m_OverlayVertexBuffers[type] = nullptr;
|
||||||
|
SDL_AtomicUnlock(&m_OverlayLock);
|
||||||
|
|
||||||
|
SAFE_COM_RELEASE(oldTexture);
|
||||||
SAFE_COM_RELEASE(oldVertexBuffer);
|
SAFE_COM_RELEASE(oldVertexBuffer);
|
||||||
|
|
||||||
// If the overlay is disabled, we're done
|
// If the overlay is disabled, we're done
|
||||||
if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) {
|
if (!Session::get()->getOverlayManager().isOverlayEnabled(type)) {
|
||||||
|
SDL_FreeSurface(newSurface);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -894,8 +901,10 @@ void DXVA2Renderer::notifyOverlayUpdated(Overlay::OverlayType type)
|
||||||
|
|
||||||
newVertexBuffer->Unlock();
|
newVertexBuffer->Unlock();
|
||||||
|
|
||||||
SDL_AtomicSetPtr((void**)&m_OverlayVertexBuffers[type], newVertexBuffer);
|
SDL_AtomicLock(&m_OverlayLock);
|
||||||
SDL_AtomicSetPtr((void**)&m_OverlayTextures[type], newTexture);
|
m_OverlayVertexBuffers[type] = newVertexBuffer;
|
||||||
|
m_OverlayTextures[type] = newTexture;
|
||||||
|
SDL_AtomicUnlock(&m_OverlayLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DXVA2Renderer::renderOverlay(Overlay::OverlayType type)
|
void DXVA2Renderer::renderOverlay(Overlay::OverlayType type)
|
||||||
|
@ -906,34 +915,54 @@ void DXVA2Renderer::renderOverlay(Overlay::OverlayType type)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DTexture9* overlayTexture = (IDirect3DTexture9*)SDL_AtomicGetPtr((void**)&m_OverlayTextures[type]);
|
// If the overlay is being updated, just skip rendering it this frame
|
||||||
IDirect3DVertexBuffer9* overlayVertexBuffer = (IDirect3DVertexBuffer9*)SDL_AtomicGetPtr((void**)&m_OverlayVertexBuffers[type]);
|
if (!SDL_AtomicTryLock(&m_OverlayLock)) {
|
||||||
|
return;
|
||||||
if (overlayTexture != nullptr && overlayVertexBuffer != nullptr) {
|
|
||||||
hr = m_Device->SetTexture(0, overlayTexture);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"SetTexture() failed: %x",
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = m_Device->SetStreamSource(0, overlayVertexBuffer, 0, sizeof(VERTEX));
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"SetStreamSource() failed: %x",
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr = m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"DrawPrimitive() failed: %x",
|
|
||||||
hr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDirect3DTexture9* overlayTexture = m_OverlayTextures[type];
|
||||||
|
IDirect3DVertexBuffer9* overlayVertexBuffer = m_OverlayVertexBuffers[type];
|
||||||
|
|
||||||
|
if (overlayTexture == nullptr) {
|
||||||
|
SDL_AtomicUnlock(&m_OverlayLock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference these objects so they don't immediately go away if the
|
||||||
|
// overlay update thread tries to release them.
|
||||||
|
SDL_assert(overlayVertexBuffer != nullptr);
|
||||||
|
overlayTexture->AddRef();
|
||||||
|
overlayVertexBuffer->AddRef();
|
||||||
|
|
||||||
|
SDL_AtomicUnlock(&m_OverlayLock);
|
||||||
|
|
||||||
|
hr = m_Device->SetTexture(0, overlayTexture);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SetTexture() failed: %x",
|
||||||
|
hr);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_Device->SetStreamSource(0, overlayVertexBuffer, 0, sizeof(VERTEX));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SetStreamSource() failed: %x",
|
||||||
|
hr);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = m_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"DrawPrimitive() failed: %x",
|
||||||
|
hr);
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
overlayTexture->Release();
|
||||||
|
overlayVertexBuffer->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
int DXVA2Renderer::getDecoderColorspace()
|
int DXVA2Renderer::getDecoderColorspace()
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
int m_SurfacesUsed;
|
int m_SurfacesUsed;
|
||||||
AVBufferPool* m_Pool;
|
AVBufferPool* m_Pool;
|
||||||
|
|
||||||
|
SDL_SpinLock m_OverlayLock;
|
||||||
IDirect3DVertexBuffer9* m_OverlayVertexBuffers[Overlay::OverlayMax];
|
IDirect3DVertexBuffer9* m_OverlayVertexBuffers[Overlay::OverlayMax];
|
||||||
IDirect3DTexture9* m_OverlayTextures[Overlay::OverlayMax];
|
IDirect3DTexture9* m_OverlayTextures[Overlay::OverlayMax];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue