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;
}
if (m_isPrimary)
{
auto origCaps = DDraw::PrimarySurface::getOrigCaps();
if ((origCaps & DDSCAPS_SYSTEMMEMORY) && !(origCaps & DDSCAPS_FLIP))
{
return true;
}
}
if (m_lockData.empty() ||
!m_lockData[data.DstSubResourceIndex].isSysMemUpToDate ||
Time::qpcToMs(Time::queryPerformanceCounter() - m_lockData[data.DstSubResourceIndex].qpcLastCpuAccess) > 200)

View File

@ -242,8 +242,9 @@ namespace
Input::updateCursor();
});
if (src ? !g_isFullscreen : !g_presentationWindow)
if (!src && !g_presentationWindow)
{
LOG_DEBUG << "Present mode: windowed GDI";
Gdi::Window::present(nullptr);
return;
}
@ -277,7 +278,7 @@ namespace
D3dDdi::SurfaceRepository* repo = nullptr;
if (src)
{
repo = DDraw::DirectDrawSurface::getSurfaceRepository(*frontBuffer);
repo = DDraw::DirectDrawSurface::getSurfaceRepository(*g_tagSurface->getDDS());
}
else
{
@ -300,15 +301,21 @@ namespace
Gdi::Region excludeRegion(mi.rcEmulated);
Gdi::Window::present(excludeRegion);
presentationBlt(*backBuffer, *src);
if (backBuffer)
{
presentationBlt(*backBuffer, *src);
}
if (useFlip)
{
if (g_isExclusiveFullscreen)
{
LOG_DEBUG << "Present mode: exclusive fullscreen flip";
frontBuffer->Flip(frontBuffer, backBuffer, DDFLIP_WAIT);
}
else
{
LOG_DEBUG << "Present mode: borderless fullscreen flip";
*g_deviceWindowPtr = g_presentationWindow;
frontBuffer->Flip(frontBuffer, nullptr, DDFLIP_WAIT);
*g_deviceWindowPtr = g_deviceWindow;
@ -320,12 +327,23 @@ namespace
{
CALL_ORIG_PROC(DirectDrawCreateClipper)(0, &g_clipper.getRef(), nullptr);
}
g_clipper->SetHWnd(g_clipper, 0, g_presentationWindow);
frontBuffer->SetClipper(frontBuffer, g_clipper);
frontBuffer->Blt(frontBuffer, nullptr, backBuffer, nullptr, DDBLT_WAIT, nullptr);
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);
}
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 srcDc = nullptr;
D3dDdi::Resource::setReadOnlyLock(true);
@ -346,6 +364,7 @@ namespace
void updateNow(CompatWeakPtr<IDirectDrawSurface7> src, bool isOverlayOnly)
{
updatePresentationParams();
present(src, isOverlayOnly);
{
@ -545,7 +564,6 @@ namespace DDraw
if (vsyncCount != lastOverlayCheckVsyncCount)
{
updatePresentationParams();
setPresentationWindowTopmost();
Gdi::Cursor::update();
Gdi::Caret::blink();
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);
}
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)
{
D3dDdi::ScopedCriticalSection lock;
std::unique_ptr<HDC__, void(*)(HDC)> virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc);
RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds();
auto fsPresentationWindow = DDraw::RealPrimarySurface::getPresentationWindow();
for (auto window : g_windowZOrder)
{
if (!window->presentationWindow)
if (!window->presentationWindow ||
window->presentationWindow == fsPresentationWindow)
{
continue;
}

View File

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

View File

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