1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added support for presenting from locked primary surface

See issue #260.
This commit is contained in:
narzoul 2024-03-23 17:26:34 +01:00
parent 17a4e44828
commit bc88dd2e92
2 changed files with 52 additions and 31 deletions

View File

@ -46,7 +46,10 @@ namespace
{
const unsigned DELAYED_FLIP_MODE_TIMEOUT_MS = 200;
CompatPtr<IDirectDrawSurface7> getBackBuffer();
CompatPtr<IDirectDrawSurface7> getLastSurface();
void onRelease();
void presentationBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src);
void updatePresentationWindow();
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
@ -82,9 +85,6 @@ namespace
HWND g_presentationWindow = nullptr;
long long g_qpcUpdatePresentationWindow = 0;
CompatPtr<IDirectDrawSurface7> getBackBuffer();
CompatPtr<IDirectDrawSurface7> getLastSurface();
void bltToPrimaryChain(CompatRef<IDirectDrawSurface7> 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<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> 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<IDirectDrawSurface7> 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;
}

View File

@ -200,8 +200,23 @@ namespace DDraw
template <typename TSurface>
HRESULT PrimarySurfaceImpl<TSurface>::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 <typename TSurface>
@ -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;