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

103 lines
2.8 KiB
C
Raw Normal View History

2019-04-23 12:44:13 +02:00
#pragma once
#include <memory>
2019-04-23 12:44:13 +02:00
#include <vector>
#include <d3d.h>
#include <d3dumddi.h>
#include <D3dDdi/FormatInfo.h>
2019-07-26 00:26:44 +02:00
2019-04-23 12:44:13 +02:00
namespace D3dDdi
{
class Device;
class Resource
{
public:
Resource(Device& device, D3DDDIARG_CREATERESOURCE2& data);
2019-04-23 12:44:13 +02:00
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
Resource(Resource&&) = default;
Resource& operator=(Resource&&) = default;
2019-04-23 12:44:13 +02:00
operator HANDLE() const { return m_handle; }
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; }
2019-04-23 12:44:13 +02:00
HRESULT blt(D3DDDIARG_BLT data);
HRESULT colorFill(D3DDDIARG_COLORFILL data);
void* getLockPtr(UINT subResourceIndex);
2019-04-23 12:44:13 +02:00
HRESULT lock(D3DDDIARG_LOCK& data);
void prepareForGdiRendering(bool isReadOnly);
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
void setAsGdiResource(bool isGdiResource);
2019-04-23 12:44:13 +02:00
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
private:
class Data : public D3DDDIARG_CREATERESOURCE2
{
public:
Data(const D3DDDIARG_CREATERESOURCE2& data);
Data(const Data&) = delete;
Data& operator=(const Data&) = delete;
2019-04-23 12:44:13 +02:00
Data(Data&&) = default;
Data& operator=(Data&&) = default;
std::vector<D3DDDI_SURFACEINFO> surfaceData;
};
struct LockData
{
void* data;
UINT pitch;
UINT lockCount;
long long qpcLastForcedLock;
bool isSysMemUpToDate;
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;
};
HRESULT bltLock(D3DDDIARG_LOCK& data);
HRESULT bltUnlock(const D3DDDIARG_UNLOCK& data);
void clipRect(UINT subResourceIndex, RECT& rect);
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);
2019-04-23 12:44:13 +02:00
bool isOversized() const;
bool isValidRect(UINT subResourceIndex, const RECT& rect);
HRESULT presentationBlt(const D3DDDIARG_BLT& data, Resource& srcResource);
2019-04-23 12:44:13 +02:00
HRESULT splitBlt(D3DDDIARG_BLT& data, UINT& subResourceIndex, RECT& rect, RECT& otherRect);
template <typename Arg>
HRESULT splitLock(Arg& data, HRESULT(APIENTRY *lockFunc)(HANDLE, Arg*));
HRESULT sysMemPreferredBlt(const D3DDDIARG_BLT& data, Resource& srcResource);
2019-04-23 12:44:13 +02:00
Device& m_device;
HANDLE m_handle;
Data m_origData;
Data m_fixedData;
2019-07-26 00:26:44 +02:00
FormatInfo m_formatInfo;
std::unique_ptr<void, void(*)(void*)> m_lockBuffer;
std::vector<LockData> m_lockData;
std::unique_ptr<void, ResourceDeleter> m_lockResource;
2019-04-23 12:44:13 +02:00
};
}