Windows2003-3790/inetcore/published/inc/dtbase.cpp
2020-09-30 16:53:55 +02:00

1682 lines
56 KiB
C++

/*******************************************************************************
* DTBase.cpp *
*------------*
* Description:
* This module contains the CDXBaseNTo1 transform
*-------------------------------------------------------------------------------
* Created By: Edward W. Connell Date: 07/28/97
* Copyright (C) 1997 Microsoft Corporation
* All Rights Reserved
*
*-------------------------------------------------------------------------------
* Revisions:
*
*******************************************************************************/
//--- Additional includes
#include <DXTrans.h>
#include "DTBase.h"
#include "new.h"
//--- Initialize static member of debug scope class
#ifdef _DEBUG
CDXTDbgFlags CDXTDbgScope::m_DebugFlags;
#endif
//--- This should only be used locally in this file. We duplicated this GUID
// value to avoid having to include DDraw.
static const IID IID_IDXDupDirectDraw =
{ 0x6C14DB80,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
static const IID IID_IDXDupDDrawSurface =
{ 0x6C14DB81,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
static const IID IID_IDXDupDirect3DRM =
{0x2bc49361, 0x8327, 0x11cf, {0xac, 0x4a, 0x0, 0x0, 0xc0, 0x38, 0x25, 0xa1 } };
static const IID IID_IDXDupDirect3DRM3 =
{0x4516ec83, 0x8f20, 0x11d0, {0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3 } };
static const IID IID_IDXDupDirect3DRMMeshBuilder3 =
{ 0x4516ec82, 0x8f20, 0x11d0, { 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3} };
HRESULT CDXDataPtr::Assign(BOOL bMesh, IUnknown * pObject, IDXSurfaceFactory *pSurfaceFactory)
{
HRESULT hr = S_OK;
if (pObject)
{
IUnknown *pNative = NULL;
if (!bMesh)
{
//--- Try to get a DX surface
hr = pObject->QueryInterface( IID_IDXSurface, (void **)&pNative );
if( FAILED( hr ) )
{
IDirectDrawSurface *pSurf;
//--- Try to get a DDraw surface
hr = pObject->QueryInterface( IID_IDXDupDDrawSurface, (void **)&pSurf );
if( SUCCEEDED( hr ) )
{
//--- Create a DXSurface from the DDraw surface
hr = pSurfaceFactory->CreateFromDDSurface(
pSurf, NULL, 0, NULL, IID_IDXSurface,
(void **)&pNative );
pSurf->Release();
}
}
}
else // Must be a mesh builder
{
hr = pObject->QueryInterface(IID_IDXDupDirect3DRMMeshBuilder3, (void **)&pNative);
}
if (SUCCEEDED(hr))
{
Release();
m_pNativeInterface = pNative;
pObject->AddRef();
m_pUnkOriginalObject = pObject;
if (SUCCEEDED(pNative->QueryInterface(IID_IDXBaseObject, (void **)&m_pBaseObj)))
{
m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId);
m_dwLastDirtyGenId--;
}
if (!bMesh)
{
((IDXSurface *)pNative)->GetPixelFormat(NULL, &m_SampleFormat);
}
}
else
{
if (hr == E_NOINTERFACE)
{
hr = E_INVALIDARG;
}
}
}
else
{
Release();
}
return hr;
} /* CDXDataPtr::Assign */
bool CDXDataPtr::IsDirty(void)
{
if (m_pBaseObj)
{
DWORD dwOldId = m_dwLastDirtyGenId;
m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId);
return dwOldId != m_dwLastDirtyGenId;
}
else
{
return false;
}
}
DWORD CDXDataPtr::GenerationId(void)
{
if (m_pBaseObj)
{
DWORD dwGenId;
m_pBaseObj->GetGenerationId(&dwGenId);
return dwGenId;
}
else
{
return 0;
}
}
bool CDXDataPtr::UpdateGenerationId(void)
{
if (m_pBaseObj)
{
DWORD dwOldId = m_dwLastUpdGenId;
m_pBaseObj->GetGenerationId(&m_dwLastUpdGenId);
return dwOldId != m_dwLastUpdGenId;
}
else
{
return false;
}
} /* CDXDataPtr::UpdateGenerationId */
ULONG CDXDataPtr::ObjectSize(void)
{
ULONG ulSize = 0;
if (m_pBaseObj)
{
m_pBaseObj->GetObjectSize(&ulSize);
}
return ulSize;
}
/*****************************************************************************
* CDXBaseNTo1::CDXBaseNTo1 *
*--------------------------*
* Description:
* Constructor
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
CDXBaseNTo1::CDXBaseNTo1() :
m_aInputs(NULL),
m_ulNumInputs(0),
m_ulNumProcessors(1), // Default to one until task manager is set
m_dwGenerationId(1),
m_dwCleanGenId(0),
m_Duration(1.0f),
m_StepResolution(0.0f),
m_Progress(0.0f),
m_dwBltFlags(0),
m_bPickDoneByBase(false),
m_bInMultiThreadWorkProc(FALSE),
m_fQuality(0.5f), // Default to normal quality.
// Wait forever before timing out on a lock by default
m_ulLockTimeOut(INFINITE),
//
// Override these flags if your object does not support one or more of these options.
// Typically, 3-D effects should set this member to 0.
//
m_dwMiscFlags(DXTMF_BLEND_WITH_OUTPUT | DXTMF_DITHER_OUTPUT |
DXTMF_BLEND_SUPPORTED | DXTMF_DITHER_SUPPORTED | DXTMF_BOUNDS_SUPPORTED | DXTMF_PLACEMENT_SUPPORTED),
//
// If your object has a different number of objects or a different number of
// required objects than 1, simply set these members in the body of your
// constructor or in FinalConstruct(). For every input that is > the number
// required, that input will be reported as optional.
//
// If your transform takes 2 required inputs, set both to 2.
// If your transform takes 2 optional inputs, set MaxInputs = 2, NumInRequired = 0
// If your transform takes 1 required and 2 optional inputs,
// set MaxInputs = 2, NumInRequired = 1
//
// For more complex combinations of optinal/required, you will need to override
// the OnSetup method of this base class, and override the methods
// GetInOutInfo
//
m_ulMaxInputs(1),
m_ulNumInRequired(1),
//
// If the intputs or output types are not surfaces then set appropriate object type
//
m_dwOptionFlags(0), // Inputs and output are surfaces, don't have to be the same size
m_ulMaxImageBands(DXB_MAX_IMAGE_BANDS),
m_fIsSetup(false)
{
DXTDBG_FUNC( "CDXBaseNTo1::CDXBaseNTo1" );
//
// Set event handles to NULL.
//
memset(m_aEvent, 0, sizeof(m_aEvent));
} /* CDXBaseNTo1::CDXBaseNTo1 */
/*****************************************************************************
* CDXBaseNTo1::~CDXBaseNTo1 *
*---------------------------*
* Description:
* Constructor
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
CDXBaseNTo1::~CDXBaseNTo1()
{
DXTDBG_FUNC( "CDXBaseNTo1::~CDXBaseNTo1" );
_ReleaseReferences();
delete[] m_aInputs;
//--- Release event objects
for(ULONG i = 0; i < DXB_MAX_IMAGE_BANDS; ++i )
{
if( m_aEvent[i] ) ::CloseHandle( m_aEvent[i] );
}
} /* CDXBaseNTo1::~CDXBaseNTo1 */
/*****************************************************************************
* CDXBaseNTo1::_ReleaseRefernces *
*--------------------------------*
* Description:
* Releases all references to input and output objects
*-----------------------------------------------------------------------------
* Created By: RAL
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
void CDXBaseNTo1::_ReleaseReferences()
{
//--- Release data objects
if( m_aInputs )
{
for( ULONG i = 0; i < m_ulNumInputs; ++i )
{
m_aInputs[i].Release();
}
}
m_Output.Release();
m_fIsSetup = false;
} /* CDXBaseNTo1::_ReleaseRefernces */
STDMETHODIMP CDXBaseNTo1::GetGenerationId(ULONG *pGenerationId)
{
DXTDBG_FUNC( "CDXBaseNTo1::GetGenerationId" );
if (DXIsBadWritePtr(pGenerationId, sizeof(*pGenerationId)))
{
return E_POINTER;
}
Lock();
OnUpdateGenerationId();
*pGenerationId = m_dwGenerationId;
Unlock();
return S_OK;
}
STDMETHODIMP CDXBaseNTo1::IncrementGenerationId(BOOL bRefresh)
{
DXTDBG_FUNC( "CDXBaseNTo1::IncrementGenerationId" );
HRESULT hr = S_OK;
Lock();
m_dwGenerationId++;
if (bRefresh)
{
//
// If we have any inputs or outputs, call Setup again to refresh all internal
// knowledge about the surfaces (formats, height or width could change, etc.)
//
// Note that we need to AddRef the objects prior to calling Setup becuase the
// DXTransform may be the only object holding a referec
//
ULONG cInputs = m_ulNumInputs;
ULONG cOutputs = 0;
IUnknown *pOutput = m_Output.m_pUnkOriginalObject;
if (pOutput)
{
cOutputs = 1;
pOutput->AddRef();
}
IUnknown ** ppInputs = NULL;
if (cInputs)
{
ppInputs = (IUnknown **)_alloca(m_ulNumInputs * sizeof(IUnknown *));
for (ULONG i = 0; i < cInputs; i++)
{
ppInputs[i] = m_aInputs[i].m_pUnkOriginalObject;
if (ppInputs[i]) ppInputs[i]->AddRef();
}
}
if (cInputs || cOutputs) // If we're not setup, skip this step.
{
hr = Setup(ppInputs, cInputs, &pOutput, cOutputs, 0);
if (pOutput) pOutput->Release();
for (ULONG i = 0; i < cInputs; i++)
{
if (ppInputs[i]) ppInputs[i]->Release();
}
}
}
Unlock();
return hr;
}
STDMETHODIMP CDXBaseNTo1::GetObjectSize(ULONG *pcbSize)
{
DXTDBG_FUNC( "CDXBaseNTo1::GetObjectSize" );
HRESULT hr = S_OK;
if (DXIsBadWritePtr(pcbSize, sizeof(*pcbSize)))
{
hr = E_POINTER;
}
else
{
Lock();
*pcbSize = OnGetObjectSize();
Unlock();
}
return hr;
}
void CDXBaseNTo1::_ReleaseServices(void)
{
m_cpTransFact.Release();
m_cpSurfFact.Release();
m_cpTaskMgr.Release();
m_cpDirectDraw.Release();
m_cpDirect3DRM.Release();
}
//
// The documentation for SetSite indicates that it is invaid to return
// an error from this function, even if the site does not support the
// functionality we want. So, even if there is no service provider, or
// the required services are not available, we will return S_OK.
//
STDMETHODIMP CDXBaseNTo1::SetSite(IUnknown * pUnkSite)
{
DXTDBG_FUNC( "CDXBaseNTo1::SetSite" );
HRESULT hr = S_OK;
Lock();
m_cpUnkSite = pUnkSite;
_ReleaseServices();
if (pUnkSite)
{
if (DXIsBadInterfacePtr(pUnkSite))
{
hr = E_INVALIDARG;
}
else
{
HRESULT hr2;
hr2 = pUnkSite->QueryInterface(IID_IDXTransformFactory, (void **)&m_cpTransFact);
if (SUCCEEDED(hr2))
{
//
// Allocate memory for inputs if necessary
//
if (m_aInputs == NULL && m_ulMaxInputs)
{
m_aInputs = new CDXDataPtr[m_ulMaxInputs];
if (!m_aInputs)
{
_ASSERT(TRUE);
hr2 = E_OUTOFMEMORY;
}
}
hr2 = m_cpTransFact->QueryService( SID_SDXSurfaceFactory, IID_IDXSurfaceFactory, (void **)&m_cpSurfFact);
if (SUCCEEDED(hr2))
{
hr2 = m_cpTransFact->QueryService( SID_SDXTaskManager, IID_IDXTaskManager, (void **)&m_cpTaskMgr);
}
if (SUCCEEDED(hr2))
{
m_cpTaskMgr->QueryNumProcessors(&m_ulNumProcessors);
if (m_ulMaxImageBands && (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)) == 0)
{
for (ULONG i = 0; SUCCEEDED(hr2) && i < m_ulMaxImageBands; i++)
{
//
// In theory we could get back here after failing to create an event, or
// by getting a new site, so make sure it's non-null before creating one.
//
if (m_aEvent[i] == NULL)
{
m_aEvent[i] = ::CreateEvent(NULL, true, false, NULL);
if (m_aEvent[i] == NULL)
{
hr2 = E_OUTOFMEMORY;
}
}
}
}
}
if (SUCCEEDED(hr2))
{
hr2 = m_cpTransFact->QueryService(SID_SDirectDraw, IID_IDXDupDirectDraw, (void**)&m_cpDirectDraw);
}
if (SUCCEEDED(hr2) &&
(m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)))
{
hr2 = m_cpTransFact->QueryService(SID_SDirect3DRM, IID_IDXDupDirect3DRM3, (void **)&m_cpDirect3DRM);
}
if (FAILED(hr2))
{
_ASSERT(TRUE);
_ReleaseServices();
}
}
}
}
Unlock();
return hr;
}
STDMETHODIMP CDXBaseNTo1::GetSite(REFIID riid, void **ppv)
{
DXTDBG_FUNC( "CDXBaseNTo1::GetSite" );
HRESULT hr = S_OK;
if( DXIsBadWritePtr(ppv, sizeof(*ppv)) )
{
hr = E_POINTER;
}
else
{
Lock();
if (m_cpUnkSite)
{
hr = m_cpUnkSite->QueryInterface(riid, ppv);
}
else
{
*ppv = NULL;
hr = E_FAIL; // This is the proper documented return code
// for this interface if no service provider.
}
Unlock();
}
return hr;
}
void CDXBaseNTo1::_UpdateBltFlags(void)
{
m_dwBltFlags = 0;
if ((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) == 0)
{
if (m_dwMiscFlags & DXTMF_BLEND_WITH_OUTPUT)
{
if ((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) || m_ulNumInputs == 0)
{
m_dwBltFlags |= DXBOF_DO_OVER;
}
else
{
for(ULONG i = 0; i < m_ulNumInputs; ++i )
{
if (InputSampleFormat(i) & DXPF_TRANSPARENCY)
{
m_dwBltFlags |= DXBOF_DO_OVER;
break;
}
}
}
}
//
// Set the dither flag to true only if output error is > at least one input
//
if (m_dwMiscFlags & DXTMF_DITHER_OUTPUT)
{
ULONG OutputErr = (OutputSampleFormat() & DXPF_ERRORMASK);
if (OutputErr)
{
if (m_ulNumInputs)
{
for(ULONG i = 0; i < m_ulNumInputs; ++i )
{
if (InputSurface(i) && (ULONG)(InputSampleFormat(i) & DXPF_ERRORMASK) < OutputErr)
{
m_dwBltFlags |= DXBOF_DITHER;
break;
}
}
}
else
{
//
// If output has no error then don't set dither in blt flags
//
if (OutputErr)
{
m_dwBltFlags |= DXBOF_DITHER;
}
}
}
}
}
}
/*****************************************************************************
* CDXBaseNTo1::Setup *
*--------------------*
* Description:
* The Setup method is used to perform any required one-time setup
* before the Execute method is called. Single surfaces or SurfaceSets may
* be used as arguments in any combination.
* If punkOutputs is NULL, Execute will allocate an output result of the
* appropriate size and return it.
* if punkInputs and punkOutputs are NULL and it is a quick setup, the current
* input and output objects are released.
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::Setup( IUnknown * const * punkInputs, ULONG ulNumInputs,
IUnknown * const * punkOutputs, ULONG ulNumOutputs, DWORD dwFlags )
{
DXTDBG_FUNC( "CDXBaseNTo1::Setup" );
//--- Lock object so state cannot change during setup
DXAUTO_OBJ_LOCK
HRESULT hr = S_OK;
ULONG i;
//
// Early out for null setup. Forget about all other param validation, just do it.
//
if (ulNumInputs == 0 && ulNumOutputs == 0)
{
_ReleaseReferences();
OnReleaseObjects();
return hr;
}
//--- Validate Params
//--- Make sure we have a reference to the transform factory
if( !m_cpTransFact )
{
hr = DXTERR_UNINITIALIZED;
DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" );
}
else
{
//
// We know that if we have a transform factory that we must also have
// allocated m_aInputs since this is done on SetSite to avoid work during
// each setup.
//
_ASSERT(m_aInputs || m_ulMaxInputs == 0);
if( dwFlags || // No flags are valid
ulNumOutputs != 1 ||
ulNumInputs < m_ulNumInRequired ||
ulNumInputs > m_ulMaxInputs ||
(ulNumInputs && DXIsBadReadPtr( punkInputs , sizeof( *punkInputs ) * ulNumInputs )) ||
DXIsBadReadPtr(punkOutputs, sizeof(*punkOutputs)) ||
DXIsBadInterfacePtr(punkOutputs[0]))
{
hr = E_INVALIDARG;
DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
}
else
{
for( i = 0; i < ulNumInputs; ++i )
{
if((punkInputs[i] && DXIsBadInterfacePtr(punkInputs[i])) ||
(punkInputs[i] == NULL && i < m_ulNumInRequired))
{
hr = E_INVALIDARG;
DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
break;
}
}
}
}
//--- Allocate slots for input data object pointers
if( SUCCEEDED( hr ) )
{
//--- Release data objects
_ReleaseReferences();
m_ulNumInputs = ulNumInputs;
}
//
// Assign
//
for( i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
{
hr = m_aInputs[i].Assign((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER), punkInputs[i], m_cpSurfFact);
}
if( SUCCEEDED(hr) )
{
hr = m_Output.Assign((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER), punkOutputs[0], m_cpSurfFact);
}
if (SUCCEEDED(hr) && (m_dwOptionFlags & DXBOF_SAME_SIZE_INPUTS))
{
hr = _MakeInputsSameSize();
}
if (SUCCEEDED(hr))
{
_UpdateBltFlags(); // Do this before calling OnSetup...
hr = OnSetup(dwFlags);
}
if (FAILED(hr))
{
_ReleaseReferences();
OnReleaseObjects();
DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup failed" );
}
else
{
m_fIsSetup = true;
}
return hr;
} /* CDXBaseNTo1::Setup */
/*****************************************************************************
* CDXBaseNTo1::_MakeInputsSameSize *
*----------------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 03/31/98
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
HRESULT CDXBaseNTo1::_MakeInputsSameSize(void)
{
_ASSERT((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) == 0);
HRESULT hr = S_OK;
if (m_ulNumInputs > 1) // No need to do this for just one input!
{
CDXDBnds SurfBnds(false);
CDXDBnds Union(true);
ULONG i;
for (i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++)
{
if (InputSurface(i))
{
hr = SurfBnds.SetToSurfaceBounds(InputSurface(i));
Union |= SurfBnds;
}
}
for (i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++)
{
if (InputSurface(i))
{
hr = SurfBnds.SetToSurfaceBounds(InputSurface(i));
if (SUCCEEDED(hr) && SurfBnds != Union)
{
IDXSurfaceModifier *pSurfMod;
hr = ::CoCreateInstance(CLSID_DXSurfaceModifier, NULL, CLSCTX_INPROC,
IID_IDXSurfaceModifier, (void **)&pSurfMod);
if (SUCCEEDED(hr))
{
POINT p;
p.x = p.y = 0;
if (m_dwOptionFlags & DXBOF_CENTER_INPUTS)
{
p.x = (Union.Width() - SurfBnds.Width()) / 2;
p.y = (Union.Height() - SurfBnds.Height()) / 2;
}
pSurfMod->SetForeground(InputSurface(i), FALSE, &p);
pSurfMod->SetBounds(&Union);
InputSurface(i)->Release();
pSurfMod->QueryInterface(IID_IDXSurface, (void **)&(m_aInputs[i].m_pNativeInterface));
((IDXSurface *)m_aInputs[i].m_pNativeInterface)->GetPixelFormat(NULL, &m_aInputs[i].m_SampleFormat);
pSurfMod->Release();
}
}
}
}
}
return hr;
}
/*****************************************************************************
* CDXBaseNTo1::Execute *
*----------------------*
* Description:
* The Execute method is used to walk the inputs/outputs and break up the
* work into suitably sized pieces to spread symetrically accross the available
* processors in the system.
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::
Execute( const GUID* pRequestID, const DXBNDS *pClipBnds, const DXVEC *pPlacement )
{
DXTDBG_FUNC( "CDXBaseNTo1::Execute" );
//--- Lock object so state cannot change during execution
DXAUTO_OBJ_LOCK
HRESULT hr = S_OK;
//--- Check args
if( !HaveOutput() )
{
DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" );
return DXTERR_UNINITIALIZED;
}
if (m_ulMaxImageBands == 0 ||
(m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)))
{
if ((pClipBnds && (m_dwMiscFlags & DXTMF_BOUNDS_SUPPORTED) == 0) ||
(pPlacement && (m_dwMiscFlags & DXTMF_PLACEMENT_SUPPORTED) == 0) )
{
DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
return E_INVALIDARG;
}
return OnExecute( pRequestID, pClipBnds, pPlacement );
}
//--- Banded image working variables
CDXTWorkInfoNTo1 WI;
if ((pClipBnds && pClipBnds->eType != DXBT_DISCRETE) ||
(pPlacement && pPlacement->eType != DXBT_DISCRETE))
{
hr = E_INVALIDARG;
DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
}
else
{
hr = MapBoundsIn2Out( NULL, 0, 0, &WI.DoBnds );
if( hr == S_OK )
{
hr = WI.OutputBnds.SetToSurfaceBounds(OutputSurface());
if (hr == S_OK)
{
hr = DXClipToOutputWithPlacement(WI.DoBnds, (CDXDBnds *)pClipBnds, WI.OutputBnds, (CDXDVec *)pPlacement);
}
}
}
//--- Check for clipping early exit
if( hr != S_OK )
{
return hr;
}
//=== Process ====================================================
_ASSERT(m_ulMaxImageBands <= DXB_MAX_IMAGE_BANDS);
ULONG ulNumBandsToDo = m_ulNumProcessors;
if( ulNumBandsToDo > 1 )
{
ulNumBandsToDo = 1 + ((WI.OutputBnds.Width() * WI.OutputBnds.Height()) / 0x1000);
if (ulNumBandsToDo > m_ulMaxImageBands)
{
ulNumBandsToDo = m_ulMaxImageBands;
}
if (ulNumBandsToDo > m_ulNumProcessors)
{
ulNumBandsToDo = m_ulNumProcessors;
}
}
hr = OnInitInstData(WI, ulNumBandsToDo);
if( SUCCEEDED( hr ) )
{
if (ulNumBandsToDo == 1 && pRequestID == NULL)
{
static BOOL bContinue = TRUE;
hr = WorkProc(WI, &bContinue);
}
else
{
_ASSERT( ulNumBandsToDo <= DXB_MAX_IMAGE_BANDS );
_ASSERT( m_aEvent[ulNumBandsToDo-1] );
long lStartAtRow = WI.DoBnds[DXB_Y].Min;
ULONG ulRowCount = WI.DoBnds[DXB_Y].Max - lStartAtRow;
_ASSERT( ( ulRowCount / ulNumBandsToDo ) != 0 );
//--- Init the work info structures
ULONG ulBand, RowsPerBand = ulRowCount / ulNumBandsToDo;
CDXTWorkInfoNTo1 *WIArray = (CDXTWorkInfoNTo1*)alloca( sizeof(CDXTWorkInfoNTo1) *
ulNumBandsToDo );
DWORD *TaskIDs = (DWORD*)alloca( sizeof(DWORD) * ulNumBandsToDo );
DXTMTASKINFO* TaskInfo = (DXTMTASKINFO*)alloca( sizeof( DXTMTASKINFO ) *
ulNumBandsToDo );
//--- Build task info list
WI.hr = S_OK;
WI.pvThis = this;
long Start = lStartAtRow;
ULONG Count = RowsPerBand;
long OutputYDelta = WI.OutputBnds[DXB_Y].Min - WI.DoBnds[DXB_Y].Min;
for (ulBand = 0; ulBand < ulNumBandsToDo; ++ulBand)
{
memcpy(&WIArray[ulBand], &WI, sizeof(WI));
WIArray[ulBand].DoBnds[DXB_Y].Min = Start;
WIArray[ulBand].OutputBnds[DXB_Y].Min = Start + OutputYDelta;
// If this is the last band, make sure it includes the last row.
if (ulBand == ulNumBandsToDo - 1)
{
WIArray[ulBand].DoBnds[DXB_Y].Max = WI.DoBnds[DXB_Y].Max;
WIArray[ulBand].OutputBnds[DXB_Y].Max = WI.OutputBnds[DXB_Y].Max;
}
else // Not the last band.
{
WIArray[ulBand].DoBnds[DXB_Y].Max = Start + Count;
WIArray[ulBand].OutputBnds[DXB_Y].Max = Start + Count
+ OutputYDelta;
}
TaskInfo[ulBand].pfnTaskProc = _TaskProc;
TaskInfo[ulBand].pTaskData = &WIArray[ulBand];
TaskInfo[ulBand].pfnCompletionAPC = NULL;
TaskInfo[ulBand].dwCompletionData = 0;
TaskInfo[ulBand].pRequestID = pRequestID;
// Advance.
Start += Count;
}
//
// Procedural surfaces (and perhaps some transforms) need to "know" that
// they are in a multi-threaded work procedure to avoid deadlocks. Procedural
// surfaces need to allow LockSurface to work WITHOUT taking the object
// critical section. Other transforms may also want to know this information
// to avoid deadlocks.
//
m_bInMultiThreadWorkProc = TRUE;
//--- Schedule the work and wait for it to complete
hr = m_cpTaskMgr->ScheduleTasks( TaskInfo, m_aEvent,
TaskIDs, ulNumBandsToDo, m_ulLockTimeOut );
m_bInMultiThreadWorkProc = FALSE;
//--- Check return codes from work info structures
// return the first bad hr if any
for( ulBand = 0; SUCCEEDED( hr ) && ( ulBand < ulNumBandsToDo ); ++ulBand )
{
hr = WIArray[ulBand].hr;
if( hr != S_OK ) break;
}
}
OnFreeInstData( WI );
}
#ifdef _DEBUG
if( FAILED( hr ) ) DXTDBG_MSG1( _CRT_ERROR, "\nExecute failed. HR = %X", hr );
#endif
return hr;
} /* CDXBaseNTo1::Execute */
/*****************************************************************************
* CDXBaseNTo1::_ImageMapIn2Out *
*------------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 07/28/97
*****************************************************************************/
HRESULT CDXBaseNTo1::_ImageMapIn2Out( CDXDBnds & bnds, ULONG ulNumInBnds,
const CDXDBnds * pInBounds )
{
HRESULT hr = S_OK;
if(ulNumInBnds)
{
for(ULONG i = 0; i < ulNumInBnds; ++i )
{
bnds |= pInBounds[i];
}
}
else
{
for( ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
{
if (InputSurface(i))
{
CDXDBnds SurfBnds(InputSurface(i), hr);
bnds |= SurfBnds;
}
}
}
if (SUCCEEDED(hr))
{
hr = DetermineBnds(bnds);
}
return hr;
} /* CDXBaseNTo1::_ImageMapIn2Out */
/*****************************************************************************
* CDXBaseNTo1::_MeshMapIn2Out *
*-----------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 07/28/97
*****************************************************************************/
HRESULT CDXBaseNTo1::_MeshMapIn2Out(CDXCBnds & bnds, ULONG ulNumInBnds, CDXCBnds * pInBounds)
{
HRESULT hr = S_OK;
if (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER)
{
if(ulNumInBnds)
{
for(ULONG i = 0; i < ulNumInBnds; ++i )
{
bnds |= pInBounds[i];
}
}
else
{
for(ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
{
if (InputMeshBuilder(i))
{
CDXCBnds MeshBnds(InputMeshBuilder(i), hr);
bnds |= MeshBnds;
}
}
}
}
else
{
// Already done -> bnds[DXB_T].Min = 0.0f;
bnds[DXB_X].Min = bnds[DXB_Y].Min = bnds[DXB_Z].Min = -1.0f;
bnds[DXB_X].Max = bnds[DXB_Y].Max = bnds[DXB_Z].Max = bnds[DXB_T].Max = 1.0f;
}
//
// Call the derived class to get the scale values.
//
if (SUCCEEDED(hr))
{
// Increase the size just a bit so we won't have rounding errors
// result in bounds that don't actually contain the result.
const float fBndsIncrease = 0.0001F;
float fTemp = bnds.Width() * fBndsIncrease;
bnds[DXB_X].Min -= fTemp;
bnds[DXB_X].Max += fTemp;
fTemp = fBndsIncrease * bnds.Height();
bnds[DXB_Y].Min -= fTemp;
bnds[DXB_Y].Max += fTemp;
fTemp = fBndsIncrease * bnds.Depth();
bnds[DXB_Z].Min -= fTemp;
bnds[DXB_Z].Max += fTemp;
hr = DetermineBnds(bnds);
}
return hr;
} /* CDXBaseNTo1::_MeshMapIn2Out */
/*****************************************************************************
* CDXBaseNTo1::MapBoundsIn2Out *
*------------------------------*
* Description:
* The MapBoundsIn2Out method is used to perform coordinate transformation
* from the input to the output coordinate space.
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::MapBoundsIn2Out( const DXBNDS *pInBounds, ULONG ulNumInBnds,
ULONG ulOutIndex, DXBNDS *pOutBounds )
{
DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsIn2Out" );
if((ulNumInBnds && DXIsBadReadPtr( pInBounds, ulNumInBnds * sizeof( *pInBounds ) )) ||
ulOutIndex)
{
return E_INVALIDARG;
}
if( DXIsBadWritePtr( pOutBounds, sizeof( *pOutBounds ) ) )
{
return E_POINTER;
}
//
// Set the bounds to empty and the appropriate type.
//
memset(pOutBounds, 0, sizeof(*pOutBounds));
_ASSERT(DXBT_DISCRETE == 0);
if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
{
pOutBounds->eType = DXBT_CONTINUOUS;
}
//
// Make sure all input bounds are of the correct type.
//
if( ulNumInBnds )
{
DXBNDTYPE eType = (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) ? DXBT_CONTINUOUS : DXBT_DISCRETE;
for (ULONG i = 0; i < ulNumInBnds; i++)
{
if (pInBounds[i].eType != eType)
{
return E_INVALIDARG;
}
}
}
//
// Now do the appropriate mapping
//
if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
{
//
// NOTE: In the case of non-mesh inputs, the inputs are discrete, but they will
// be completely ignored by the function so it's OK to cast them to CDXCBnds
//
return _MeshMapIn2Out(*((CDXCBnds *)pOutBounds), ulNumInBnds, (CDXCBnds *)pInBounds);
}
else
{
return _ImageMapIn2Out(*(CDXDBnds *)pOutBounds, ulNumInBnds, (CDXDBnds *)pInBounds);
}
} /* CDXBaseNTo1::MapBoundsIn2Out */
/*****************************************************************************
* CDXBaseNTo1::MapBoundsOut2In *
*------------------------------*
* Description:
* The MapBoundsOut2In method is used to perform coordinate transformation
* from the input to the output coordinate space.
*-----------------------------------------------------------------------------
* Created By: Ed Connell Date: 07/28/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::
MapBoundsOut2In( ULONG ulOutIndex, const DXBNDS *pOutBounds, ULONG ulInIndex, DXBNDS *pInBounds )
{
DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsOut2In" );
HRESULT hr = S_OK;
if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
{
hr = E_NOTIMPL; // This is pointless for meshes.
}
else if(ulInIndex >= m_ulMaxInputs || ulOutIndex || DXIsBadReadPtr( pOutBounds, sizeof( *pOutBounds ) ) )
{
hr = E_INVALIDARG;
}
else if( DXIsBadWritePtr( pInBounds, sizeof( *pInBounds ) ) )
{
hr = E_POINTER;
}
else
{
*pInBounds = *pOutBounds;
}
return hr;
} /* CDXBaseNTo1::MapBoundsOut2In */
/*****************************************************************************
* CDXBaseNTo1::SetMiscFlags *
*---------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 10/30.97
*-----------------------------------------------------------------------------
* Parameters:
* bMiscFlags - New value to set
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::SetMiscFlags( DWORD dwMiscFlags )
{
DXTDBG_FUNC( "CDXBaseNTo1::SetMiscFlags" );
HRESULT hr = S_OK;
Lock();
WORD wOpts = (WORD)dwMiscFlags; // Ignore high word. Only set low word.
if (((WORD)m_dwMiscFlags) != wOpts)
{
if ((wOpts & (~DXTMF_VALID_OPTIONS)) ||
((wOpts & DXTMF_BLEND_WITH_OUTPUT) && (m_dwMiscFlags & DXTMF_BLEND_SUPPORTED) == 0) ||
((wOpts & DXTMF_DITHER_OUTPUT) && (m_dwMiscFlags & DXTMF_DITHER_SUPPORTED) == 0))
{
hr = E_INVALIDARG;
}
else
{
m_dwMiscFlags &= 0xFFFF0000;
m_dwMiscFlags |= wOpts;
_UpdateBltFlags();
m_dwGenerationId++;
}
}
Unlock();
return hr;
} /* CDXBaseNTo1::SetMiscFlags */
/*****************************************************************************
* CDXBaseNTo1::GetMiscFlags *
*----------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 10/30/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::GetMiscFlags( DWORD* pdwMiscFlags )
{
if( DXIsBadWritePtr( pdwMiscFlags, sizeof( *pdwMiscFlags ) ) )
{
return E_POINTER;
}
*pdwMiscFlags = m_dwMiscFlags;
return S_OK;
} /* CDXBaseNTo1::GetMiscFlags */
/*****************************************************************************
* CDXBaseNTo1::SetQuality *
*----------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 10/30/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::SetQuality(float fQuality)
{
if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0)
{
return E_NOTIMPL;
}
if (fQuality < 0.0f || fQuality > 1.0f)
{
return E_INVALIDARG;
}
Lock();
if (m_fQuality != fQuality)
{
m_fQuality = fQuality;
m_dwGenerationId++;
}
Unlock();
return S_OK;
}
/*****************************************************************************
* CDXBaseNTo1::GetQuality *
*-------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 10/30/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::GetQuality(float *pfQuality)
{
HRESULT hr = S_OK;
if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0)
{
hr = E_NOTIMPL;
}
else
{
if( DXIsBadWritePtr( pfQuality, sizeof( *pfQuality ) ) )
{
hr = E_POINTER;
}
else
{
*pfQuality = m_fQuality;
}
}
return hr;
}
/*****************************************************************************
* GetInOutInfo
*-----------------------------------------------------------------------------
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::GetInOutInfo( BOOL bOutput, ULONG ulIndex, DWORD *pdwFlags,
GUID * pIDs, ULONG *pcIDs, IUnknown **ppUnkCurObj )
{
DXTDBG_FUNC( "CDXBaseNTo1::GetInOutInfo" );
HRESULT hr = S_FALSE;
DWORD dwFlags = 0;
BOOL bImage;
if( bOutput )
{
bImage = !(m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER);
if (ulIndex == 0)
{
hr = S_OK;
}
}
else
{
bImage = !(m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER);
if (ulIndex < m_ulMaxInputs)
{
hr = S_OK;
if (ulIndex >= m_ulNumInRequired)
{
dwFlags = DXINOUTF_OPTIONAL;
}
}
}
if( hr == S_OK )
{
if( pdwFlags && !DXIsBadWritePtr( pdwFlags, sizeof( *pdwFlags ) ) )
{
*pdwFlags = dwFlags;
}
if( pIDs )
{
if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) ||
DXIsBadWritePtr( pIDs, *pcIDs * sizeof( *pIDs ) ) )
{
hr = E_INVALIDARG;
}
else
{
if (bImage)
{
if (*pcIDs > 0)
{
pIDs[0] = IID_IDXSurface;
}
if (*pcIDs > 1)
{
pIDs[1] = IID_IDXDupDDrawSurface;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
}
*pcIDs = 2;
}
else
{
if (*pcIDs > 0)
{
pIDs[0] = IID_IDXDupDirect3DRMMeshBuilder3;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
}
*pcIDs = 1;
}
}
}
else if( pcIDs )
{
if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) )
{
hr = E_POINTER;
}
else
{
*pcIDs = bImage ? 2 : 1;
}
}
if (hr == S_OK && ppUnkCurObj)
{
if (DXIsBadWritePtr(ppUnkCurObj, sizeof(*ppUnkCurObj)))
{
hr = E_POINTER;
}
else
{
if (bOutput)
{
*ppUnkCurObj = m_Output.m_pNativeInterface;
}
else
{
*ppUnkCurObj = NULL;
if (ulIndex < GetNumInputs())
{
*ppUnkCurObj = m_aInputs[ulIndex].m_pUnkOriginalObject;
}
}
if (*ppUnkCurObj)
{
(*ppUnkCurObj)->AddRef();
}
}
}
}
return hr;
} /* CDXBaseNTo1::GetInOutInfo */
/*****************************************************************************
* CDXBaseNTo1::OnUpdateGenerationId *
*-----------------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
void CDXBaseNTo1::OnUpdateGenerationId(void)
{
DXTDBG_FUNC( "CDXBaseNTo1::OnUpdateGenerationId" );
if( (m_dwMiscFlags & DXTMF_INPLACE_OPERATION) &&
m_Output.UpdateGenerationId())
{
m_dwGenerationId++;
}
for (ULONG i = 0; i < m_ulNumInputs; i++)
{
if (m_aInputs[i].UpdateGenerationId())
{
m_dwGenerationId++;
}
}
} /* CDXBaseNTo1::OnUpdateGenerationId */
/*****************************************************************************
* CDXBaseNTo1::OnGetObjectSize *
*------------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
ULONG CDXBaseNTo1::OnGetObjectSize(void)
{
return sizeof(*this);
}
//
// Effect interface
//
/*****************************************************************************
* CDXBaseNTo1::get_Progress *
*---------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::get_Progress(float *pVal)
{
DXTDBG_FUNC( "CDXBaseNTo1::get_Progress" );
HRESULT hr = S_OK;
if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
{
hr = E_POINTER;
}
else
{
*pVal = m_Progress;
}
return hr;
}
/*****************************************************************************
* CDXBaseNTo1::put_Progress *
*---------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::put_Progress(float newVal)
{
DXTDBG_FUNC( "CDXBaseNTo1::put_Progress" );
HRESULT hr = S_OK;
if (newVal < 0.0 || newVal > 1.0f)
{
hr = E_INVALIDARG;
}
else
{
Lock();
m_Progress = newVal;
m_dwCleanGenId++; // This should not make the transform "dirty" internally
m_dwGenerationId++;
Unlock();
}
return hr;
}
/*****************************************************************************
* CDXBaseNTo1::get_StepResolution *
*---------------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::get_StepResolution(float *pVal)
{
DXTDBG_FUNC( "CDXBaseNTo1::get_StepResolution" );
HRESULT hr = S_OK;
if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
{
hr = E_POINTER;
}
else
{
*pVal = m_StepResolution;
}
return hr;
}
/*****************************************************************************
* CDXBaseNTo1::get_Duration *
*---------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::get_Duration(float *pVal)
{
DXTDBG_FUNC( "CDXBaseNTo1::get_Duration" );
if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
{
return E_POINTER;
}
else
{
*pVal = m_Duration;
}
return S_OK;
}
/*****************************************************************************
* CDXBaseNTo1::put_Duration *
*---------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::put_Duration(float newVal)
{
DXTDBG_FUNC( "CDXBaseNTo1::put_Duration" );
if (newVal <= 0.)
{
return E_INVALIDARG;
}
if(newVal != m_Duration)
{
Lock();
m_dwGenerationId++;
m_dwCleanGenId++; // This should not make the transform "dirty" internally
m_Duration = newVal;
Unlock();
}
return S_OK;
}
/*****************************************************************************
* CDXBaseNTo1::PointPick *
*------------------------*
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 5/5/98
*****************************************************************************/
STDMETHODIMP CDXBaseNTo1::PointPick(const DXVEC *pPoint,
ULONG * pulInputSurfaceIndex,
DXVEC *pInputPoint)
{
HRESULT hr = S_OK;
BOOL bFoundIt = FALSE;
// If we haven't been set up yet, we will just act as if we're transparent.
if (!m_fIsSetup)
{
hr = S_FALSE;
goto done;
}
if (DXIsBadReadPtr(pPoint, sizeof(*pPoint)) || pPoint->eType != DXBT_DISCRETE)
{
hr = E_INVALIDARG;
}
else
{
if (DXIsBadWritePtr(pulInputSurfaceIndex, sizeof(*pulInputSurfaceIndex)) ||
DXIsBadWritePtr(pInputPoint, sizeof(*pInputPoint)))
{
hr = E_POINTER;
}
else
{
HRESULT hr2 = S_OK;
CDXDBnds bndsOutput;
CDXDBnds OutBndsPoint(*((CDXDVec *)pPoint));
CDXDVec & InVec = *(new(pInputPoint) CDXDVec(*((CDXDVec *)pPoint)));
// Get the output size of the DXTransform. If this point is not on
// the output at all, we can return S_FALSE right now.
hr = MapBoundsIn2Out(NULL, 0, 0, &bndsOutput);
if (FAILED(hr))
{
goto done;
}
if (!bndsOutput.TestIntersect(OutBndsPoint))
{
hr = S_FALSE;
goto done;
}
hr2 = OnSurfacePick(OutBndsPoint, *pulInputSurfaceIndex, InVec);
if (hr2 != E_NOTIMPL)
{
hr = hr2;
}
else
{
//--- The derived class does not implement so we will do
// the hit test against the input for them.
ULONG * aulInIndex = (ULONG *)_alloca(sizeof(ULONG) * m_ulMaxInputs);
BYTE * aWeights = (BYTE *)_alloca(sizeof(BYTE) * m_ulMaxInputs);
ULONG ulNumToTest;
OnGetSurfacePickOrder(OutBndsPoint, ulNumToTest, aulInIndex, aWeights);
if( m_bPickDoneByBase && ( m_ulNumInputs > 1 ) )
{
//--- We don't know how to do multi-input picking from the base.
hr = E_NOTIMPL;
}
for (ULONG i = 0; SUCCEEDED(hr) && i < ulNumToTest; i++)
{
ULONG ulInput = aulInIndex[i];
if (HaveInput(ulInput) && aWeights[i])
{
CDXDBnds Out2InBnds(false);
hr = MapBoundsOut2In(0, &OutBndsPoint, ulInput, &Out2InBnds);
if (SUCCEEDED(hr))
{
CDXDBnds InSurfBnds(InputSurface(ulInput), hr);
if (SUCCEEDED(hr) && InSurfBnds.IntersectBounds(Out2InBnds))
{
IDXARGBReadPtr * pPtr;
hr = InputSurface(ulInput)->LockSurface(&InSurfBnds, m_ulLockTimeOut, DXLOCKF_READ,
IID_IDXARGBReadPtr, (void **)&pPtr, NULL);
if( SUCCEEDED(hr) )
{
DXPMSAMPLE val;
pPtr->UnpackPremult(&val, 1, FALSE);
pPtr->Release();
if (val.Alpha * aWeights[i] / 255)
{
InSurfBnds.GetMinVector(InVec);
bFoundIt = TRUE;
*pulInputSurfaceIndex = ulInput;
break;
}
}
}
}
}
}
if (SUCCEEDED(hr) & (!bFoundIt))
{
hr = S_FALSE;
}
}
}
}
done:
return hr;
} /* CDXBaseNTo1::PointPick */
/*****************************************************************************
* RegisterTansform (STATIC member function)
*-----------------------------------------------------------------------------
* Description:
*-----------------------------------------------------------------------------
* Created By: RAL Date: 12/10/97
*-----------------------------------------------------------------------------
* Parameters:
*****************************************************************************/
HRESULT CDXBaseNTo1::
RegisterTransform(REFCLSID rcid, int ResourceId, ULONG cCatImpl, const CATID * pCatImpl,
ULONG cCatReq, const CATID * pCatReq, BOOL bRegister)
{
DXTDBG_FUNC( "CDXBaseNTo1::RegisterTransform" );
HRESULT hr = bRegister ? _Module.UpdateRegistryFromResource(ResourceId, bRegister) : S_OK;
if (SUCCEEDED(hr))
{
CComPtr<ICatRegister> pCatRegister;
HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC, IID_ICatRegister, (void **)&pCatRegister);
if (SUCCEEDED(hr))
{
if (bRegister)
{
hr = pCatRegister->RegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
if (SUCCEEDED(hr) && cCatReq && pCatReq) {
hr = pCatRegister->RegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
}
}
else
{
pCatRegister->UnRegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
if (cCatReq && pCatReq)
{
pCatRegister->UnRegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
}
}
}
}
if ((!bRegister) && SUCCEEDED(hr))
{
_Module.UpdateRegistryFromResource(ResourceId, bRegister);
}
return hr;
}
void CDXBaseNTo1::_TaskProc(void* pTaskInfo, BOOL* pbContinue )
{
_ASSERT( pTaskInfo );
CDXTWorkInfoNTo1& WI = *((CDXTWorkInfoNTo1 *)pTaskInfo);
CDXBaseNTo1& This = *((CDXBaseNTo1 *)WI.pvThis);
WI.hr = This.WorkProc(WI, pbContinue);
}