mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Improved GetPixel performance via DDLOCK_READONLY
Reduces Diablo II startup time.
This commit is contained in:
parent
b78ea774d7
commit
cf08f10162
@ -17,6 +17,7 @@ namespace
|
|||||||
{
|
{
|
||||||
std::atomic<int> g_disableEmulationCount = 0;
|
std::atomic<int> g_disableEmulationCount = 0;
|
||||||
DWORD g_renderingRefCount = 0;
|
DWORD g_renderingRefCount = 0;
|
||||||
|
DWORD g_ddLockFlags = 0;
|
||||||
DWORD g_ddLockThreadRenderingRefCount = 0;
|
DWORD g_ddLockThreadRenderingRefCount = 0;
|
||||||
DWORD g_ddLockThreadId = 0;
|
DWORD g_ddLockThreadId = 0;
|
||||||
HANDLE g_ddUnlockBeginEvent = nullptr;
|
HANDLE g_ddUnlockBeginEvent = nullptr;
|
||||||
@ -53,16 +54,22 @@ namespace
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lockPrimarySurface()
|
bool lockPrimarySurface(DWORD lockFlags)
|
||||||
{
|
{
|
||||||
DDSURFACEDESC2 desc = {};
|
DDSURFACEDESC2 desc = {};
|
||||||
desc.dwSize = sizeof(desc);
|
desc.dwSize = sizeof(desc);
|
||||||
auto primary(CompatPrimarySurface::getPrimary());
|
auto primary(CompatPrimarySurface::getPrimary());
|
||||||
if (FAILED(primary->Lock(primary, nullptr, &desc, DDLOCK_WAIT, nullptr)))
|
if (FAILED(primary->Lock(primary, nullptr, &desc, lockFlags | DDLOCK_WAIT, nullptr)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_ddLockFlags = lockFlags;
|
||||||
|
if (0 != lockFlags)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&CompatGdi::g_gdiCriticalSection);
|
||||||
|
}
|
||||||
|
|
||||||
g_ddLockThreadId = GetCurrentThreadId();
|
g_ddLockThreadId = GetCurrentThreadId();
|
||||||
CompatGdiDcCache::setDdLockThreadId(g_ddLockThreadId);
|
CompatGdiDcCache::setDdLockThreadId(g_ddLockThreadId);
|
||||||
CompatGdiDcCache::setSurfaceMemory(desc.lpSurface, desc.lPitch);
|
CompatGdiDcCache::setSurfaceMemory(desc.lpSurface, desc.lPitch);
|
||||||
@ -74,8 +81,17 @@ namespace
|
|||||||
GdiFlush();
|
GdiFlush();
|
||||||
auto primary(CompatPrimarySurface::getPrimary());
|
auto primary(CompatPrimarySurface::getPrimary());
|
||||||
primary->Unlock(primary, nullptr);
|
primary->Unlock(primary, nullptr);
|
||||||
RealPrimarySurface::invalidate(nullptr);
|
if (DDLOCK_READONLY != g_ddLockFlags)
|
||||||
RealPrimarySurface::update();
|
{
|
||||||
|
RealPrimarySurface::invalidate(nullptr);
|
||||||
|
RealPrimarySurface::update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != g_ddLockFlags)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection(&CompatGdi::g_gdiCriticalSection);
|
||||||
|
}
|
||||||
|
g_ddLockFlags = 0;
|
||||||
|
|
||||||
Compat::origProcs.ReleaseDDThreadLock();
|
Compat::origProcs.ReleaseDDThreadLock();
|
||||||
}
|
}
|
||||||
@ -85,7 +101,7 @@ namespace CompatGdi
|
|||||||
{
|
{
|
||||||
CRITICAL_SECTION g_gdiCriticalSection;
|
CRITICAL_SECTION g_gdiCriticalSection;
|
||||||
|
|
||||||
bool beginGdiRendering()
|
bool beginGdiRendering(DWORD lockFlags)
|
||||||
{
|
{
|
||||||
if (!isEmulationEnabled())
|
if (!isEmulationEnabled())
|
||||||
{
|
{
|
||||||
@ -99,7 +115,7 @@ namespace CompatGdi
|
|||||||
LeaveCriticalSection(&g_gdiCriticalSection);
|
LeaveCriticalSection(&g_gdiCriticalSection);
|
||||||
Compat::origProcs.AcquireDDThreadLock();
|
Compat::origProcs.AcquireDDThreadLock();
|
||||||
EnterCriticalSection(&g_gdiCriticalSection);
|
EnterCriticalSection(&g_gdiCriticalSection);
|
||||||
if (!lockPrimarySurface())
|
if (!lockPrimarySurface(lockFlags))
|
||||||
{
|
{
|
||||||
Compat::origProcs.ReleaseDDThreadLock();
|
Compat::origProcs.ReleaseDDThreadLock();
|
||||||
return false;
|
return false;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace CompatGdi
|
namespace CompatGdi
|
||||||
{
|
{
|
||||||
bool beginGdiRendering();
|
bool beginGdiRendering(DWORD lockFlags = 0);
|
||||||
void endGdiRendering();
|
void endGdiRendering();
|
||||||
|
|
||||||
void disableEmulation();
|
void disableEmulation();
|
||||||
|
@ -10,6 +10,9 @@ namespace
|
|||||||
{
|
{
|
||||||
std::unordered_map<void*, const char*> g_funcNames;
|
std::unordered_map<void*, const char*> g_funcNames;
|
||||||
|
|
||||||
|
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename... Params>
|
||||||
|
DWORD getDdLockFlags(Params... params);
|
||||||
|
|
||||||
BOOL WINAPI GdiDrawStream(HDC, DWORD, DWORD) { return FALSE; }
|
BOOL WINAPI GdiDrawStream(HDC, DWORD, DWORD) { return FALSE; }
|
||||||
BOOL WINAPI PolyPatBlt(HDC, DWORD, DWORD, DWORD, DWORD) { return FALSE; }
|
BOOL WINAPI PolyPatBlt(HDC, DWORD, DWORD, DWORD, DWORD) { return FALSE; }
|
||||||
|
|
||||||
@ -67,7 +70,8 @@ namespace
|
|||||||
Compat::LogEnter(g_funcNames[origFunc], params...);
|
Compat::LogEnter(g_funcNames[origFunc], params...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!hasDisplayDcArg(params...) || !CompatGdi::beginGdiRendering())
|
if (!hasDisplayDcArg(params...) ||
|
||||||
|
!CompatGdi::beginGdiRendering(getDdLockFlags<OrigFuncPtr, origFunc>(params...)))
|
||||||
{
|
{
|
||||||
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
|
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
|
||||||
|
|
||||||
@ -107,6 +111,18 @@ namespace
|
|||||||
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename... Params>
|
||||||
|
DWORD getDdLockFlags(Params...)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
DWORD getDdLockFlags<decltype(&GetPixel), &GetPixel>(HDC, int, int)
|
||||||
|
{
|
||||||
|
return DDLOCK_READONLY;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||||
void hookGdiDcFunction(const char* moduleName, const char* funcName)
|
void hookGdiDcFunction(const char* moduleName, const char* funcName)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user