From 66e0d20897c5c8fe61da0e2ca2538a8c3e067179 Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 25 Aug 2019 12:09:35 +0200 Subject: [PATCH] Fixed GDI updates interrupted by presentation sync --- DDrawCompat/D3dDdi/Resource.cpp | 20 ++++++++++++++++++++ DDrawCompat/D3dDdi/Resource.h | 2 ++ DDrawCompat/Gdi/AccessGuard.cpp | 18 ++++++++---------- DDrawCompat/Gdi/AccessGuard.h | 5 ----- DDrawCompat/Gdi/PaintHandlers.cpp | 6 +++++- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index b612ac4..e478f96 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -188,6 +188,18 @@ namespace D3dDdi { } + void Resource::beginGdiAccess(bool isReadOnly) + { + if (m_lockResource) + { + if (!m_lockData[0].isSysMemUpToDate) + { + copyToSysMem(0); + } + m_lockData[0].isVidMemUpToDate &= isReadOnly; + } + } + HRESULT Resource::blt(D3DDDIARG_BLT data) { if (!isValidRect(data.DstSubResourceIndex, data.DstRect)) @@ -455,6 +467,14 @@ namespace D3dDdi LOG_RESULT(m_lockResource.get()); } + void Resource::endGdiAccess(bool isReadOnly) + { + if (m_lockResource && !isReadOnly && m_lockData[0].isSysMemUpToDate) + { + m_lockData[0].isVidMemUpToDate = false; + } + } + void Resource::fixVertexData(UINT offset, UINT count, UINT stride) { if (!m_fixedData.Flags.MightDrawFromLocked || diff --git a/DDrawCompat/D3dDdi/Resource.h b/DDrawCompat/D3dDdi/Resource.h index c616b06..667ef6f 100644 --- a/DDrawCompat/D3dDdi/Resource.h +++ b/DDrawCompat/D3dDdi/Resource.h @@ -26,8 +26,10 @@ namespace D3dDdi operator HANDLE() const { return m_handle; } + void beginGdiAccess(bool isReadOnly); HRESULT blt(D3DDDIARG_BLT data); HRESULT colorFill(D3DDDIARG_COLORFILL data); + void endGdiAccess(bool isReadOnly); void fixVertexData(UINT offset, UINT count, UINT stride); void* getLockPtr(UINT subResourceIndex); HRESULT lock(D3DDDIARG_LOCK& data); diff --git a/DDrawCompat/Gdi/AccessGuard.cpp b/DDrawCompat/Gdi/AccessGuard.cpp index 4063d57..7a114d2 100644 --- a/DDrawCompat/Gdi/AccessGuard.cpp +++ b/DDrawCompat/Gdi/AccessGuard.cpp @@ -16,25 +16,23 @@ namespace Gdi auto gdiResource = D3dDdi::Device::getGdiResource(); if (gdiResource) { - D3DDDIARG_LOCK lockData = {}; - lockData.hResource = gdiResource; - lockData.Flags.ReadOnly = ACCESS_READ == access; - gdiResource->lock(lockData); - - D3DDDIARG_UNLOCK unlockData = {}; - unlockData.hResource = gdiResource; - gdiResource->unlock(unlockData); + gdiResource->beginGdiAccess(ACCESS_READ == m_access); } } } AccessGuard::~AccessGuard() { - if (m_condition && ACCESS_WRITE == m_access) + if (m_condition) { D3dDdi::ScopedCriticalSection lock; auto gdiResource = D3dDdi::Device::getGdiResource(); - if (!gdiResource || DDraw::PrimarySurface::getFrontResource() == *gdiResource) + if (gdiResource) + { + gdiResource->endGdiAccess(ACCESS_READ == m_access); + } + if (ACCESS_WRITE == m_access && + (!gdiResource || DDraw::PrimarySurface::getFrontResource() == *gdiResource)) { DDraw::RealPrimarySurface::gdiUpdate(); } diff --git a/DDrawCompat/Gdi/AccessGuard.h b/DDrawCompat/Gdi/AccessGuard.h index b1296a3..0bd5b5a 100644 --- a/DDrawCompat/Gdi/AccessGuard.h +++ b/DDrawCompat/Gdi/AccessGuard.h @@ -1,10 +1,5 @@ #pragma once -namespace D3dDdi -{ - class Resource; -} - namespace Gdi { enum Access diff --git a/DDrawCompat/Gdi/PaintHandlers.cpp b/DDrawCompat/Gdi/PaintHandlers.cpp index 3c4af05..447fe87 100644 --- a/DDrawCompat/Gdi/PaintHandlers.cpp +++ b/DDrawCompat/Gdi/PaintHandlers.cpp @@ -217,7 +217,10 @@ namespace return onNcPaint(hwnd, wParam, origWndProc); case WM_PAINT: + { + D3dDdi::ScopedCriticalSection lock; return onPaint(hwnd, origWndProc); + } case WM_PRINTCLIENT: { @@ -238,7 +241,8 @@ namespace case 0x1e5: if (-1 == wParam) { - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE); + D3dDdi::ScopedCriticalSection lock; + RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW); } return CallWindowProc(origWndProc, hwnd, msg, wParam, lParam);