mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
GDI performance enhancements
This commit is contained in:
parent
c4ea2541a9
commit
c8ecb227a3
@ -1,9 +1,31 @@
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatPtr.h"
|
||||
#include "DDrawProcs.h"
|
||||
#include "DDrawRepository.h"
|
||||
#include "Hook.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_compatibleSurface = {};
|
||||
HDC g_compatibleDc = nullptr;
|
||||
CompatDisplayMode::DisplayMode g_emulatedDisplayMode = {};
|
||||
|
||||
CompatPtr<IDirectDrawSurface7> createCompatibleSurface()
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||
desc.dwWidth = 1;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddpfPixelFormat = g_emulatedDisplayMode.pixelFormat;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
auto dd = DDrawRepository::getDirectDraw();
|
||||
CompatPtr<IDirectDrawSurface7> surface;
|
||||
dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
|
||||
return surface;
|
||||
}
|
||||
|
||||
template <typename TSurfaceDesc>
|
||||
HRESULT PASCAL enumDisplayModesCallback(
|
||||
TSurfaceDesc* lpDDSurfaceDesc,
|
||||
@ -49,13 +71,63 @@ namespace
|
||||
Compat::Log() << "Failed to find the requested display mode: " <<
|
||||
width << "x" << height << "x" << bpp;
|
||||
}
|
||||
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
void releaseCompatibleDc()
|
||||
{
|
||||
if (g_compatibleDc)
|
||||
{
|
||||
Compat::origProcs.AcquireDDThreadLock();
|
||||
g_compatibleSurface->ReleaseDC(g_compatibleSurface, g_compatibleDc);
|
||||
g_compatibleDc = nullptr;
|
||||
g_compatibleSurface.release();
|
||||
}
|
||||
}
|
||||
|
||||
void replaceDc(HDC& hdc)
|
||||
{
|
||||
if (g_compatibleDc && hdc && OBJ_DC == GetObjectType(hdc) &&
|
||||
DT_RASDISPLAY == GetDeviceCaps(hdc, TECHNOLOGY))
|
||||
{
|
||||
hdc = g_compatibleDc;
|
||||
}
|
||||
}
|
||||
|
||||
void updateCompatibleDc()
|
||||
{
|
||||
releaseCompatibleDc();
|
||||
g_compatibleSurface = createCompatibleSurface().detach();
|
||||
if (g_compatibleSurface &&
|
||||
SUCCEEDED(g_compatibleSurface->GetDC(g_compatibleSurface, &g_compatibleDc)))
|
||||
{
|
||||
Compat::origProcs.ReleaseDDThreadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace CompatDisplayMode
|
||||
{
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(CreateDIBitmap)(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
|
||||
{
|
||||
replaceDc(hdc);
|
||||
return CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight);
|
||||
}
|
||||
|
||||
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
if (0 == g_emulatedDisplayMode.width)
|
||||
@ -85,6 +157,7 @@ namespace CompatDisplayMode
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
ZeroMemory(&g_emulatedDisplayMode, sizeof(g_emulatedDisplayMode));
|
||||
releaseCompatibleDc();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -111,6 +184,7 @@ namespace CompatDisplayMode
|
||||
g_emulatedDisplayMode.pixelFormat = pf;
|
||||
g_emulatedDisplayMode.refreshRate = refreshRate;
|
||||
g_emulatedDisplayMode.flags = flags;
|
||||
updateCompatibleDc();
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
@ -17,6 +17,11 @@ namespace CompatDisplayMode
|
||||
DWORD flags;
|
||||
};
|
||||
|
||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy);
|
||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage);
|
||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight);
|
||||
|
||||
DisplayMode getDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
DisplayMode getRealDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
HRESULT restoreDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "CompatDisplayMode.h"
|
||||
#include "CompatGdi.h"
|
||||
#include "CompatGdiDc.h"
|
||||
#include "CompatGdiDcFunctions.h"
|
||||
@ -111,18 +112,86 @@ namespace
|
||||
return &compatGdiDcFunc<OrigFuncPtr, origFunc, Result, Params...>;
|
||||
}
|
||||
|
||||
DWORD getDdLockFlagsBlt(HDC hdcDest, HDC hdcSrc)
|
||||
{
|
||||
return hasDisplayDcArg(hdcSrc) && !hasDisplayDcArg(hdcDest) ? DDLOCK_READONLY : 0;
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc, typename... Params>
|
||||
DWORD getDdLockFlags(Params...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&AlphaBlend), &AlphaBlend>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, int, int, BLENDFUNCTION)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&BitBlt), &BitBlt>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, DWORD)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&GdiAlphaBlend), &GdiAlphaBlend>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, int, int, BLENDFUNCTION)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&GdiTransparentBlt), &GdiTransparentBlt >(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, int, int, UINT)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&GetDIBits), &GetDIBits>(
|
||||
HDC, HBITMAP, UINT, UINT, LPVOID, LPBITMAPINFO, UINT)
|
||||
{
|
||||
return DDLOCK_READONLY;
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&GetPixel), &GetPixel>(HDC, int, int)
|
||||
{
|
||||
return DDLOCK_READONLY;
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&MaskBlt), &MaskBlt>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, HBITMAP, int, int, DWORD)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&PlgBlt), &PlgBlt>(
|
||||
HDC hdcDest, const POINT*, HDC hdcSrc, int, int, int, int, HBITMAP, int, int)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&StretchBlt), &StretchBlt>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, int, int, DWORD)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <>
|
||||
DWORD getDdLockFlags<decltype(&TransparentBlt), &TransparentBlt>(
|
||||
HDC hdcDest, int, int, int, int, HDC hdcSrc, int, int, int, int, UINT)
|
||||
{
|
||||
return getDdLockFlagsBlt(hdcDest, hdcSrc);
|
||||
}
|
||||
|
||||
template <typename OrigFuncPtr, OrigFuncPtr origFunc>
|
||||
void hookGdiDcFunction(const char* moduleName, const char* funcName)
|
||||
{
|
||||
@ -154,10 +223,9 @@ namespace CompatGdiDcFunctions
|
||||
// Bitmap functions
|
||||
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, BitBlt);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, CreateCompatibleBitmap);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, CreateDIBitmap);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, CreateDIBSection);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, CreateDiscardableBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, CompatDisplayMode::createCompatibleBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDIBitmap, CompatDisplayMode::createDIBitmap);
|
||||
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, CompatDisplayMode::createDiscardableBitmap);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
||||
@ -179,7 +247,6 @@ namespace CompatGdiDcFunctions
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, PatBlt);
|
||||
|
||||
// Device context functions
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, CreateCompatibleDC);
|
||||
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
|
||||
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user