mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved lock surface handling to UMD level
This commit is contained in:
parent
9b24a9b306
commit
8cc73dc68d
@ -12,23 +12,6 @@ namespace
|
||||
HANDLE g_gdiResourceHandle = nullptr;
|
||||
D3dDdi::Resource* g_gdiResource = nullptr;
|
||||
bool g_isReadOnlyGdiLockEnabled = false;
|
||||
|
||||
template <typename Container, typename Predicate>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
#include <type_traits>
|
||||
|
||||
#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 <Common/HResultException.h>
|
||||
#include <Common/Log.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <D3dDdi/Log/DeviceFuncsLog.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <DDraw/Blitter.h>
|
||||
#include <Gdi/VirtualScreen.h>
|
||||
|
||||
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<D3DDDI_SURFACEINFO> 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<D3DDDI_SURFACEINFO>& 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<D3DDDIARG_CREATERESOURCE*>(&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<void*>(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<void*>(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;
|
||||
|
@ -4,15 +4,9 @@
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
#include <ddraw.h>
|
||||
|
||||
#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 <typename Arg>
|
||||
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<D3DDDI_SURFACEINFO>& 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<LockData> m_lockData;
|
||||
std::vector<std::vector<BYTE>> m_lockBuffers;
|
||||
bool m_canCreateLockResource;
|
||||
};
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
namespace
|
||||
{
|
||||
CompatWeakPtr<IDirectDrawSurface7> g_primarySurface;
|
||||
std::vector<CompatWeakPtr<IDirectDrawSurface7>> 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<TSurface> 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<TSurface> lockBuffer;
|
||||
dd->CreateSurface(&dd, &desc, &lockBuffer.getRef(), nullptr);
|
||||
if (lockBuffer)
|
||||
{
|
||||
g_lockBackBuffers.push_back(CompatPtr<IDirectDrawSurface7>::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();
|
||||
|
@ -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<IDirectDrawSurface7> dds, std::unique_ptr<Surface> 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 <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
HRESULT Surface::create(
|
||||
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData)
|
||||
@ -125,32 +72,16 @@ namespace DDraw
|
||||
surface7->GetPixelFormat(surface7, &desc.ddpfPixelFormat);
|
||||
}
|
||||
|
||||
privateData->m_lockSurface = privateData->createLockSurface<TDirectDraw, TSurface>(dd, desc);
|
||||
if (privateData->m_lockSurface)
|
||||
{
|
||||
attach(*privateData->m_lockSurface, std::make_unique<Surface>(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<Surface>(privateData.get()));
|
||||
privateData->m_attachedSurfaces.push_back(data.get());
|
||||
attach(*attachedSurfaces[i], std::move(data));
|
||||
attach(*attachedSurfaces[i], std::make_unique<Surface>());
|
||||
}
|
||||
}
|
||||
|
||||
Surface* rootSurface = privateData.get();
|
||||
attach(*surface7, std::move(privateData));
|
||||
rootSurface->restore();
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -184,28 +115,6 @@ namespace DDraw
|
||||
template <>
|
||||
SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl<IDirectDrawSurface7>() const { return m_impl7.get(); }
|
||||
|
||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
CompatPtr<IDirectDrawSurface7> Surface::createLockSurface(CompatRef<TDirectDraw> 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<TSurface> lockSurface;
|
||||
dd->CreateSurface(&dd, &desc, &lockSurface.getRef(), nullptr);
|
||||
return LOG_RESULT(lockSurface);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
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<IDirectDrawSurface7> lockSurface)
|
||||
{
|
||||
if (lockSurface)
|
||||
{
|
||||
auto resource = D3dDdi::Device::getResource(getDriverResourceHandle(*m_surface));
|
||||
if (resource)
|
||||
{
|
||||
resource->setLockResource(D3dDdi::Device::getResource(getDriverResourceHandle(*lockSurface)));
|
||||
resource->setRootSurface(m_rootSurface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace DDraw
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef();
|
||||
virtual ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
Surface(Surface* rootSurface = nullptr);
|
||||
Surface();
|
||||
virtual ~Surface();
|
||||
|
||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
@ -33,7 +33,6 @@ namespace DDraw
|
||||
template <typename TSurface>
|
||||
SurfaceImpl<TSurface>* getImpl() const;
|
||||
|
||||
void clearResources();
|
||||
virtual void restore();
|
||||
|
||||
protected:
|
||||
@ -49,22 +48,11 @@ namespace DDraw
|
||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface7>> m_impl7;
|
||||
|
||||
CompatWeakPtr<IDirectDrawSurface7> m_surface;
|
||||
std::vector<Surface*> m_attachedSurfaces;
|
||||
CompatPtr<IDirectDrawSurface7> m_lockSurface;
|
||||
std::vector<CompatWeakPtr<IDirectDrawSurface7>> m_attachedLockSurfaces;
|
||||
|
||||
private:
|
||||
template <typename TDirectDrawSurface>
|
||||
friend class SurfaceImpl;
|
||||
template <typename TDirectDrawSurface>
|
||||
friend class SurfaceImpl2;
|
||||
|
||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
CompatPtr<IDirectDrawSurface7> createLockSurface(CompatRef<TDirectDraw> dd, TSurfaceDesc desc);
|
||||
|
||||
void setResources(CompatWeakPtr<IDirectDrawSurface7> lockSurface);
|
||||
|
||||
DWORD m_refCount;
|
||||
Surface* m_rootSurface;
|
||||
};
|
||||
}
|
||||
|
@ -210,34 +210,34 @@ namespace Gdi
|
||||
{
|
||||
D3dDdi::ScopedCriticalSection driverLock;
|
||||
D3dDdi::Device::setGdiResourceHandle(nullptr);
|
||||
}
|
||||
|
||||
g_region = Region();
|
||||
EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast<LPARAM>(&g_region));
|
||||
GetRgnBox(g_region, &g_bounds);
|
||||
g_region = Region();
|
||||
EnumDisplayMonitors(nullptr, nullptr, addMonitorRectToRegion, reinterpret_cast<LPARAM>(&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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user