mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Always wait for flip before Blt/Lock
Returning DDERR_WASSTILLDRAWING interferes with rendering in Lego Island. Viewport clear should wait for flip, but it's internally buffered by ddraw and flushed during Blt, which didn't happen because of Blt failing early.
This commit is contained in:
parent
67f38479b7
commit
b878028748
@ -58,10 +58,8 @@ namespace
|
||||
SET_COMPAT_METHOD(Blt);
|
||||
SET_COMPAT_METHOD(BltFast);
|
||||
SET_COMPAT_METHOD(Flip);
|
||||
SET_COMPAT_METHOD(GetBltStatus);
|
||||
SET_COMPAT_METHOD(GetCaps);
|
||||
SET_COMPAT_METHOD(GetDC);
|
||||
SET_COMPAT_METHOD(GetFlipStatus);
|
||||
SET_COMPAT_METHOD(GetSurfaceDesc);
|
||||
SET_COMPAT_METHOD(IsLost);
|
||||
SET_COMPAT_METHOD(Lock);
|
||||
|
@ -317,7 +317,6 @@ namespace DDraw
|
||||
updateNow(PrimarySurface::getPrimary(), flipInterval);
|
||||
}
|
||||
g_flipEndVsyncCount = D3dDdi::KernelModeThunks::getVsyncCounter() + flipInterval;
|
||||
g_presentEndVsyncCount = g_flipEndVsyncCount;
|
||||
|
||||
if (0 != flipInterval)
|
||||
{
|
||||
@ -424,7 +423,7 @@ namespace DDraw
|
||||
}
|
||||
}
|
||||
|
||||
bool RealPrimarySurface::waitForFlip(Surface* surface, bool wait)
|
||||
bool RealPrimarySurface::waitForFlip(Surface* surface)
|
||||
{
|
||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||
if (!surface || !primary ||
|
||||
@ -434,11 +433,6 @@ namespace DDraw
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!wait)
|
||||
{
|
||||
return !isFlipPending();
|
||||
}
|
||||
|
||||
D3dDdi::KernelModeThunks::waitForVsyncCounter(g_flipEndVsyncCount);
|
||||
return true;
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ namespace DDraw
|
||||
static void scheduleUpdate();
|
||||
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
||||
static void update();
|
||||
static bool waitForFlip(Surface* surface, bool wait = true);
|
||||
static bool waitForFlip(Surface* surface);
|
||||
};
|
||||
}
|
||||
|
@ -120,11 +120,7 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT PrimarySurfaceImpl<TSurface>::Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags)
|
||||
{
|
||||
if (!waitForFlip(This, dwFlags, DDFLIP_WAIT, DDFLIP_DONOTWAIT))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
|
||||
DDraw::RealPrimarySurface::waitForFlip(m_data);
|
||||
auto surfaceTargetOverride(CompatPtr<TSurface>::from(lpDDSurfaceTargetOverride));
|
||||
const bool isFlipEmulated = 0 != (PrimarySurface::getOrigCaps() & DDSCAPS_SYSTEMMEMORY);
|
||||
if (isFlipEmulated)
|
||||
|
@ -9,15 +9,6 @@
|
||||
#include <DDraw/Surfaces/SurfaceImpl.h>
|
||||
#include <Dll/Dll.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
void* getSurface7VtablePtr(IUnknown* surface)
|
||||
{
|
||||
static void* vtable = CompatPtr<IDirectDrawSurface7>::from(surface).get()->lpVtbl;
|
||||
return vtable;
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
template <typename TSurface>
|
||||
@ -36,10 +27,7 @@ namespace DDraw
|
||||
TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
|
||||
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
||||
{
|
||||
if (!waitForFlip(This, dwFlags, DDBLT_WAIT, DDBLT_DONOTWAIT))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
RealPrimarySurface::waitForFlip(m_data);
|
||||
DirectDrawClipper::update();
|
||||
return getOrigVtable(This).Blt(This, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
|
||||
}
|
||||
@ -48,10 +36,7 @@ namespace DDraw
|
||||
HRESULT SurfaceImpl<TSurface>::BltFast(
|
||||
TSurface* This, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
|
||||
{
|
||||
if (!waitForFlip(This, dwTrans, DDBLTFAST_WAIT, DDBLTFAST_DONOTWAIT))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
RealPrimarySurface::waitForFlip(m_data);
|
||||
return getOrigVtable(This).BltFast(This, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
|
||||
}
|
||||
|
||||
@ -61,21 +46,6 @@ namespace DDraw
|
||||
return getOrigVtable(This).Flip(This, lpDDSurfaceTargetOverride, dwFlags);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::GetBltStatus(TSurface* This, DWORD dwFlags)
|
||||
{
|
||||
HRESULT result = getOrigVtable(This).GetBltStatus(This, dwFlags);
|
||||
if (SUCCEEDED(result) && (dwFlags & DDGBS_CANBLT))
|
||||
{
|
||||
const bool wait = false;
|
||||
if (!RealPrimarySurface::waitForFlip(m_data, wait))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
|
||||
{
|
||||
@ -90,30 +60,15 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::GetDC(TSurface* This, HDC* lphDC)
|
||||
{
|
||||
RealPrimarySurface::waitForFlip(m_data);
|
||||
HRESULT result = getOrigVtable(This).GetDC(This, lphDC);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
RealPrimarySurface::waitForFlip(m_data);
|
||||
Dll::g_origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::GetFlipStatus(TSurface* This, DWORD dwFlags)
|
||||
{
|
||||
HRESULT result = getOrigVtable(This).GetFlipStatus(This, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
const bool wait = false;
|
||||
if (!RealPrimarySurface::waitForFlip(m_data, wait))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||
{
|
||||
@ -142,11 +97,7 @@ namespace DDraw
|
||||
TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
||||
DWORD dwFlags, HANDLE hEvent)
|
||||
{
|
||||
if (!waitForFlip(This, dwFlags, DDLOCK_WAIT, DDLOCK_DONOTWAIT))
|
||||
{
|
||||
return DDERR_WASSTILLDRAWING;
|
||||
}
|
||||
|
||||
RealPrimarySurface::waitForFlip(m_data);
|
||||
HRESULT result = getOrigVtable(This).Lock(This, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
@ -235,14 +186,6 @@ namespace DDraw
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
bool SurfaceImpl<TSurface>::waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag)
|
||||
{
|
||||
const bool wait = (flags & waitFlag) || !(flags & doNotWaitFlag) &&
|
||||
getSurface7VtablePtr(reinterpret_cast<IUnknown*>(This)) == This->lpVtbl;
|
||||
return DDraw::RealPrimarySurface::waitForFlip(m_data, wait);
|
||||
}
|
||||
|
||||
template SurfaceImpl<IDirectDrawSurface>;
|
||||
template SurfaceImpl<IDirectDrawSurface2>;
|
||||
template SurfaceImpl<IDirectDrawSurface3>;
|
||||
|
@ -27,10 +27,8 @@ namespace DDraw
|
||||
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
|
||||
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans);
|
||||
virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags);
|
||||
virtual HRESULT GetBltStatus(TSurface* This, DWORD dwFlags);
|
||||
virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
|
||||
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
|
||||
virtual HRESULT GetFlipStatus(TSurface* This, DWORD dwFlags);
|
||||
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||
virtual HRESULT IsLost(TSurface* This);
|
||||
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
|
||||
@ -43,11 +41,9 @@ namespace DDraw
|
||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
||||
|
||||
protected:
|
||||
bool waitForFlip(TSurface* This, DWORD flags, DWORD waitFlag, DWORD doNotWaitFlag);
|
||||
Surface* m_data;
|
||||
|
||||
private:
|
||||
void restoreOrigCaps(DWORD& caps);
|
||||
|
||||
Surface* m_data;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user