294 lines
10 KiB
C++
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 |