diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 0726e21..ff3d12d 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -46,7 +46,10 @@ namespace { const unsigned DELAYED_FLIP_MODE_TIMEOUT_MS = 200; + CompatPtr getBackBuffer(); + CompatPtr getLastSurface(); void onRelease(); + void presentationBlt(CompatRef dst, CompatRef src); void updatePresentationWindow(); CompatWeakPtr g_defaultPrimary; @@ -82,9 +85,6 @@ namespace HWND g_presentationWindow = nullptr; long long g_qpcUpdatePresentationWindow = 0; - CompatPtr getBackBuffer(); - CompatPtr getLastSurface(); - void bltToPrimaryChain(CompatRef src) { if (!g_isFullscreen) @@ -93,20 +93,7 @@ namespace if (g_presentationWindow) { - D3dDdi::ScopedCriticalSection lock; - auto srcResource = D3dDdi::Device::findResource( - DDraw::DirectDrawSurface::getDriverResourceHandle(src.get())); - auto bbResource = D3dDdi::Device::findResource( - DDraw::DirectDrawSurface::getDriverResourceHandle(*g_windowedBackBuffer)); - - D3DDDIARG_BLT blt = {}; - blt.hSrcResource = *srcResource; - blt.SrcSubResourceIndex = DDraw::DirectDrawSurface::getSubResourceIndex(src.get()); - blt.SrcRect = DDraw::PrimarySurface::getMonitorRect(); - blt.hDstResource = *bbResource; - blt.DstSubResourceIndex = 0; - blt.DstRect = g_monitorRect; - bbResource->presentationBlt(blt, srcResource); + presentationBlt(*g_windowedBackBuffer, src); } Gdi::Window::present(*g_frontBuffer, g_presentationWindow ? *g_windowedBackBuffer : src, *g_clipper); @@ -116,7 +103,7 @@ namespace auto backBuffer(getBackBuffer()); if (backBuffer) { - backBuffer->Blt(backBuffer, nullptr, &src, nullptr, DDBLT_WAIT, nullptr); + presentationBlt(*backBuffer, src); } } @@ -348,6 +335,28 @@ namespace g_flipEndVsyncCount = g_presentEndVsyncCount; } + void presentationBlt(CompatRef dst, CompatRef src) + { + D3dDdi::ScopedCriticalSection lock; + auto srcResource = D3dDdi::Device::findResource( + DDraw::DirectDrawSurface::getDriverResourceHandle(src.get())); + auto dstResource = D3dDdi::Device::findResource( + DDraw::DirectDrawSurface::getDriverResourceHandle(dst.get())); + if (!srcResource || !dstResource) + { + return; + } + + D3DDDIARG_BLT blt = {}; + blt.hSrcResource = *srcResource; + blt.SrcSubResourceIndex = DDraw::DirectDrawSurface::getSubResourceIndex(src.get()); + blt.SrcRect = DDraw::PrimarySurface::getMonitorRect(); + blt.hDstResource = *dstResource; + blt.DstSubResourceIndex = DDraw::DirectDrawSurface::getSubResourceIndex(dst.get()); + blt.DstRect = g_monitorRect; + dstResource->presentationBlt(blt, srcResource); + } + void presentToPrimaryChain(CompatWeakPtr src, bool isOverlayOnly) { LOG_FUNC("RealPrimarySurface::presentToPrimaryChain", src, isOverlayOnly); @@ -720,14 +729,15 @@ namespace DDraw src = DDraw::PrimarySurface::getGdiPrimary(); } + updateNow(src, isOverlayOnly); + RECT emptyRect = {}; HRESULT result = src ? src->BltFast(src, 0, 0, src, &emptyRect, DDBLTFAST_WAIT) : DD_OK; if (DDERR_SURFACEBUSY == result || DDERR_LOCKEDSURFACES == result) { - return 1; + scheduleUpdate(); } - updateNow(src, isOverlayOnly); return 0; } diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index 152fbca..4b13f07 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -200,8 +200,23 @@ namespace DDraw template HRESULT PrimarySurfaceImpl::GetDC(TSurface* This, HDC* lphDC) { + if (RealPrimarySurface::isLost()) + { + return DDERR_SURFACELOST; + } + RealPrimarySurface::flush(); - return SurfaceImpl::GetDC(This, lphDC); + HRESULT result = SurfaceImpl::GetDC(This, lphDC); + if (SUCCEEDED(result)) + { + auto statsWindow = Gdi::GuiThread::getStatsWindow(); + if (statsWindow) + { + statsWindow->m_lock.add(); + } + RealPrimarySurface::scheduleUpdate(); + } + return result; } template @@ -241,6 +256,12 @@ namespace DDraw if (SUCCEEDED(result)) { restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); + auto statsWindow = Gdi::GuiThread::getStatsWindow(); + if (statsWindow) + { + statsWindow->m_lock.add(); + } + RealPrimarySurface::scheduleUpdate(); } return result; } @@ -251,11 +272,6 @@ namespace DDraw HRESULT result = SurfaceImpl::ReleaseDC(This, hDC); if (SUCCEEDED(result)) { - auto statsWindow = Gdi::GuiThread::getStatsWindow(); - if (statsWindow) - { - statsWindow->m_lock.add(); - } RealPrimarySurface::scheduleUpdate(); } return result; @@ -300,11 +316,6 @@ namespace DDraw HRESULT result = SurfaceImpl::Unlock(This, lpRect); if (SUCCEEDED(result)) { - auto statsWindow = Gdi::GuiThread::getStatsWindow(); - if (statsWindow) - { - statsWindow->m_lock.add(); - } RealPrimarySurface::scheduleUpdate(); } return result;