From 8cc73dc68d91cfadb566d6c3c8a04c6a4fa0761a Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 11 Aug 2019 22:29:36 +0200 Subject: [PATCH] Moved lock surface handling to UMD level --- DDrawCompat/D3dDdi/Device.cpp | 42 ++-- DDrawCompat/D3dDdi/Resource.cpp | 223 ++++++++++-------- DDrawCompat/D3dDdi/Resource.h | 23 +- DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp | 37 --- DDrawCompat/DDraw/Surfaces/Surface.cpp | 117 +-------- DDrawCompat/DDraw/Surfaces/Surface.h | 14 +- DDrawCompat/Gdi/VirtualScreen.cpp | 44 ++-- 7 files changed, 179 insertions(+), 321 deletions(-) diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index e08d9aa..fe6e23b 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -12,23 +12,6 @@ namespace HANDLE g_gdiResourceHandle = nullptr; D3dDdi::Resource* g_gdiResource = nullptr; bool g_isReadOnlyGdiLockEnabled = false; - - template - void erase_if(Container& container, Predicate pred) - { - auto it = container.begin(); - while (it != container.end()) - { - if (pred(*it)) - { - it = container.erase(it); - } - else - { - ++it; - } - } - } } namespace D3dDdi @@ -116,15 +99,10 @@ namespace D3dDdi HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource); if (SUCCEEDED(result)) { - erase_if(m_dirtyRenderTargets, - [=](const decltype(m_dirtyRenderTargets)::value_type& v) { return v.first.first == resource; }); - erase_if(m_dirtyTextures, - [=](const decltype(m_dirtyTextures)::value_type& v) { return v.first.first == resource; }); - auto it = m_resources.find(resource); if (it != m_resources.end()) { - it->second.destroy(); + it->second.destroyLockResource(); m_resources.erase(it); } @@ -374,11 +352,23 @@ namespace D3dDdi void Device::setGdiResourceHandle(HANDLE resource) { - g_gdiResourceHandle = resource; - g_gdiResource = getResource(resource); + if ((!resource && !g_gdiResource) || + (g_gdiResource && resource == *g_gdiResource)) + { + return; + } + if (g_gdiResource) { - g_gdiResource->resync(); + g_gdiResource->setAsGdiResource(false); + } + + g_gdiResourceHandle = resource; + g_gdiResource = getResource(resource); + + if (g_gdiResource) + { + g_gdiResource->setAsGdiResource(true); } } diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index 6ce0ca0..a0df88e 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -1,13 +1,14 @@ #include -#include "Common/HResultException.h" -#include "Common/Log.h" -#include "D3dDdi/Adapter.h" -#include "D3dDdi/Device.h" -#include "D3dDdi/Log/DeviceFuncsLog.h" -#include "D3dDdi/Resource.h" -#include "DDraw/Blitter.h" -#include "DDraw/Surfaces/Surface.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { @@ -181,8 +182,8 @@ namespace D3dDdi : m_device(device) , m_handle(nullptr) , m_origData(data) - , m_rootSurface(nullptr) , m_lockResource(nullptr) + , m_canCreateLockResource(false) { } @@ -297,11 +298,11 @@ namespace D3dDdi return LOG_RESULT(m_device.getOrigVtable().pfnColorFill(m_device, &data)); } - HRESULT Resource::copySubResource(Resource& dstResource, Resource& srcResource, UINT subResourceIndex) + HRESULT Resource::copySubResource(HANDLE dstResource, HANDLE srcResource, UINT subResourceIndex) { RECT rect = {}; - rect.right = dstResource.m_fixedData.pSurfList[subResourceIndex].Width; - rect.bottom = dstResource.m_fixedData.pSurfList[subResourceIndex].Height; + rect.right = m_fixedData.pSurfList[subResourceIndex].Width; + rect.bottom = m_fixedData.pSurfList[subResourceIndex].Height; D3DDDIARG_BLT data = {}; data.hSrcResource = srcResource; @@ -311,7 +312,7 @@ namespace D3dDdi data.DstSubResourceIndex = subResourceIndex; data.DstRect = rect; - HRESULT result = dstResource.m_device.getOrigVtable().pfnBlt(dstResource.m_device, &data); + HRESULT result = m_device.getOrigVtable().pfnBlt(m_device, &data); if (FAILED(result)) { LOG_ONCE("ERROR: Resource::copySubResource failed: " << Compat::hex(result)); @@ -321,13 +322,97 @@ namespace D3dDdi void Resource::copyToSysMem(UINT subResourceIndex) { - copySubResource(*m_lockResource, *this, subResourceIndex); + copySubResource(m_lockResource, m_handle, subResourceIndex); setSysMemUpToDate(subResourceIndex, true); } + void Resource::createGdiLockResource() + { + auto gdiSurfaceDesc(Gdi::VirtualScreen::getSurfaceDesc(D3dDdi::KernelModeThunks::getMonitorRect())); + if (!gdiSurfaceDesc.lpSurface) + { + return; + } + + D3DDDI_SURFACEINFO surfaceInfo = {}; + surfaceInfo.Width = gdiSurfaceDesc.dwWidth; + surfaceInfo.Height = gdiSurfaceDesc.dwHeight; + surfaceInfo.pSysMem = gdiSurfaceDesc.lpSurface; + surfaceInfo.SysMemPitch = gdiSurfaceDesc.lPitch; + + createSysMemResource({ surfaceInfo }); + if (m_lockResource) + { + copySubResource(m_handle, m_lockResource, 0); + m_canCreateLockResource = false; + } + } + + void Resource::createLockResource() + { + std::vector surfaceInfo(m_fixedData.SurfCount); + m_lockBuffers.resize(m_fixedData.SurfCount); + + for (UINT i = 0; i < m_fixedData.SurfCount; ++i) + { + auto width = m_fixedData.pSurfList[i].Width; + auto height = m_fixedData.pSurfList[i].Height; + auto pitch = divCeil(width * m_formatInfo.bytesPerPixel, 8) * 8; + m_lockBuffers[i].resize(pitch * height); + + surfaceInfo[i].Width = width; + surfaceInfo[i].Height = height; + surfaceInfo[i].pSysMem = m_lockBuffers[i].data(); + surfaceInfo[i].SysMemPitch = pitch; + } + + createSysMemResource(surfaceInfo); + if (!m_lockResource) + { + m_lockBuffers.clear(); + } + } + + void Resource::createSysMemResource(const std::vector& surfaceInfo) + { + D3DDDIARG_CREATERESOURCE2 data = {}; + data.Format = m_fixedData.Format; + data.Pool = D3DDDIPOOL_SYSTEMMEM; + data.pSurfList = surfaceInfo.data(); + data.SurfCount = surfaceInfo.size(); + data.Rotation = D3DDDI_ROTATION_IDENTITY; + data.Flags.Texture = m_fixedData.Flags.Texture; + + HRESULT result = S_OK; + if (m_device.getOrigVtable().pfnCreateResource2) + { + result = m_device.getOrigVtable().pfnCreateResource2(m_device, &data); + } + else + { + result = m_device.getOrigVtable().pfnCreateResource(m_device, + reinterpret_cast(&data)); + } + + if (FAILED(result)) + { + return; + } + + m_lockResource = data.hResource; + m_lockData.resize(surfaceInfo.size()); + for (std::size_t i = 0; i < surfaceInfo.size(); ++i) + { + m_lockData[i].data = const_cast(surfaceInfo[i].pSysMem); + m_lockData[i].pitch = surfaceInfo[i].SysMemPitch; + m_lockData[i].isSysMemUpToDate = false; + m_lockData[i].isVidMemUpToDate = true; + } + } + void Resource::copyToVidMem(UINT subResourceIndex) { - copySubResource(*this, *m_lockResource, subResourceIndex); + copySubResource(m_handle, m_lockResource, subResourceIndex); setVidMemUpToDate(subResourceIndex, true); } @@ -357,6 +442,9 @@ namespace D3dDdi } resource.m_handle = data.hResource; + resource.m_canCreateLockResource = D3DDDIPOOL_SYSTEMMEM != data.Pool && + 0 != resource.m_formatInfo.bytesPerPixel && + !data.Flags.Primary; data = origData; data.hResource = resource.m_handle; return resource; @@ -372,11 +460,19 @@ namespace D3dDdi return create(device, data, device.getOrigVtable().pfnCreateResource2); } - void Resource::destroy() + void Resource::destroyLockResource() { - if (m_rootSurface) + if (m_lockResource) { - m_rootSurface->clearResources(); + for (UINT i = 0; i < m_lockData.size(); ++i) + { + setSysMemUpToDate(i, false); + setVidMemUpToDate(i, true); + } + m_device.getOrigVtable().pfnDestroyResource(m_device, m_lockResource); + m_lockResource = nullptr; + m_lockData.clear(); + m_lockBuffers.clear(); } } @@ -435,7 +531,14 @@ namespace D3dDdi } return splitLock(data, m_device.getOrigVtable().pfnLock); } - else if (m_lockResource) + + if (m_canCreateLockResource) + { + createLockResource(); + m_canCreateLockResource = false; + } + + if (m_lockResource) { return bltLock(data); } @@ -445,14 +548,14 @@ namespace D3dDdi void Resource::moveToSysMem(UINT subResourceIndex) { - copySubResource(*m_lockResource, *this, subResourceIndex); + copySubResource(m_lockResource, m_handle, subResourceIndex); setSysMemUpToDate(subResourceIndex, true); setVidMemUpToDate(subResourceIndex, false); } void Resource::moveToVidMem(UINT subResourceIndex) { - copySubResource(*this, *m_lockResource, subResourceIndex); + copySubResource(m_handle, m_lockResource, subResourceIndex); setVidMemUpToDate(subResourceIndex, true); setSysMemUpToDate(subResourceIndex, false); } @@ -503,7 +606,7 @@ namespace D3dDdi { if (srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate) { - copySubResource(srcResource, *srcResource.m_lockResource, data.SrcSubResourceIndex); + copySubResource(srcResource.m_handle, srcResource.m_lockResource, data.SrcSubResourceIndex); } } else @@ -514,83 +617,15 @@ namespace D3dDdi return m_device.getOrigVtable().pfnBlt(m_device, &data); } - void Resource::resync() + void Resource::setAsGdiResource(bool isGdiResource) { - if (!m_lockData.empty() && m_lockData[0].isSysMemUpToDate) + destroyLockResource(); + if (isGdiResource) { - copySubResource(*this, *m_lockResource, 0); - if (!m_lockData[0].isVidMemUpToDate) - { - setVidMemUpToDate(0, true); - } + createGdiLockResource(); } } - void Resource::setLockResource(Resource* lockResource) - { - if (!m_lockResource == !lockResource) - { - return; - } - - if (lockResource) - { - if (lockResource->m_fixedData.SurfCount != m_fixedData.SurfCount) - { - LOG_ONCE("ERROR: Lock surface count mismatch: " << - m_fixedData.surfaceData << " vs " << lockResource->m_fixedData.SurfCount); - return; - } - m_lockData.resize(m_fixedData.SurfCount); - for (UINT i = 0; i < m_fixedData.SurfCount; ++i) - { - m_lockData[i].data = const_cast(lockResource->m_fixedData.pSurfList[i].pSysMem); - m_lockData[i].pitch = lockResource->m_fixedData.pSurfList[i].SysMemPitch; - m_lockData[i].isSysMemUpToDate = true; - m_lockData[i].isVidMemUpToDate = true; - } - - m_lockResource = lockResource; - if (m_fixedData.Flags.RenderTarget) - { - for (std::size_t i = 0; i < m_lockData.size(); ++i) - { - m_device.addDirtyRenderTarget(*this, i); - } - } - } - else - { - if (m_fixedData.Flags.RenderTarget) - { - for (std::size_t i = 0; i < m_lockData.size(); ++i) - { - if (m_lockData[i].isSysMemUpToDate) - { - m_device.removeDirtyRenderTarget(*this, i); - } - } - } - if (m_fixedData.Flags.Texture) - { - for (std::size_t i = 0; i < m_lockData.size(); ++i) - { - if (!m_lockData[i].isVidMemUpToDate) - { - m_device.removeDirtyTexture(*this, i); - } - } - } - m_lockResource = nullptr; - m_lockData.clear(); - } - } - - void Resource::setRootSurface(DDraw::Surface* rootSurface) - { - m_rootSurface = rootSurface; - } - void Resource::setSysMemUpToDate(UINT subResourceIndex, bool upToDate) { m_lockData[subResourceIndex].isSysMemUpToDate = upToDate; diff --git a/DDrawCompat/D3dDdi/Resource.h b/DDrawCompat/D3dDdi/Resource.h index 676b73d..62c3826 100644 --- a/DDrawCompat/D3dDdi/Resource.h +++ b/DDrawCompat/D3dDdi/Resource.h @@ -4,15 +4,9 @@ #include #include -#include #include "D3dDdi/FormatInfo.h" -namespace DDraw -{ - class Surface; -} - namespace D3dDdi { class Device; @@ -27,14 +21,12 @@ namespace D3dDdi HRESULT blt(D3DDDIARG_BLT data); HRESULT colorFill(const D3DDDIARG_COLORFILL& data); - void destroy(); + void destroyLockResource(); void fixVertexData(UINT offset, UINT count, UINT stride); void* getLockPtr(UINT subResourceIndex); HRESULT lock(D3DDDIARG_LOCK& data); void prepareForRendering(UINT subResourceIndex, bool isReadOnly); - void resync(); - void setLockResource(Resource* lockResource); - void setRootSurface(DDraw::Surface* rootSurface); + void setAsGdiResource(bool isGdiResource); HRESULT unlock(const D3DDDIARG_UNLOCK& data); private: @@ -72,15 +64,17 @@ namespace D3dDdi Resource(Device& device, const D3DDDIARG_CREATERESOURCE& data); Resource(Device& device, const D3DDDIARG_CREATERESOURCE2& data); - static HRESULT copySubResource(Resource& dstResource, Resource& srcResource, UINT subResourceIndex); - template static Resource create(Device& device, Arg& data, HRESULT(APIENTRY *createResourceFunc)(HANDLE, Arg*)); HRESULT bltLock(D3DDDIARG_LOCK& data); HRESULT bltUnlock(const D3DDDIARG_UNLOCK& data); + HRESULT copySubResource(HANDLE dstResource, HANDLE srcResource, UINT subResourceIndex); void copyToSysMem(UINT subResourceIndex); void copyToVidMem(UINT subResourceIndex); + void createGdiLockResource(); + void createLockResource(); + void createSysMemResource(const std::vector& surfaceInfo); bool isOversized() const; void moveToSysMem(UINT subResourceIndex); void moveToVidMem(UINT subResourceIndex); @@ -100,8 +94,9 @@ namespace D3dDdi Data m_origData; Data m_fixedData; FormatInfo m_formatInfo; - DDraw::Surface* m_rootSurface; - Resource* m_lockResource; + HANDLE m_lockResource; std::vector m_lockData; + std::vector> m_lockBuffers; + bool m_canCreateLockResource; }; } diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp index 59e2e25..8933dd7 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurface.cpp @@ -14,7 +14,6 @@ namespace { CompatWeakPtr g_primarySurface; - std::vector> g_lockBackBuffers; HANDLE g_gdiResourceHandle = nullptr; HANDLE g_frontResource = nullptr; DWORD g_origCaps = 0; @@ -32,12 +31,6 @@ namespace DDraw g_origCaps = 0; s_palette = nullptr; - for (auto& lockBuffer : g_lockBackBuffers) - { - lockBuffer.release(); - } - g_lockBackBuffers.clear(); - DDraw::RealPrimarySurface::release(); } @@ -71,30 +64,6 @@ namespace DDraw } g_origCaps = origCaps; - - data->m_lockSurface.release(); - data->m_attachedLockSurfaces.clear(); - - desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS; - desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - CompatPtr lockSurface; - dd->CreateSurface(&dd, &desc, &lockSurface.getRef(), nullptr); - data->m_lockSurface = lockSurface; - - if (g_origCaps & DDSCAPS_FLIP) - { - for (std::size_t i = 0; i < desc.dwBackBufferCount; ++i) - { - CompatPtr lockBuffer; - dd->CreateSurface(&dd, &desc, &lockBuffer.getRef(), nullptr); - if (lockBuffer) - { - g_lockBackBuffers.push_back(CompatPtr::from(lockBuffer.get()).detach()); - data->m_attachedLockSurfaces.push_back(g_lockBackBuffers.back()); - } - } - } - data->restore(); return DD_OK; } @@ -211,13 +180,7 @@ namespace DDraw { LOG_FUNC("PrimarySurface::restore"); - clearResources(); - Gdi::VirtualScreen::update(); - auto desc = Gdi::VirtualScreen::getSurfaceDesc(D3dDdi::KernelModeThunks::getMonitorRect()); - desc.dwFlags &= ~DDSD_CAPS; - m_lockSurface->SetSurfaceDesc(m_lockSurface, &desc, 0); - g_primarySurface = m_surface; g_gdiResourceHandle = getRuntimeResourceHandle(*g_primarySurface); updateFrontResource(); diff --git a/DDrawCompat/DDraw/Surfaces/Surface.cpp b/DDrawCompat/DDraw/Surfaces/Surface.cpp index f0584f1..d9c83b0 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.cpp +++ b/DDrawCompat/DDraw/Surfaces/Surface.cpp @@ -33,46 +33,13 @@ namespace DDraw return refCount; } - Surface::Surface(Surface* rootSurface) + Surface::Surface() : m_refCount(0) - , m_rootSurface(rootSurface ? rootSurface : this) { } Surface::~Surface() { - clearResources(); - if (m_rootSurface != this) - { - auto it = std::find(m_rootSurface->m_attachedSurfaces.begin(), - m_rootSurface->m_attachedSurfaces.end(), this); - if (it != m_rootSurface->m_attachedSurfaces.end()) - { - m_rootSurface->m_attachedSurfaces.erase(it); - } - - if (m_rootSurface->m_lockSurface == m_surface) - { - m_rootSurface->m_lockSurface.detach(); - m_rootSurface->m_attachedLockSurfaces.clear(); - } - } - else - { - for (auto attachedSurface : m_attachedSurfaces) - { - attachedSurface->m_rootSurface = attachedSurface; - } - - if (m_lockSurface) - { - auto lockSurface(getSurface(*m_lockSurface)); - if (lockSurface) - { - lockSurface->m_rootSurface = lockSurface; - } - } - } } void Surface::attach(CompatRef dds, std::unique_ptr privateData) @@ -86,26 +53,6 @@ namespace DDraw } } - void Surface::clearResources() - { - if (!m_surface) - { - return; - } - - auto resource = D3dDdi::Device::getResource(getDriverResourceHandle(*m_surface)); - if (resource) - { - resource->setLockResource(nullptr); - resource->setRootSurface(nullptr); - } - - for (auto attachedSurface : m_attachedSurfaces) - { - attachedSurface->clearResources(); - } - } - template HRESULT Surface::create( CompatRef dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr privateData) @@ -125,32 +72,16 @@ namespace DDraw surface7->GetPixelFormat(surface7, &desc.ddpfPixelFormat); } - privateData->m_lockSurface = privateData->createLockSurface(dd, desc); - if (privateData->m_lockSurface) - { - attach(*privateData->m_lockSurface, std::make_unique(privateData.get())); - } - if (desc.ddsCaps.dwCaps & DDSCAPS_COMPLEX) { auto attachedSurfaces(getAllAttachedSurfaces(*surface7)); - if (privateData->m_lockSurface) - { - auto attachedLockSurfaces(getAllAttachedSurfaces(*privateData->m_lockSurface)); - privateData->m_attachedLockSurfaces.assign(attachedLockSurfaces.begin(), attachedLockSurfaces.end()); - } - for (DWORD i = 0; i < attachedSurfaces.size(); ++i) { - auto data(std::make_unique(privateData.get())); - privateData->m_attachedSurfaces.push_back(data.get()); - attach(*attachedSurfaces[i], std::move(data)); + attach(*attachedSurfaces[i], std::make_unique()); } } - Surface* rootSurface = privateData.get(); attach(*surface7, std::move(privateData)); - rootSurface->restore(); return result; } @@ -184,28 +115,6 @@ namespace DDraw template <> SurfaceImpl* Surface::getImpl() const { return m_impl7.get(); } - template - CompatPtr Surface::createLockSurface(CompatRef dd, TSurfaceDesc desc) - { - LOG_FUNC("Surface::createLockSurface", dd, desc); - - if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) || - !(desc.ddpfPixelFormat.dwFlags & DDPF_RGB) || - 0 == desc.ddpfPixelFormat.dwRGBBitCount || - desc.ddpfPixelFormat.dwRGBBitCount > 32 || - 0 != (desc.ddpfPixelFormat.dwRGBBitCount % 8)) - { - return LOG_RESULT(nullptr); - } - - desc.ddsCaps.dwCaps &= ~(DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM); - desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; - - CompatPtr lockSurface; - dd->CreateSurface(&dd, &desc, &lockSurface.getRef(), nullptr); - return LOG_RESULT(lockSurface); - } - template Surface* Surface::getSurface(TSurface& dds) { @@ -228,27 +137,5 @@ namespace DDraw void Surface::restore() { - setResources(m_lockSurface); - if (m_lockSurface) - { - for (std::size_t i = 0; i < m_attachedSurfaces.size(); ++i) - { - m_attachedSurfaces[i]->setResources( - i < m_attachedLockSurfaces.size() ? m_attachedLockSurfaces[i] : nullptr); - } - } - } - - void Surface::setResources(CompatWeakPtr lockSurface) - { - if (lockSurface) - { - auto resource = D3dDdi::Device::getResource(getDriverResourceHandle(*m_surface)); - if (resource) - { - resource->setLockResource(D3dDdi::Device::getResource(getDriverResourceHandle(*lockSurface))); - resource->setRootSurface(m_rootSurface); - } - } } } diff --git a/DDrawCompat/DDraw/Surfaces/Surface.h b/DDrawCompat/DDraw/Surfaces/Surface.h index 8885fd3..17729e1 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.h +++ b/DDrawCompat/DDraw/Surfaces/Surface.h @@ -20,7 +20,7 @@ namespace DDraw virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); - Surface(Surface* rootSurface = nullptr); + Surface(); virtual ~Surface(); template @@ -33,7 +33,6 @@ namespace DDraw template SurfaceImpl* getImpl() const; - void clearResources(); virtual void restore(); protected: @@ -49,22 +48,11 @@ namespace DDraw std::unique_ptr> m_impl7; CompatWeakPtr m_surface; - std::vector m_attachedSurfaces; - CompatPtr m_lockSurface; - std::vector> m_attachedLockSurfaces; private: template friend class SurfaceImpl; - template - friend class SurfaceImpl2; - - template - CompatPtr createLockSurface(CompatRef dd, TSurfaceDesc desc); - - void setResources(CompatWeakPtr lockSurface); DWORD m_refCount; - Surface* m_rootSurface; }; } diff --git a/DDrawCompat/Gdi/VirtualScreen.cpp b/DDrawCompat/Gdi/VirtualScreen.cpp index 3e9c29f..8a2cfbb 100644 --- a/DDrawCompat/Gdi/VirtualScreen.cpp +++ b/DDrawCompat/Gdi/VirtualScreen.cpp @@ -210,34 +210,34 @@ namespace Gdi { D3dDdi::ScopedCriticalSection driverLock; D3dDdi::Device::setGdiResourceHandle(nullptr); - } - g_region = Region(); - EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast(&g_region)); - GetRgnBox(g_region, &g_bounds); + g_region = Region(); + EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast(&g_region)); + GetRgnBox(g_region, &g_bounds); - g_bpp = bpp; - g_width = g_bounds.right - g_bounds.left; - g_height = g_bounds.bottom - g_bounds.top; - g_pitch = (g_width * g_bpp / 8 + 3) & ~3; + g_bpp = bpp; + g_width = g_bounds.right - g_bounds.left; + g_height = g_bounds.bottom - g_bounds.top; + g_pitch = (g_width * g_bpp / 8 + 3) & ~3; + + if (g_surfaceFileMapping) + { + for (HDC dc : g_dcs) + { + DeleteObject(SelectObject(dc, g_stockBitmap)); + } + UnmapViewOfFile(g_surfaceView); + CloseHandle(g_surfaceFileMapping); + } + + g_surfaceFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, + g_pitch * (g_height + Config::virtualScreenBufferExtraRows), nullptr); + g_surfaceView = MapViewOfFile(g_surfaceFileMapping, FILE_MAP_WRITE, 0, 0, 0); - if (g_surfaceFileMapping) - { for (HDC dc : g_dcs) { - DeleteObject(SelectObject(dc, g_stockBitmap)); + SelectObject(dc, createDib()); } - UnmapViewOfFile(g_surfaceView); - CloseHandle(g_surfaceFileMapping); - } - - g_surfaceFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, - g_pitch * (g_height + Config::virtualScreenBufferExtraRows), nullptr); - g_surfaceView = MapViewOfFile(g_surfaceFileMapping, FILE_MAP_WRITE, 0, 0, 0); - - for (HDC dc : g_dcs) - { - SelectObject(dc, createDib()); } Gdi::redraw(nullptr);