windows-nt/Source/XPSP1/NT/public/sdk/inc/dxsurfb.h
2020-09-26 16:20:57 +08:00

294 lines
10 KiB
C++

/*******************************************************************************
* DXSurfB.h *
*----------*
* Description:
* This is the header file for the CDXBaseSurface implementation. It is
* used as a base class to implement read-only procedural DXSurfaces.
*-------------------------------------------------------------------------------
* Created By: RAL Date: 02/12/1998
* Copyright (C) 1998 Microsoft Corporation
* All Rights Reserved
*
*-------------------------------------------------------------------------------
* Revisions:
*
*******************************************************************************/
#ifndef __DXSurfB_H__
#define __DXSurfB_H__
#include "dtbase.h"
class CDXBaseSurface;
class CDXBaseARGBPtr;
class ATL_NO_VTABLE CDXBaseSurface :
public CDXBaseNTo1,
public IDXSurface,
public IDXSurfaceInit
{
/*=== ATL Setup ===*/
public:
BEGIN_COM_MAP(CDXBaseSurface)
COM_INTERFACE_ENTRY(IDXSurface)
COM_INTERFACE_ENTRY(IDXSurfaceInit)
COM_INTERFACE_ENTRY_CHAIN(CDXBaseNTo1)
END_COM_MAP()
DECLARE_GET_CONTROLLING_UNKNOWN()
/*=== Member Data ===*/
public:
ULONG m_Height;
ULONG m_Width;
DWORD m_dwStatusFlags;
HANDLE m_hSemaphore;
ULONG m_ulLocks;
ULONG m_ulThreadsWaiting;
CDXBaseARGBPtr *m_pFreePtr;
DWORD_PTR m_dwAppData;
CComAutoCriticalSection m_MPWorkProcCrit; // See comments in LockSurface for details
CDXBaseSurface();
HRESULT FinalConstruct();
void FinalRelease();
//
// IDXBaseObject
//
STDMETHODIMP GetGenerationId(ULONG *pGenId);
STDMETHODIMP IncrementGenerationId(BOOL bRefresh);
STDMETHODIMP GetObjectSize(ULONG *pulze);
//
// Overridden methods of DXTransform
//
STDMETHODIMP MapBoundsIn2Out(const DXBNDS *pInBounds, ULONG ulNumInBnds,
ULONG /*ulOutIndex*/, DXBNDS *pOutBounds );
//
// IDXSurfaceInit
//
STDMETHODIMP InitSurface(IUnknown *pDirectDraw,
const DDSURFACEDESC * pDDSurfaceDesc,
const GUID * pFormatId,
const DXBNDS *pBounds,
DWORD dwFlags);
//
// IDXSurface methods
//
STDMETHODIMP GetPixelFormat(GUID *pFormat, DXSAMPLEFORMATENUM *pSampleEnum);
STDMETHODIMP GetBounds(DXBNDS *pBounds);
STDMETHODIMP GetStatusFlags(DWORD * pdwStatusFlags);
STDMETHODIMP SetStatusFlags(DWORD dwStatusFlags);
STDMETHODIMP GetDirectDrawSurface(REFIID riid, void **ppSurface);
STDMETHODIMP LockSurface(const DXBNDS *pBounds, ULONG ulTimeOut, DWORD dwFlags,
REFIID riid, void **ppPointer, DWORD * pGenerationId);
STDMETHODIMP SetAppData(DWORD_PTR dwAppData)
{
m_dwAppData = dwAppData;
return S_OK;
}
STDMETHODIMP GetAppData(DWORD_PTR *pdwAppData)
{
if (DXIsBadWritePtr(pdwAppData, sizeof(*pdwAppData)))
{
return E_POINTER;
}
*pdwAppData = m_dwAppData;
return S_OK;
}
//
// These methods aren't supported by procedural surfaces...
//
STDMETHODIMP GetColorKey(DXSAMPLE *pColorKey)
{
return E_NOTIMPL;
}
STDMETHODIMP SetColorKey(DXSAMPLE pColorKey)
{
return E_NOTIMPL;
}
STDMETHODIMP LockSurfaceDC(const DXBNDS *pBounds, ULONG ulTimeOut, DWORD dwFlags, IDXDCLock **ppDXLock)
{
return E_NOTIMPL;
}
//
// Surfaces should override this.
//
virtual ULONG OnGetObjectSize(void) { return sizeof(*this); }
//
// This work procedure can be overridden by the derived class to improve performance
// or execution of the transform by directly producing data in large blocks if desired.
//
virtual HRESULT WorkProc(const CDXTWorkInfoNTo1 & WI, BOOL* pbContinueProcessing)
{
return DXBitBlt(OutputSurface(), WI.OutputBnds, this, WI.DoBnds, m_dwBltFlags, m_ulLockTimeOut);
}
//
// Pick interface needs to test procedural surface.
//
virtual HRESULT OnSurfacePick(const CDXDBnds & OutPoint, ULONG & ulInputIndex, CDXDVec & InVec);
//
// Helper functions
//
// _EnterCritWith0PtrLocks()
//
// This function is similar to calling Lock() except that it will wait until there
// are no pointers to the surface before returning. This should be used whenever you
// are going to change the state of a surface, for example the size or some other
// property that the read pointers rely on.
//
// WARNING: You must be sure that one of the following is true:
// 1) The objects critical section has NOT been taken prior to calling this function
// or 2) There are no pointers to the surface taken prior to calling this function.
//
// Case 2 is useful in nested function calls. If the outer function has already used this
// function to enter the critical section, then it is OK to use it on the inner nested
// function. If the object's lock is taken, but there are outstanding pointers, YOU WILL DEADLOCK!
//
inline void _EnterCritWith0PtrLocks(void)
{
while (TRUE)
{
Lock();
if (m_ulLocks == 0) break;
m_ulThreadsWaiting++;
Unlock();
WaitForSingleObject(m_hSemaphore, INFINITE);
}
}
//
// Virtual functions derived class MUST override
//
virtual const GUID & SurfaceCLSID() = 0;
virtual HRESULT CreateARGBPointer(CDXBaseSurface * pSurface, CDXBaseARGBPtr ** ppPtr) = 0;
virtual void DeleteARGBPointer(CDXBaseARGBPtr *pPtr) = 0;
//
// Class may override this virtual function to return a more accurate enum
// for example, no transparency or translucency.
//
virtual DXSAMPLEFORMATENUM SampleFormatEnum()
{
return (DXSAMPLEFORMATENUM)(DXPF_NONSTANDARD | DXPF_TRANSPARENCY | DXPF_TRANSLUCENCY);
}
//
// Class may override this virtual function to perform necessary computations
// when the size of the surface changes. The base class will only call this
// function from InitSurface. You may choose to call it from other interfaces
// you implement, for example IDXTScaleOutput.
//
// This function will be called with the critical section taken and 0 outstanding
// surface pointers (_EnterCritWith0PtrLocks).
//
virtual HRESULT OnSetSize(ULONG Width, ULONG Height)
{
if (m_Width != Width || m_Height != Height)
{
m_Width = Width;
m_Height = Height;
m_dwGenerationId++;
}
return S_OK;
}
//
// Internal functions for base class
//
void _InternalUnlock(CDXBaseARGBPtr *pPtrToUnlock);
//
// Static member function for registering surface
//
static HRESULT RegisterSurface(REFCLSID rcid, int ResourceId, ULONG cCatImpl, const CATID * pCatImpl,
ULONG cCatReq, const CATID * pCatReq, BOOL bRegister);
};
struct DXPtrFillInfo
{
DXBASESAMPLE * pSamples;
ULONG cSamples;
ULONG x;
ULONG y;
BOOL bPremult;
};
class CDXBaseARGBPtr : public IDXARGBReadPtr
{
public:
CDXBaseARGBPtr * m_pNext;
CDXBaseSurface * m_pSurface;
ULONG m_ulRefCount;
DXPtrFillInfo m_FillInfo;
RECT m_LockedRect;
DXRUNINFO m_RunInfo;
CDXBaseARGBPtr(CDXBaseSurface *pSurface) :
m_pSurface(pSurface),
m_pNext(NULL),
m_ulRefCount(0) {}
//
// IUnknown
//
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
//
// IDXARGBReadPtr
//
HRESULT STDMETHODCALLTYPE GetSurface(REFIID riid, void **ppSurface);
DXSAMPLEFORMATENUM STDMETHODCALLTYPE GetNativeType(DXNATIVETYPEINFO *pInfo);
void STDMETHODCALLTYPE Move(long cSamples);
void STDMETHODCALLTYPE MoveToRow(ULONG y);
void STDMETHODCALLTYPE MoveToXY(ULONG x, ULONG y);
ULONG STDMETHODCALLTYPE MoveAndGetRunInfo(ULONG Row, const DXRUNINFO ** ppInfo);
DXSAMPLE *STDMETHODCALLTYPE Unpack(DXSAMPLE *pSamples, ULONG cSamples, BOOL bMove);
DXPMSAMPLE *STDMETHODCALLTYPE UnpackPremult(DXPMSAMPLE *pSamples, ULONG cSamples, BOOL bMove);
void STDMETHODCALLTYPE UnpackRect(const DXPACKEDRECTDESC *pDesc);
//
// Virtual function derived class MUST override
//
virtual void FillSamples(const DXPtrFillInfo & FillInfo) = 0;
//
// Virtual functions derived class MAY want to override (but you will need to call the base class too)
//
virtual HRESULT InitFromLock(const RECT & rect, ULONG ulTimeOut, DWORD dwLockFlags, REFIID riid, void ** ppv);
};
//=== Macro Definitions ============================================
#define DECLARE_REGISTER_DX_SURFACE(id)\
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) \
{ \
CATID cat[2]; \
cat[0] = CATID_DXSurface; \
cat[1] = CATID_DXImageTransform; \
return RegisterSurface(GetObjectCLSID(), (id), 2, cat, 0, NULL, bRegister); \
}
#define DECLARE_REGISTER_DX_AUTHORING_SURFACE(id)\
static HRESULT WINAPI UpdateRegistry(BOOL bRegister) \
{ \
CATID cat[3]; \
cat[0] = CATID_DXSurface; \
cat[1] = CATID_DXImageTransform; \
cat[2] = CATID_DXAuthoringTransform; \
return RegisterSurface(GetObjectCLSID(), (id), 3, cat, 0, NULL, bRegister); \
}
#endif