windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/d3d8/fw/volume.hpp
2020-09-26 16:20:57 +08:00

196 lines
5.5 KiB
C++

#ifndef __VOLUME_HPP__
#define __VOLUME_HPP__
/*==========================================================================;
*
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
*
* File: volume.hpp
* Content: Class header the volume class. This class acts
* as a level for the MipVolume class. The base class
* assumes a system-memory allocation; while the
* Driver sub-class will call the driver for every
* lock and unlock operation.
*
*
***************************************************************************/
// Includes
#include "mipvol.hpp"
//
// Each Volume implements the IDirect3DVolume8 interface.
// To reduce overhead per level, we have
// put most of the "real" guts of each volume into the MipVolume container
// class; i.e. most of the methods of the Volume really just end
// up calling something in the MipVolume object.
//
// The base class implementation assumes a sys-mem allocation.
//
//
// The CVolume class is a special class that
// works solely with the CMipVolume class. Each Volume
// corresponds to a single level of the mip-volume. They are
// not stand-alone COM objects because they share the
// same life-time as their CMipVolume parent.
//
// The CDriverVolume class is declared later in this file
//
class CVolume : public IDirect3DVolume8
{
public:
// Constructor
CVolume(CMipVolume *pParent,
BYTE iLevel,
HANDLE hKernelHandle
) :
m_pParent(pParent),
m_isLocked(FALSE),
m_iLevel(iLevel),
m_hKernelHandle(hKernelHandle)
{
DXGASSERT(pParent);
DXGASSERT(hKernelHandle || (pParent->GetUserPool() == D3DPOOL_SCRATCH) );
#ifdef DEBUG
m_cRefDebug = 0;
#endif // DEBUG
if (m_pParent->Desc()->Usage &
(D3DUSAGE_LOCK | D3DUSAGE_LOADONCE))
{
m_isLockable = TRUE;
}
else
{
m_isLockable = FALSE;
}
return;
} // CVolume
~CVolume()
{
DXGASSERT(m_cRefDebug == 0);
if (m_pParent->GetUserPool() != D3DPOOL_SCRATCH)
{
// Tell the thunk layer that we need to
// be freed.
DXGASSERT(m_hKernelHandle);
D3D8_DESTROYSURFACEDATA DestroySurfData;
DestroySurfData.hDD = m_pParent->Device()->GetHandle();
DestroySurfData.hSurface = m_hKernelHandle;
m_pParent->Device()->GetHalCallbacks()->DestroySurface(&DestroySurfData);
}
#ifdef DEBUG
else
{
DXGASSERT(m_pParent->GetUserPool() == D3DPOOL_SCRATCH);
}
#endif //DEBUG
}; // ~CVolume
public:
// IUnknown methods
STDMETHOD(QueryInterface) (REFIID riid,
VOID **ppvObj);
STDMETHOD_(ULONG,AddRef) ();
STDMETHOD_(ULONG,Release) ();
// IBuffer methods
STDMETHOD(SetPrivateData)(REFGUID riid,
CONST VOID *pvData,
DWORD cbData,
DWORD dwFlags);
STDMETHOD(GetPrivateData)(REFGUID riid,
VOID *pvData,
DWORD *pcbData);
STDMETHOD(FreePrivateData)(REFGUID riid);
STDMETHOD(GetContainer)(REFIID riid,
void **ppContainer);
STDMETHOD(GetDevice)(IDirect3DDevice8 **ppDevice);
// IDirect3DVolume8 methods
STDMETHOD(GetDesc)(D3DVOLUME_DESC *pDesc);
STDMETHOD(LockBox)(D3DLOCKED_BOX *pLockedBox,
CONST D3DBOX *pBox,
DWORD dwFlags);
STDMETHOD(UnlockBox)(void);
virtual HRESULT InternalLockBox(D3DLOCKED_BOX *pLockedBox,
CONST D3DBOX *pBox,
DWORD dwFlags);
virtual HRESULT InternalUnlockBox();
BOOL IsLocked() const
{
return m_isLocked;
} // IsLocked
protected:
CMipVolume *m_pParent;
BOOL m_isLocked;
BOOL m_isLockable;
BYTE m_iLevel;
// We'll need internal handles so that
// we can communicate call Destroy
// and so that CDriverVolume can call
// Lock/Unlock etc.
HANDLE m_hKernelHandle;
CBaseDevice * Device() const
{
return m_pParent->Device();
} // Device
// Debugging trick to help spew better
// information if someone over-releases a volume
// (Since our ref's carry over to the parent object; it
// means that over-releases can be hard to find.)
#ifdef DEBUG
DWORD m_cRefDebug;
#endif // DEBUG
}; // CVolume
// The CDriverVolume is a modification of the base volume
// class. It overrides lock and unlock and routes the call to the
// driver
class CDriverVolume : public CVolume
{
public:
// Constructor
CDriverVolume(CMipVolume *pParent,
BYTE iLevel,
HANDLE hKernelHandle
) :
CVolume(pParent, iLevel, hKernelHandle)
{
} // CDriverVolume
public:
STDMETHOD(LockBox)(D3DLOCKED_BOX *pLockedBox,
CONST D3DBOX *pBox,
DWORD dwFlags);
STDMETHOD(UnlockBox)();
virtual HRESULT InternalLockBox(D3DLOCKED_BOX *pLockedBox,
CONST D3DBOX *pBox,
DWORD dwFlags);
virtual HRESULT InternalUnlockBox();
}; // CDriverVolume
#endif // __VOLUME_HPP__