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

Fixed windowed presentation

See issue #298.
This commit is contained in:
narzoul 2024-04-28 16:21:49 +02:00
parent e7068b507a
commit 2fe2e03455
5 changed files with 71 additions and 13 deletions

View File

@ -1675,6 +1675,15 @@ namespace D3dDdi
return true; return true;
} }
if (m_isPrimary)
{
auto origCaps = DDraw::PrimarySurface::getOrigCaps();
if ((origCaps & DDSCAPS_SYSTEMMEMORY) && !(origCaps & DDSCAPS_FLIP))
{
return true;
}
}
if (m_lockData.empty() || if (m_lockData.empty() ||
!m_lockData[data.DstSubResourceIndex].isSysMemUpToDate || !m_lockData[data.DstSubResourceIndex].isSysMemUpToDate ||
Time::qpcToMs(Time::queryPerformanceCounter() - m_lockData[data.DstSubResourceIndex].qpcLastCpuAccess) > 200) Time::qpcToMs(Time::queryPerformanceCounter() - m_lockData[data.DstSubResourceIndex].qpcLastCpuAccess) > 200)

View File

@ -242,8 +242,9 @@ namespace
Input::updateCursor(); Input::updateCursor();
}); });
if (src ? !g_isFullscreen : !g_presentationWindow) if (!src && !g_presentationWindow)
{ {
LOG_DEBUG << "Present mode: windowed GDI";
Gdi::Window::present(nullptr); Gdi::Window::present(nullptr);
return; return;
} }
@ -277,7 +278,7 @@ namespace
D3dDdi::SurfaceRepository* repo = nullptr; D3dDdi::SurfaceRepository* repo = nullptr;
if (src) if (src)
{ {
repo = DDraw::DirectDrawSurface::getSurfaceRepository(*frontBuffer); repo = DDraw::DirectDrawSurface::getSurfaceRepository(*g_tagSurface->getDDS());
} }
else else
{ {
@ -300,15 +301,21 @@ namespace
Gdi::Region excludeRegion(mi.rcEmulated); Gdi::Region excludeRegion(mi.rcEmulated);
Gdi::Window::present(excludeRegion); Gdi::Window::present(excludeRegion);
if (backBuffer)
{
presentationBlt(*backBuffer, *src); presentationBlt(*backBuffer, *src);
}
if (useFlip) if (useFlip)
{ {
if (g_isExclusiveFullscreen) if (g_isExclusiveFullscreen)
{ {
LOG_DEBUG << "Present mode: exclusive fullscreen flip";
frontBuffer->Flip(frontBuffer, backBuffer, DDFLIP_WAIT); frontBuffer->Flip(frontBuffer, backBuffer, DDFLIP_WAIT);
} }
else else
{ {
LOG_DEBUG << "Present mode: borderless fullscreen flip";
*g_deviceWindowPtr = g_presentationWindow; *g_deviceWindowPtr = g_presentationWindow;
frontBuffer->Flip(frontBuffer, nullptr, DDFLIP_WAIT); frontBuffer->Flip(frontBuffer, nullptr, DDFLIP_WAIT);
*g_deviceWindowPtr = g_deviceWindow; *g_deviceWindowPtr = g_deviceWindow;
@ -320,12 +327,23 @@ namespace
{ {
CALL_ORIG_PROC(DirectDrawCreateClipper)(0, &g_clipper.getRef(), nullptr); CALL_ORIG_PROC(DirectDrawCreateClipper)(0, &g_clipper.getRef(), nullptr);
} }
g_clipper->SetHWnd(g_clipper, 0, g_presentationWindow);
frontBuffer->SetClipper(frontBuffer, g_clipper); frontBuffer->SetClipper(frontBuffer, g_clipper);
if (g_presentationWindow)
{
LOG_DEBUG << "Present mode: windowed fullscreen blt";
g_clipper->SetHWnd(g_clipper, 0, g_presentationWindow);
frontBuffer->Blt(frontBuffer, nullptr, backBuffer, nullptr, DDBLT_WAIT, nullptr); frontBuffer->Blt(frontBuffer, nullptr, backBuffer, nullptr, DDBLT_WAIT, nullptr);
} }
else else
{ {
LOG_DEBUG << "Present mode: windowed blt";
Gdi::Window::present(*frontBuffer, *src, *g_clipper);
}
}
else
{
LOG_DEBUG << "Present mode: windowed fullscreen GDI";
HDC dstDc = GetWindowDC(g_presentationWindow); HDC dstDc = GetWindowDC(g_presentationWindow);
HDC srcDc = nullptr; HDC srcDc = nullptr;
D3dDdi::Resource::setReadOnlyLock(true); D3dDdi::Resource::setReadOnlyLock(true);
@ -346,6 +364,7 @@ namespace
void updateNow(CompatWeakPtr<IDirectDrawSurface7> src, bool isOverlayOnly) void updateNow(CompatWeakPtr<IDirectDrawSurface7> src, bool isOverlayOnly)
{ {
updatePresentationParams();
present(src, isOverlayOnly); present(src, isOverlayOnly);
{ {
@ -545,7 +564,6 @@ namespace DDraw
if (vsyncCount != lastOverlayCheckVsyncCount) if (vsyncCount != lastOverlayCheckVsyncCount)
{ {
updatePresentationParams(); updatePresentationParams();
setPresentationWindowTopmost();
Gdi::Cursor::update(); Gdi::Cursor::update();
Gdi::Caret::blink(); Gdi::Caret::blink();
auto statsWindow = Gdi::GuiThread::getStatsWindow(); auto statsWindow = Gdi::GuiThread::getStatsWindow();

View File

@ -554,15 +554,32 @@ namespace Gdi
RedrawWindow(hwnd, &emptyRect, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ERASENOW); RedrawWindow(hwnd, &emptyRect, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ERASENOW);
} }
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
CompatRef<IDirectDrawClipper> clipper)
{
D3dDdi::ScopedCriticalSection lock;
auto mr = DDraw::PrimarySurface::getMonitorInfo().rcEmulated;
for (auto window : g_windowZOrder)
{
if (window->presentationWindow && !window->visibleRegion.isEmpty())
{
clipper->SetHWnd(&clipper, 0, window->presentationWindow);
dst->Blt(&dst, &mr, &src, nullptr, DDBLT_WAIT, nullptr);
}
}
}
void present(Gdi::Region excludeRegion) void present(Gdi::Region excludeRegion)
{ {
D3dDdi::ScopedCriticalSection lock; D3dDdi::ScopedCriticalSection lock;
std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc); std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc);
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds(); RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();
auto fsPresentationWindow = DDraw::RealPrimarySurface::getPresentationWindow();
for (auto window : g_windowZOrder) for (auto window : g_windowZOrder)
{ {
if (!window->presentationWindow) if (!window->presentationWindow ||
window->presentationWindow == fsPresentationWindow)
{ {
continue; continue;
} }

View File

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <ddraw.h>
#include <Common/CompatRef.h>
#include <Gdi/Region.h> #include <Gdi/Region.h>
namespace Gdi namespace Gdi
@ -27,6 +30,8 @@ namespace Gdi
bool isTopLevelWindow(HWND hwnd); bool isTopLevelWindow(HWND hwnd);
void onStyleChanged(HWND hwnd, WPARAM wParam); void onStyleChanged(HWND hwnd, WPARAM wParam);
void onSyncPaint(HWND hwnd); void onSyncPaint(HWND hwnd);
void present(CompatRef<IDirectDrawSurface7> dst, CompatRef<IDirectDrawSurface7> src,
CompatRef<IDirectDrawClipper> clipper);
void present(Gdi::Region excludeRegion); void present(Gdi::Region excludeRegion);
void setDpiAwareness(HWND hwnd, bool dpiAware); void setDpiAwareness(HWND hwnd, bool dpiAware);
void updateAll(); void updateAll();

View File

@ -227,9 +227,12 @@ namespace
{ {
Compat::ScopedCriticalSection lock(g_cs); Compat::ScopedCriticalSection lock(g_cs);
if (lpDevMode) if (lpDevMode)
{
if (lpDevMode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT))
{ {
g_emulatedDisplayMode.width = emulatedResolution.cx; g_emulatedDisplayMode.width = emulatedResolution.cx;
g_emulatedDisplayMode.height = emulatedResolution.cy; g_emulatedDisplayMode.height = emulatedResolution.cy;
}
if (lpDevMode->dmFields & DM_BITSPERPEL) if (lpDevMode->dmFields & DM_BITSPERPEL)
{ {
g_emulatedDisplayMode.bpp = lpDevMode->dmBitsPerPel; g_emulatedDisplayMode.bpp = lpDevMode->dmBitsPerPel;
@ -322,9 +325,12 @@ namespace
if (getDeviceName(lpszDeviceName) == g_emulatedDisplayMode.deviceName) if (getDeviceName(lpszDeviceName) == g_emulatedDisplayMode.deviceName)
{ {
lpDevMode->dmBitsPerPel = g_emulatedDisplayMode.bpp; lpDevMode->dmBitsPerPel = g_emulatedDisplayMode.bpp;
if (0 != g_emulatedDisplayMode.width)
{
lpDevMode->dmPelsWidth = g_emulatedDisplayMode.width; lpDevMode->dmPelsWidth = g_emulatedDisplayMode.width;
lpDevMode->dmPelsHeight = g_emulatedDisplayMode.height; lpDevMode->dmPelsHeight = g_emulatedDisplayMode.height;
} }
}
else else
{ {
lpDevMode->dmBitsPerPel = g_desktopBpp; lpDevMode->dmBitsPerPel = g_desktopBpp;
@ -693,9 +699,12 @@ namespace
mi.rcEmulated = mi.rcMonitor; mi.rcEmulated = mi.rcMonitor;
if (g_emulatedDisplayMode.deviceName == mi.szDevice) if (g_emulatedDisplayMode.deviceName == mi.szDevice)
{
if (0 != g_emulatedDisplayMode.width)
{ {
mi.rcEmulated.right = mi.rcEmulated.left + g_emulatedDisplayMode.width; mi.rcEmulated.right = mi.rcEmulated.left + g_emulatedDisplayMode.width;
mi.rcEmulated.bottom = mi.rcEmulated.top + g_emulatedDisplayMode.height; mi.rcEmulated.bottom = mi.rcEmulated.top + g_emulatedDisplayMode.height;
}
mi.bpp = g_emulatedDisplayMode.bpp; mi.bpp = g_emulatedDisplayMode.bpp;
mi.isEmulated = true; mi.isEmulated = true;
} }