📄 dtbase.cpp
字号:
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" );
}
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);
for (ULONG 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -