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;
|
||||
DWORD g_renderingRefCount = 0;
|
||||
DWORD g_ddLockFlags = 0;
|
||||
DWORD g_ddLockThreadRenderingRefCount = 0;
|
||||
DWORD g_ddLockThreadId = 0;
|
||||
HANDLE g_ddUnlockBeginEvent = nullptr;
|
||||
@ -53,16 +54,22 @@ namespace
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool lockPrimarySurface()
|
||||
bool lockPrimarySurface(DWORD lockFlags)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
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;
|
||||
}
|
||||
|
||||
g_ddLockFlags = lockFlags;
|
||||
if (0 != lockFlags)
|
||||
{
|
||||
EnterCriticalSection(&CompatGdi::g_gdiCriticalSection);
|
||||
}
|
||||
|
||||
g_ddLockThreadId = GetCurrentThreadId();
|
||||
CompatGdiDcCache::setDdLockThreadId(g_ddLockThreadId);
|
||||
CompatGdiDcCache::setSurfaceMemory(desc.lpSurface, desc.lPitch);
|
||||
@ -74,8 +81,17 @@ namespace
|
||||
GdiFlush();
|
||||
auto primary(CompatPrimarySurface::getPrimary());
|
||||
primary->Unlock(primary, nullptr);
|
||||
RealPrimarySurface::invalidate(nullptr);
|
||||
RealPrimarySurface::update();
|
||||
if (DDLOCK_READONLY != g_ddLockFlags)
|
||||
{
|
||||
RealPrimarySurface::invalidate(nullptr);
|
||||
RealPrimarySurface::update();
|
||||
}
|
||||
|
||||
if (0 != g_ddLockFlags)
|
||||
{
|
||||
LeaveCriticalSection(&CompatGdi::g_gdiCriticalSection);
|
||||
}
|
||||
g_ddLockFlags = 0;
|
||||
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
@ -85,7 +101,7 @@ namespace CompatGdi
|
||||
{
|
||||
CRITICAL_SECTION g_gdiCriticalSection;
|
||||
|
||||
bool beginGdiRendering()
|
||||
bool beginGdiRendering(DWORD lockFlags)
|
||||
{
|
||||
if (!isEmulationEnabled())
|
||||
{
|
||||
@ -99,7 +115,7 @@ namespace CompatGdi
|
||||
LeaveCriticalSection(&g_gdiCriticalSection);
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
EnterCriticalSection(&g_gdiCriticalSection);
|
||||
if (!lockPrimarySurface())
|
||||
if (!lockPrimarySurface(lockFlags))
|
||||
{
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
return false;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
namespace CompatGdi
|
||||
{
|
||||
bool beginGdiRendering();
|
||||
bool beginGdiRendering(DWORD lockFlags = 0);
|
||||
void endGdiRendering();
|
||||
|
||||
void disableEmulation();
|
||||
|
@ -10,6 +10,9 @@ namespace
|
||||
{
|
||||
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 PolyPatBlt(HDC, DWORD, DWORD, DWORD, DWORD) { return FALSE; }
|
||||
|
||||
@ -67,7 +70,8 @@ namespace
|
||||
Compat::LogEnter(g_funcNames[origFunc], params...);
|
||||
#endif
|
||||
|
||||
if (!hasDisplayDcArg(params...) || !CompatGdi::beginGdiRendering())
|
||||
if (!hasDisplayDcArg(params...) ||
|
||||
!CompatGdi::beginGdiRendering(getDdLockFlags<OrigFuncPtr, origFunc>(params...)))
|
||||
{
|
||||
Result result = Compat::getOrigFuncPtr<OrigFuncPtr, origFunc>()(params...);
|
||||
|
||||
@ -107,6 +111,18 @@ namespace
|
||||
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>
|
||||
void hookGdiDcFunction(const char* moduleName, const char* funcName)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user