From a45e5768ae829dd2bc69abfec1a546ada8798072 Mon Sep 17 00:00:00 2001 From: narzoul Date: Thu, 22 Aug 2019 12:24:36 +0200 Subject: [PATCH] Restrict lock surfaces to off-screen plain and render target surfaces --- DDrawCompat/D3dDdi/Device.cpp | 81 +++------ DDrawCompat/D3dDdi/Device.h | 13 +- DDrawCompat/D3dDdi/DeviceFuncs.cpp | 3 +- DDrawCompat/D3dDdi/Resource.cpp | 269 ++++++++--------------------- DDrawCompat/D3dDdi/Resource.h | 29 ++-- DDrawCompat/Gdi/Window.cpp | 16 +- 6 files changed, 123 insertions(+), 288 deletions(-) diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index 03559bf..d10be69 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -20,6 +20,8 @@ namespace D3dDdi : m_origVtable(DeviceFuncs::s_origVtables.at(device)) , m_adapter(Adapter::get(adapter)) , m_device(device) + , m_renderTarget(nullptr) + , m_renderTargetSubResourceIndex(0) , m_sharedPrimary(nullptr) , m_streamSourceData{} , m_streamSource(nullptr) @@ -39,7 +41,10 @@ namespace D3dDdi HRESULT Device::clear(const D3DDDIARG_CLEAR& data, UINT numRect, const RECT* rect) { - prepareForRendering(); + if (data.Flags & D3DCLEAR_TARGET) + { + prepareForRendering(); + } return m_origVtable.pfnClear(m_device, &data, numRect, rect); } @@ -59,7 +64,7 @@ namespace D3dDdi try { Resource resource(Resource::create(*this, data)); - m_resources.emplace(resource, std::move(resource)).first->second.initialize(); + m_resources.emplace(resource, std::move(resource)); return S_OK; } catch (const HResultException& e) @@ -99,13 +104,7 @@ namespace D3dDdi HRESULT result = m_origVtable.pfnDestroyResource(m_device, resource); if (SUCCEEDED(result)) { - auto it = m_resources.find(resource); - if (it != m_resources.end()) - { - it->second.destroyLockResource(); - m_resources.erase(it); - } - + m_resources.erase(resource); if (resource == m_sharedPrimary) { m_sharedPrimary = nullptr; @@ -203,6 +202,17 @@ namespace D3dDdi return m_origVtable.pfnPresent1(m_device, &data); } + HRESULT Device::setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data) + { + HRESULT result = m_origVtable.pfnSetRenderTarget(m_device, &data); + if (SUCCEEDED(result) && 0 == data.RenderTargetIndex) + { + m_renderTarget = getResource(data.hRenderTarget); + m_renderTargetSubResourceIndex = data.SubResourceIndex; + } + return result; + } + HRESULT Device::setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data) { HRESULT result = m_origVtable.pfnSetStreamSource(m_device, &data); @@ -225,20 +235,6 @@ namespace D3dDdi return result; } - HRESULT Device::texBlt(const D3DDDIARG_TEXBLT& data) - { - prepareForRendering(data.hDstResource, UINT_MAX, false); - prepareForRendering(data.hSrcResource, UINT_MAX, true); - return m_origVtable.pfnTexBlt(m_device, &data); - } - - HRESULT Device::texBlt1(const D3DDDIARG_TEXBLT1& data) - { - prepareForRendering(data.hDstResource, UINT_MAX, false); - prepareForRendering(data.hSrcResource, UINT_MAX, true); - return m_origVtable.pfnTexBlt1(m_device, &data); - } - HRESULT Device::unlock(const D3DDDIARG_UNLOCK& data) { auto it = m_resources.find(data.hResource); @@ -261,16 +257,6 @@ namespace D3dDdi return m_origVtable.pfnUpdateWInfo(m_device, &data); } - void Device::addDirtyRenderTarget(Resource& resource, UINT subResourceIndex) - { - m_dirtyRenderTargets.emplace(std::make_pair(static_cast(resource), subResourceIndex), resource); - } - - void Device::addDirtyTexture(Resource& resource, UINT subResourceIndex) - { - m_dirtyTextures.emplace(std::make_pair(static_cast(resource), subResourceIndex), resource); - } - Resource* Device::getGdiResource() { return g_gdiResource; @@ -285,33 +271,12 @@ namespace D3dDdi } } - void Device::prepareForRendering(std::map, Resource&>& resources, bool isReadOnly) - { - auto it = resources.begin(); - while (it != resources.end()) - { - auto& resource = it->second; - auto subResourceIndex = it->first.second; - ++it; - resource.prepareForRendering(subResourceIndex, isReadOnly); - } - } - void Device::prepareForRendering() { - const bool isReadOnly = true; - prepareForRendering(m_dirtyRenderTargets, !isReadOnly); - prepareForRendering(m_dirtyTextures, isReadOnly); - } - - void Device::removeDirtyRenderTarget(Resource& resource, UINT subResourceIndex) - { - m_dirtyRenderTargets.erase(std::make_pair(static_cast(resource), subResourceIndex)); - } - - void Device::removeDirtyTexture(Resource& resource, UINT subResourceIndex) - { - m_dirtyTextures.erase(std::make_pair(static_cast(resource), subResourceIndex)); + if (m_renderTarget) + { + m_renderTarget->prepareForRendering(m_renderTargetSubResourceIndex, false); + } } void Device::add(HANDLE adapter, HANDLE device) diff --git a/DDrawCompat/D3dDdi/Device.h b/DDrawCompat/D3dDdi/Device.h index be1875f..7a47d3d 100644 --- a/DDrawCompat/D3dDdi/Device.h +++ b/DDrawCompat/D3dDdi/Device.h @@ -36,10 +36,9 @@ namespace D3dDdi HRESULT openResource(D3DDDIARG_OPENRESOURCE& data); HRESULT present(const D3DDDIARG_PRESENT& data); HRESULT present1(D3DDDIARG_PRESENT1& data); + HRESULT setRenderTarget(const D3DDDIARG_SETRENDERTARGET& data); HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data); HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer); - HRESULT texBlt(const D3DDDIARG_TEXBLT& data); - HRESULT texBlt1(const D3DDDIARG_TEXBLT1& data); HRESULT unlock(const D3DDDIARG_UNLOCK& data); HRESULT updateWInfo(const D3DDDIARG_WINFO& data); @@ -47,12 +46,8 @@ namespace D3dDdi const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; } Resource* getResource(HANDLE resource); - void addDirtyRenderTarget(Resource& resource, UINT subResourceIndex); - void addDirtyTexture(Resource& resource, UINT subResourceIndex); void prepareForRendering(HANDLE resource, UINT subResourceIndex, bool isReadOnly); void prepareForRendering(); - void removeDirtyRenderTarget(Resource& resource, UINT subResourceIndex); - void removeDirtyTexture(Resource& resource, UINT subResourceIndex); static void add(HANDLE adapter, HANDLE device); static Device& get(HANDLE device); @@ -69,14 +64,12 @@ namespace D3dDdi template HRESULT createResourceImpl(Arg& data); - void prepareForRendering(std::map, Resource&>& resources, bool isReadOnly); - const D3DDDI_DEVICEFUNCS& m_origVtable; Adapter& m_adapter; HANDLE m_device; std::unordered_map m_resources; - std::map, Resource&> m_dirtyRenderTargets; - std::map, Resource&> m_dirtyTextures; + Resource* m_renderTarget; + UINT m_renderTargetSubResourceIndex; HANDLE m_sharedPrimary; D3DDDIARG_SETSTREAMSOURCE m_streamSourceData; Resource* m_streamSource; diff --git a/DDrawCompat/D3dDdi/DeviceFuncs.cpp b/DDrawCompat/D3dDdi/DeviceFuncs.cpp index 75b37bc..c4b4366 100644 --- a/DDrawCompat/D3dDdi/DeviceFuncs.cpp +++ b/DDrawCompat/D3dDdi/DeviceFuncs.cpp @@ -54,10 +54,9 @@ namespace D3dDdi vtable.pfnOpenResource = &DEVICE_FUNC(openResource); vtable.pfnPresent = &DEVICE_FUNC(present); vtable.pfnPresent1 = &DEVICE_FUNC(present1); + vtable.pfnSetRenderTarget = &DEVICE_FUNC(setRenderTarget); vtable.pfnSetStreamSource = &DEVICE_FUNC(setStreamSource); vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm); - vtable.pfnTexBlt = &DEVICE_FUNC(texBlt); - vtable.pfnTexBlt1 = &DEVICE_FUNC(texBlt1); vtable.pfnUnlock = &DEVICE_FUNC(unlock); vtable.pfnUpdateWInfo = &DEVICE_FUNC(updateWInfo); } diff --git a/DDrawCompat/D3dDdi/Resource.cpp b/DDrawCompat/D3dDdi/Resource.cpp index b17bf79..7d61819 100644 --- a/DDrawCompat/D3dDdi/Resource.cpp +++ b/DDrawCompat/D3dDdi/Resource.cpp @@ -160,19 +160,9 @@ namespace D3dDdi { if (!resource.m_lockData[subResourceIndex].isSysMemUpToDate) { - if (isReadOnly) - { - resource.copyToSysMem(subResourceIndex); - } - else - { - resource.moveToSysMem(subResourceIndex); - } - } - else if (!isReadOnly && resource.m_lockData[subResourceIndex].isVidMemUpToDate) - { - resource.setVidMemUpToDate(subResourceIndex, false); + resource.copyToSysMem(subResourceIndex); } + resource.m_lockData[subResourceIndex].isVidMemUpToDate &= isReadOnly; data = resource.m_lockData[subResourceIndex].data; pitch = resource.m_lockData[subResourceIndex].pitch; } @@ -187,9 +177,8 @@ namespace D3dDdi : m_device(device) , m_handle(nullptr) , m_origData(data) - , m_lockResource(nullptr) , m_lockBuffer(nullptr, &heapFree) - , m_canCreateLockResource(false) + , m_lockResource(nullptr, ResourceDeleter(device)) { } @@ -235,19 +224,9 @@ namespace D3dDdi auto& lockData = m_lockData[data.SubResourceIndex]; if (!lockData.isSysMemUpToDate) { - if (data.Flags.ReadOnly) - { - copyToSysMem(data.SubResourceIndex); - } - else - { - moveToSysMem(data.SubResourceIndex); - } - } - else if (!data.Flags.ReadOnly && lockData.isVidMemUpToDate) - { - setVidMemUpToDate(data.SubResourceIndex, false); + copyToSysMem(data.SubResourceIndex); } + lockData.isVidMemUpToDate &= data.Flags.ReadOnly; unsigned char* ptr = static_cast(lockData.data); if (data.Flags.AreaValid) @@ -274,7 +253,7 @@ namespace D3dDdi HRESULT Resource::colorFill(const D3DDDIARG_COLORFILL& data) { LOG_FUNC("Resource::colorFill", data); - if (m_lockResource && 0 != m_formatInfo.bytesPerPixel) + if (m_lockResource) { auto& lockData = m_lockData[data.SubResourceIndex]; if (lockData.isSysMemUpToDate) @@ -286,10 +265,7 @@ namespace D3dDdi data.DstRect.right - data.DstRect.left, data.DstRect.bottom - data.DstRect.top, m_formatInfo.bytesPerPixel, colorConvert(m_formatInfo, data.Color)); - if (lockData.isVidMemUpToDate) - { - setVidMemUpToDate(data.SubResourceIndex, false); - } + m_lockData[data.SubResourceIndex].isVidMemUpToDate = false; return LOG_RESULT(S_OK); } } @@ -322,8 +298,14 @@ namespace D3dDdi void Resource::copyToSysMem(UINT subResourceIndex) { - copySubResource(m_lockResource, m_handle, subResourceIndex); - setSysMemUpToDate(subResourceIndex, true); + copySubResource(m_lockResource.get(), m_handle, subResourceIndex); + m_lockData[subResourceIndex].isSysMemUpToDate = true; + } + + void Resource::copyToVidMem(UINT subResourceIndex) + { + copySubResource(m_handle, m_lockResource.get(), subResourceIndex); + m_lockData[subResourceIndex].isVidMemUpToDate = true; } void Resource::createGdiLockResource() @@ -344,8 +326,7 @@ namespace D3dDdi createSysMemResource({ surfaceInfo }); if (m_lockResource) { - setSysMemUpToDate(0, true); - setVidMemUpToDate(0, false); + m_lockData[0].isVidMemUpToDate = false; } else { @@ -355,6 +336,16 @@ namespace D3dDdi void Resource::createLockResource() { + D3DDDI_RESOURCEFLAGS flags = {}; + flags.Value = g_resourceTypeFlags; + flags.RenderTarget = 0; + if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || + 0 == m_formatInfo.bytesPerPixel || + 0 != (m_fixedData.Flags.Value & flags.Value)) + { + return; + } + std::vector surfaceInfo(m_fixedData.SurfCount); for (UINT i = 0; i < m_fixedData.SurfCount; ++i) { @@ -401,7 +392,6 @@ namespace D3dDdi 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) @@ -416,22 +406,18 @@ namespace D3dDdi if (SUCCEEDED(result)) { - m_lockResource = data.hResource; + m_lockResource.reset(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 = true; + m_lockData[i].isVidMemUpToDate = true; } } - m_canCreateLockResource = false; - LOG_RESULT(m_lockResource); - } - - void Resource::copyToVidMem(UINT subResourceIndex) - { - copySubResource(m_handle, m_lockResource, subResourceIndex); - setVidMemUpToDate(subResourceIndex, true); + LOG_RESULT(m_lockResource.get()); } template @@ -460,6 +446,7 @@ namespace D3dDdi } resource.m_handle = data.hResource; + resource.createLockResource(); data = origData; data.hResource = resource.m_handle; return resource; @@ -475,23 +462,6 @@ namespace D3dDdi return create(device, data, device.getOrigVtable().pfnCreateResource2); } - void Resource::destroyLockResource() - { - for (UINT i = 0; i < m_lockData.size(); ++i) - { - setSysMemUpToDate(i, false); - setVidMemUpToDate(i, true); - } - - if (m_lockResource) - { - m_device.getOrigVtable().pfnDestroyResource(m_device, m_lockResource); - m_lockResource = nullptr; - } - - m_lockBuffer.reset(); - } - void Resource::fixVertexData(UINT offset, UINT count, UINT stride) { if (!m_fixedData.Flags.MightDrawFromLocked || @@ -523,21 +493,10 @@ namespace D3dDdi : const_cast(m_fixedData.pSurfList[subResourceIndex].pSysMem); } - void Resource::initialize() + bool Resource::isInSysMem(UINT subResourceIndex) const { - m_canCreateLockResource = D3DDDIPOOL_SYSTEMMEM != m_fixedData.Pool && - 0 != m_formatInfo.bytesPerPixel && - !m_fixedData.Flags.Primary; - - if (m_canCreateLockResource) - { - m_lockData.resize(m_fixedData.SurfCount); - for (std::size_t i = 0; i < m_fixedData.SurfCount; ++i) - { - setSysMemUpToDate(i, true); - setVidMemUpToDate(i, true); - } - } + return D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || + (m_lockResource && m_lockData[subResourceIndex].isSysMemUpToDate); } bool Resource::isOversized() const @@ -558,11 +517,6 @@ namespace D3dDdi return splitLock(data, m_device.getOrigVtable().pfnLock); } - if (m_canCreateLockResource) - { - createLockResource(); - } - if (m_lockResource) { return bltLock(data); @@ -571,55 +525,15 @@ namespace D3dDdi return m_device.getOrigVtable().pfnLock(m_device, &data); } - void Resource::moveToSysMem(UINT subResourceIndex) - { - copySubResource(m_lockResource, m_handle, subResourceIndex); - setSysMemUpToDate(subResourceIndex, true); - setVidMemUpToDate(subResourceIndex, false); - } - - void Resource::moveToVidMem(UINT subResourceIndex) - { - copySubResource(m_handle, m_lockResource, subResourceIndex); - setVidMemUpToDate(subResourceIndex, true); - setSysMemUpToDate(subResourceIndex, false); - } - void Resource::prepareForRendering(UINT subResourceIndex, bool isReadOnly) { - if (subResourceIndex < m_lockData.size()) + if (m_lockResource && 0 == m_lockData[subResourceIndex].lockCount) { - prepareSubResourceForRendering(subResourceIndex, isReadOnly); - } - else if (UINT_MAX == subResourceIndex) - { - for (UINT i = 0; i < m_lockData.size(); ++i) + if (!m_lockData[subResourceIndex].isVidMemUpToDate) { - prepareSubResourceForRendering(i, isReadOnly); - } - } - } - - void Resource::prepareSubResourceForRendering(UINT subResourceIndex, bool isReadOnly) - { - auto& lockData = m_lockData[subResourceIndex]; - if (0 == lockData.lockCount) - { - if (isReadOnly) - { - if (!lockData.isVidMemUpToDate) - { - copyToVidMem(subResourceIndex); - } - } - else if (lockData.isVidMemUpToDate) - { - setSysMemUpToDate(subResourceIndex, false); - } - else - { - moveToVidMem(subResourceIndex); + copyToVidMem(subResourceIndex); } + m_lockData[subResourceIndex].isSysMemUpToDate &= isReadOnly; } } @@ -628,56 +542,22 @@ namespace D3dDdi if (srcResource.m_lockResource && srcResource.m_lockData[data.SrcSubResourceIndex].isSysMemUpToDate) { - copySubResource(srcResource.m_handle, srcResource.m_lockResource, data.SrcSubResourceIndex); - if (!srcResource.m_lockData[data.SrcSubResourceIndex].isVidMemUpToDate) - { - srcResource.setVidMemUpToDate(data.SrcSubResourceIndex, true); - } + srcResource.copyToVidMem(data.SrcSubResourceIndex); } return m_device.getOrigVtable().pfnBlt(m_device, &data); } void Resource::setAsGdiResource(bool isGdiResource) { - destroyLockResource(); + m_lockResource.reset(); + m_lockData.clear(); + m_lockBuffer.reset(); if (isGdiResource) { createGdiLockResource(); } } - void Resource::setSysMemUpToDate(UINT subResourceIndex, bool upToDate) - { - m_lockData[subResourceIndex].isSysMemUpToDate = upToDate; - if (m_fixedData.Flags.RenderTarget) - { - if (upToDate) - { - m_device.addDirtyRenderTarget(*this, subResourceIndex); - } - else - { - m_device.removeDirtyRenderTarget(*this, subResourceIndex); - } - } - } - - void Resource::setVidMemUpToDate(UINT subResourceIndex, bool upToDate) - { - m_lockData[subResourceIndex].isVidMemUpToDate = upToDate; - if (m_fixedData.Flags.Texture) - { - if (upToDate) - { - m_device.removeDirtyTexture(*this, subResourceIndex); - } - else - { - m_device.addDirtyTexture(*this, subResourceIndex); - } - } - } - HRESULT Resource::splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect) { LOG_FUNC("Resource::splitBlt", data, subResourceIndex, rect, otherRect); @@ -742,49 +622,36 @@ namespace D3dDdi HRESULT Resource::sysMemPreferredBlt(const D3DDDIARG_BLT& data, Resource& srcResource) { if (m_fixedData.Format == srcResource.m_fixedData.Format && - 0 != m_formatInfo.bytesPerPixel) + 0 != m_formatInfo.bytesPerPixel && + (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown || + (isInSysMem(data.DstSubResourceIndex) && + (!srcResource.m_fixedData.Flags.RenderTarget || srcResource.isInSysMem(data.SrcSubResourceIndex))))) { - if (data.Flags.MirrorLeftRight || data.Flags.MirrorUpDown) + SysMemBltGuard srcGuard(srcResource, data.SrcSubResourceIndex, true); + if (srcGuard.data) { - if (m_canCreateLockResource) + SysMemBltGuard dstGuard(*this, data.DstSubResourceIndex, false); + if (dstGuard.data) { - createLockResource(); - } - if (srcResource.m_canCreateLockResource) - { - srcResource.createLockResource(); - } - } + auto dstBuf = static_cast(dstGuard.data) + + data.DstRect.top * dstGuard.pitch + data.DstRect.left * m_formatInfo.bytesPerPixel; + auto srcBuf = static_cast(srcGuard.data) + + data.SrcRect.top * srcGuard.pitch + data.SrcRect.left * m_formatInfo.bytesPerPixel; - if (D3DDDIPOOL_SYSTEMMEM == m_fixedData.Pool || - (m_lockResource && m_lockData[data.DstSubResourceIndex].isSysMemUpToDate)) - { - SysMemBltGuard srcGuard(srcResource, data.SrcSubResourceIndex, true); - if (srcGuard.data) - { - SysMemBltGuard dstGuard(*this, data.DstSubResourceIndex, false); - if (dstGuard.data) - { - auto dstBuf = static_cast(dstGuard.data) + - data.DstRect.top * dstGuard.pitch + data.DstRect.left * m_formatInfo.bytesPerPixel; - auto srcBuf = static_cast(srcGuard.data) + - data.SrcRect.top * srcGuard.pitch + data.SrcRect.left * m_formatInfo.bytesPerPixel; + DDraw::Blitter::blt( + dstBuf, + dstGuard.pitch, + data.DstRect.right - data.DstRect.left, + data.DstRect.bottom - data.DstRect.top, + srcBuf, + srcGuard.pitch, + (1 - 2 * data.Flags.MirrorLeftRight) * (data.SrcRect.right - data.SrcRect.left), + (1 - 2 * data.Flags.MirrorUpDown) * (data.SrcRect.bottom - data.SrcRect.top), + m_formatInfo.bytesPerPixel, + data.Flags.DstColorKey ? reinterpret_cast(&data.ColorKey) : nullptr, + data.Flags.SrcColorKey ? reinterpret_cast(&data.ColorKey) : nullptr); - DDraw::Blitter::blt( - dstBuf, - dstGuard.pitch, - data.DstRect.right - data.DstRect.left, - data.DstRect.bottom - data.DstRect.top, - srcBuf, - srcGuard.pitch, - (1 - 2 * data.Flags.MirrorLeftRight) * (data.SrcRect.right - data.SrcRect.left), - (1 - 2 * data.Flags.MirrorUpDown) * (data.SrcRect.bottom - data.SrcRect.top), - m_formatInfo.bytesPerPixel, - data.Flags.DstColorKey ? reinterpret_cast(&data.ColorKey) : nullptr, - data.Flags.SrcColorKey ? reinterpret_cast(&data.ColorKey) : nullptr); - - return S_OK; - } + return S_OK; } } } diff --git a/DDrawCompat/D3dDdi/Resource.h b/DDrawCompat/D3dDdi/Resource.h index fb47c7e..c81d09f 100644 --- a/DDrawCompat/D3dDdi/Resource.h +++ b/DDrawCompat/D3dDdi/Resource.h @@ -18,14 +18,18 @@ namespace D3dDdi static Resource create(Device& device, D3DDDIARG_CREATERESOURCE& data); static Resource create(Device& device, D3DDDIARG_CREATERESOURCE2& data); + Resource(const Resource&) = delete; + Resource& operator=(const Resource&) = delete; + + Resource(Resource&&) = default; + Resource& operator=(Resource&&) = default; + operator HANDLE() const { return m_handle; } HRESULT blt(D3DDDIARG_BLT data); HRESULT colorFill(const D3DDDIARG_COLORFILL& data); - void destroyLockResource(); void fixVertexData(UINT offset, UINT count, UINT stride); void* getLockPtr(UINT subResourceIndex); - void initialize(); HRESULT lock(D3DDDIARG_LOCK& data); void prepareForRendering(UINT subResourceIndex, bool isReadOnly); void setAsGdiResource(bool isGdiResource); @@ -55,6 +59,16 @@ namespace D3dDdi bool isVidMemUpToDate; }; + class ResourceDeleter + { + public: + ResourceDeleter(Device& device) : m_device(device) {} + void operator()(HANDLE resource) { m_device.getOrigVtable().pfnDestroyResource(m_device, resource); } + + private: + Device& m_device; + }; + struct SysMemBltGuard { void* data; @@ -78,12 +92,8 @@ namespace D3dDdi void createLockResource(); void createSysMemResource(const std::vector& surfaceInfo); bool isOversized() const; - void moveToSysMem(UINT subResourceIndex); - void moveToVidMem(UINT subResourceIndex); - void prepareSubResourceForRendering(UINT subResourceIndex, bool isReadOnly); + bool isInSysMem(UINT subResourceIndex) const; HRESULT presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource); - void setSysMemUpToDate(UINT subResourceIndex, bool upToDate); - void setVidMemUpToDate(UINT subResourceIndex, bool upToDate); HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect); template @@ -96,9 +106,8 @@ namespace D3dDdi Data m_origData; Data m_fixedData; FormatInfo m_formatInfo; - HANDLE m_lockResource; - std::vector m_lockData; std::unique_ptr m_lockBuffer; - bool m_canCreateLockResource; + std::vector m_lockData; + std::unique_ptr m_lockResource; }; } diff --git a/DDrawCompat/Gdi/Window.cpp b/DDrawCompat/Gdi/Window.cpp index f6b48d5..2567fda 100644 --- a/DDrawCompat/Gdi/Window.cpp +++ b/DDrawCompat/Gdi/Window.cpp @@ -182,13 +182,15 @@ namespace Gdi if (!preservedRegion.isEmpty()) { - HDC screenDc = Gdi::getScreenDc(); - SelectClipRgn(screenDc, preservedRegion); - BitBlt(screenDc, m_windowRect.left, m_windowRect.top, - oldWindowRect.right - oldWindowRect.left, oldWindowRect.bottom - oldWindowRect.top, - screenDc, oldWindowRect.left, oldWindowRect.top, SRCCOPY); - SelectClipRgn(screenDc, nullptr); - + if (m_windowRect.left != oldWindowRect.left || m_windowRect.top != oldWindowRect.top) + { + HDC screenDc = Gdi::getScreenDc(); + SelectClipRgn(screenDc, preservedRegion); + BitBlt(screenDc, m_windowRect.left, m_windowRect.top, + oldWindowRect.right - oldWindowRect.left, oldWindowRect.bottom - oldWindowRect.top, + screenDc, oldWindowRect.left, oldWindowRect.top, SRCCOPY); + SelectClipRgn(screenDc, nullptr); + } m_invalidatedRegion -= preservedRegion; } }