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

Merged Gdi::DcCache into Gdi::Dc

This commit is contained in:
narzoul 2021-02-20 12:10:05 +01:00
parent b83f7ca879
commit 4e3debf776
6 changed files with 37 additions and 102 deletions

View File

@ -218,7 +218,6 @@
<ClInclude Include="Gdi\Gdi.h" />
<ClInclude Include="Gdi\Caret.h" />
<ClInclude Include="Gdi\Dc.h" />
<ClInclude Include="Gdi\DcCache.h" />
<ClInclude Include="Gdi\DcFunctions.h" />
<ClInclude Include="Gdi\Icon.h" />
<ClInclude Include="Gdi\Metrics.h" />
@ -293,7 +292,6 @@
<ClCompile Include="Gdi\Gdi.cpp" />
<ClCompile Include="Gdi\Caret.cpp" />
<ClCompile Include="Gdi\Dc.cpp" />
<ClCompile Include="Gdi\DcCache.cpp" />
<ClCompile Include="Gdi\DcFunctions.cpp" />
<ClCompile Include="Gdi\Icon.cpp" />
<ClCompile Include="Gdi\Metrics.cpp" />

View File

@ -90,9 +90,6 @@
<ClInclude Include="Gdi\Dc.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\DcCache.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
<ClInclude Include="Gdi\DcFunctions.h">
<Filter>Header Files\Gdi</Filter>
</ClInclude>
@ -416,9 +413,6 @@
<ClCompile Include="Gdi\Dc.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\DcCache.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>
<ClCompile Include="Gdi\DcFunctions.cpp">
<Filter>Source Files\Gdi</Filter>
</ClCompile>

View File

@ -1,20 +1,25 @@
#include <algorithm>
#include <unordered_map>
#include <map>
#include <vector>
#include "Common/Hook.h"
#include "Common/Log.h"
#include "Common/ScopedCriticalSection.h"
#include "D3dDdi/ScopedCriticalSection.h"
#include "Gdi/Dc.h"
#include "Gdi/DcCache.h"
#include "Gdi/Gdi.h"
#include "Gdi/Region.h"
#include "Gdi/VirtualScreen.h"
#include "Gdi/Window.h"
#include <Common/Hook.h>
#include <Common/Log.h>
#include <Common/ScopedCriticalSection.h>
#include <D3dDdi/ScopedCriticalSection.h>
#include <Gdi/Dc.h>
#include <Gdi/Gdi.h>
#include <Gdi/Region.h>
#include <Gdi/VirtualScreen.h>
#include <Gdi/Window.h>
namespace
{
struct Cache
{
std::vector<std::unique_ptr<HDC__, void(*)(HDC)>> cache;
std::vector<std::unique_ptr<HDC__, void(*)(HDC)>> defPalCache;
};
struct CompatDc
{
HDC dc;
@ -25,10 +30,11 @@ namespace
bool useDefaultPalette;
};
typedef std::unordered_map<HDC, CompatDc> CompatDcMap;
typedef std::map<HDC, CompatDc> CompatDcMap;
Compat::CriticalSection g_cs;
CompatDcMap g_origDcToCompatDc;
std::map<DWORD, Cache> g_threadIdToDcCache;
void restoreDc(const CompatDc& compatDc);
@ -137,6 +143,7 @@ namespace Gdi
Gdi::VirtualScreen::deleteDc(origDcToCompatDc.second.dc);
}
g_origDcToCompatDc.clear();
g_threadIdToDcCache.clear();
}
void dllThreadDetach()
@ -157,6 +164,7 @@ namespace Gdi
++it;
}
}
g_threadIdToDcCache.erase(GetCurrentThreadId());
}
HDC getDc(HDC origDc)
@ -179,10 +187,21 @@ namespace Gdi
CompatDc compatDc;
compatDc.useDefaultPalette = GetStockObject(DEFAULT_PALETTE) == GetCurrentObject(origDc, OBJ_PAL);
compatDc.dc = Gdi::DcCache::getDc(compatDc.useDefaultPalette);
if (!compatDc.dc)
auto& cache = g_threadIdToDcCache[GetCurrentThreadId()];
auto& dcCache = compatDc.useDefaultPalette ? cache.defPalCache : cache.cache;
if (dcCache.empty())
{
return nullptr;
compatDc.dc = Gdi::VirtualScreen::createDc(compatDc.useDefaultPalette);
if (!compatDc.dc)
{
return nullptr;
}
}
else
{
compatDc.dc = dcCache.back().release();
dcCache.pop_back();
}
POINT origin = {};
@ -235,7 +254,9 @@ namespace Gdi
if (0 == compatDc.refCount)
{
restoreDc(compatDc);
Gdi::DcCache::releaseDc(compatDc.dc, compatDc.useDefaultPalette);
auto& cache = g_threadIdToDcCache[GetCurrentThreadId()];
auto& dcCache = compatDc.useDefaultPalette ? cache.defPalCache : cache.cache;
dcCache.emplace_back(compatDc.dc, Gdi::VirtualScreen::deleteDc);
g_origDcToCompatDc.erase(origDc);
}
}

View File

@ -1,61 +0,0 @@
#include <map>
#include <memory>
#include <vector>
#include <Common/ScopedCriticalSection.h>
#include <Gdi/DcCache.h>
#include <Gdi/VirtualScreen.h>
namespace
{
struct Cache
{
std::vector<std::unique_ptr<HDC__, void(*)(HDC)>> cache;
std::vector<std::unique_ptr<HDC__, void(*)(HDC)>> defPalCache;
};
Compat::CriticalSection g_cs;
std::map<DWORD, Cache> g_threadIdToDcCache;
}
namespace Gdi
{
namespace DcCache
{
void dllProcessDetach()
{
Compat::ScopedCriticalSection lock(g_cs);
g_threadIdToDcCache.clear();
}
void dllThreadDetach()
{
Compat::ScopedCriticalSection lock(g_cs);
g_threadIdToDcCache.erase(GetCurrentThreadId());
}
HDC getDc(bool useDefaultPalette)
{
Compat::ScopedCriticalSection lock(g_cs);
auto& cache = g_threadIdToDcCache[GetCurrentThreadId()];
auto& dcCache = useDefaultPalette ? cache.defPalCache : cache.cache;
if (dcCache.empty())
{
return Gdi::VirtualScreen::createDc(useDefaultPalette);
}
HDC dc = dcCache.back().release();
dcCache.pop_back();
return dc;
}
void releaseDc(HDC cachedDc, bool useDefaultPalette)
{
Compat::ScopedCriticalSection lock(g_cs);
auto& cache = g_threadIdToDcCache[GetCurrentThreadId()];
auto& dcCache = useDefaultPalette ? cache.defPalCache : cache.cache;
dcCache.emplace_back(cachedDc, Gdi::VirtualScreen::deleteDc);
}
}
}

View File

@ -1,14 +0,0 @@
#pragma once
#include <Windows.h>
namespace Gdi
{
namespace DcCache
{
void dllProcessDetach();
void dllThreadDetach();
HDC getDc(bool useDefaultPalette);
void releaseDc(HDC cachedDc, bool useDefaultPalette);
}
}

View File

@ -1,7 +1,6 @@
#include <DDraw/Surfaces/PrimarySurface.h>
#include <Gdi/Caret.h>
#include <Gdi/Dc.h>
#include <Gdi/DcCache.h>
#include <Gdi/DcFunctions.h>
#include <Gdi/Font.h>
#include <Gdi/Gdi.h>
@ -33,7 +32,6 @@ namespace Gdi
{
WinProc::dllThreadDetach();
Dc::dllThreadDetach();
DcCache::dllThreadDetach();
}
void installHooks()
@ -98,7 +96,6 @@ namespace Gdi
PresentationWindow::uninstallHooks();
WinProc::uninstallHooks();
Dc::dllProcessDetach();
DcCache::dllProcessDetach();
}
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)