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:
parent
17a4e44828
commit
bc88dd2e92
@ -46,7 +46,10 @@ namespace
|
|||||||
{
|
{
|
||||||
const unsigned DELAYED_FLIP_MODE_TIMEOUT_MS = 200;
|
const unsigned DELAYED_FLIP_MODE_TIMEOUT_MS = 200;
|
||||||
|
|
||||||
|
CompatPtr<IDirectDrawSurface7> getBackBuffer();
|
||||||
|
CompatPtr<IDirectDrawSurface7> getLastSurface();
|
||||||
void onRelease();
|
void onRelease();
|
||||||
|
void presentationBlt(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src);
|
||||||
void updatePresentationWindow();
|
void updatePresentationWindow();
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
|
CompatWeakPtr<IDirectDrawSurface7> g_defaultPrimary;
|
||||||
@ -82,9 +85,6 @@ namespace
|
|||||||
HWND g_presentationWindow = nullptr;
|
HWND g_presentationWindow = nullptr;
|
||||||
long long g_qpcUpdatePresentationWindow = 0;
|
long long g_qpcUpdatePresentationWindow = 0;
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface7> getBackBuffer();
|
|
||||||
CompatPtr<IDirectDrawSurface7> getLastSurface();
|
|
||||||
|
|
||||||
void bltToPrimaryChain(CompatRef<IDirectDrawSurface7> src)
|
void bltToPrimaryChain(CompatRef<IDirectDrawSurface7> src)
|
||||||
{
|
{
|
||||||
if (!g_isFullscreen)
|
if (!g_isFullscreen)
|
||||||
@ -93,20 +93,7 @@ namespace
|
|||||||
|
|
||||||
if (g_presentationWindow)
|
if (g_presentationWindow)
|
||||||
{
|
{
|
||||||
D3dDdi::ScopedCriticalSection lock;
|
presentationBlt(*g_windowedBackBuffer, src);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Gdi::Window::present(*g_frontBuffer, g_presentationWindow ? *g_windowedBackBuffer : src, *g_clipper);
|
Gdi::Window::present(*g_frontBuffer, g_presentationWindow ? *g_windowedBackBuffer : src, *g_clipper);
|
||||||
@ -116,7 +103,7 @@ namespace
|
|||||||
auto backBuffer(getBackBuffer());
|
auto backBuffer(getBackBuffer());
|
||||||
if (backBuffer)
|
if (backBuffer)
|
||||||
{
|
{
|
||||||
backBuffer->Blt(backBuffer, nullptr, &src, nullptr, DDBLT_WAIT, nullptr);
|
presentationBlt(*backBuffer, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,6 +335,28 @@ namespace
|
|||||||
g_flipEndVsyncCount = g_presentEndVsyncCount;
|
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)
|
void presentToPrimaryChain(CompatWeakPtr<IDirectDrawSurface7> src, bool isOverlayOnly)
|
||||||
{
|
{
|
||||||
LOG_FUNC("RealPrimarySurface::presentToPrimaryChain", src, isOverlayOnly);
|
LOG_FUNC("RealPrimarySurface::presentToPrimaryChain", src, isOverlayOnly);
|
||||||
@ -720,14 +729,15 @@ namespace DDraw
|
|||||||
src = DDraw::PrimarySurface::getGdiPrimary();
|
src = DDraw::PrimarySurface::getGdiPrimary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateNow(src, isOverlayOnly);
|
||||||
|
|
||||||
RECT emptyRect = {};
|
RECT emptyRect = {};
|
||||||
HRESULT result = src ? src->BltFast(src, 0, 0, src, &emptyRect, DDBLTFAST_WAIT) : DD_OK;
|
HRESULT result = src ? src->BltFast(src, 0, 0, src, &emptyRect, DDBLTFAST_WAIT) : DD_OK;
|
||||||
if (DDERR_SURFACEBUSY == result || DDERR_LOCKEDSURFACES == result)
|
if (DDERR_SURFACEBUSY == result || DDERR_LOCKEDSURFACES == result)
|
||||||
{
|
{
|
||||||
return 1;
|
scheduleUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNow(src, isOverlayOnly);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,8 +200,23 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
HRESULT PrimarySurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
HRESULT PrimarySurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
||||||
{
|
{
|
||||||
|
if (RealPrimarySurface::isLost())
|
||||||
|
{
|
||||||
|
return DDERR_SURFACELOST;
|
||||||
|
}
|
||||||
|
|
||||||
RealPrimarySurface::flush();
|
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>
|
template <typename TSurface>
|
||||||
@ -241,6 +256,12 @@ namespace DDraw
|
|||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
restorePrimaryCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
||||||
|
auto statsWindow = Gdi::GuiThread::getStatsWindow();
|
||||||
|
if (statsWindow)
|
||||||
|
{
|
||||||
|
statsWindow->m_lock.add();
|
||||||
|
}
|
||||||
|
RealPrimarySurface::scheduleUpdate();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -251,11 +272,6 @@ namespace DDraw
|
|||||||
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
|
HRESULT result = SurfaceImpl::ReleaseDC(This, hDC);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
auto statsWindow = Gdi::GuiThread::getStatsWindow();
|
|
||||||
if (statsWindow)
|
|
||||||
{
|
|
||||||
statsWindow->m_lock.add();
|
|
||||||
}
|
|
||||||
RealPrimarySurface::scheduleUpdate();
|
RealPrimarySurface::scheduleUpdate();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -300,11 +316,6 @@ namespace DDraw
|
|||||||
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
|
HRESULT result = SurfaceImpl::Unlock(This, lpRect);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
auto statsWindow = Gdi::GuiThread::getStatsWindow();
|
|
||||||
if (statsWindow)
|
|
||||||
{
|
|
||||||
statsWindow->m_lock.add();
|
|
||||||
}
|
|
||||||
RealPrimarySurface::scheduleUpdate();
|
RealPrimarySurface::scheduleUpdate();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user