source-engine/materialsystem/imaterialsysteminternal.h

225 lines
6.0 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef IMATERIALSYSTEMINTERNAL_H
#define IMATERIALSYSTEMINTERNAL_H
#ifdef _WIN32
#pragma once
#endif
#include "materialsystem/imaterialsystem.h"
#include "tier1/callqueue.h"
#include "tier1/memstack.h"
class IMaterialInternal;
//-----------------------------------------------------------------------------
// Special call queue that knows (a) single threaded access, and (b) all
// functions called after last function added
//-----------------------------------------------------------------------------
class CMatCallQueue
{
public:
CMatCallQueue()
{
MEM_ALLOC_CREDIT_( "CMatCallQueue.m_Allocator" );
#ifdef SWDS
m_Allocator.Init( 2*1024, 0, 0, 16 );
#else
m_Allocator.Init( IsX360() ? 2*1024*1024 : 8*1024*1024, 64*1024, 256*1024, 16 );
#endif
m_FunctorFactory.SetAllocator( &m_Allocator );
m_pHead = m_pTail = NULL;
}
size_t GetMemoryUsed()
{
return m_Allocator.GetUsed();
}
int Count()
{
int i = 0;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
i++;
pCurrent = pCurrent->pNext;
}
return i;
}
void CallQueued()
{
if ( !m_pHead )
{
return;
}
CFunctor *pFunctor;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
pFunctor = pCurrent->pFunctor;
#ifdef _DEBUG
if ( pFunctor->m_nUserID == m_nBreakSerialNumber)
{
m_nBreakSerialNumber = (unsigned)-1;
}
#endif
(*pFunctor)();
pFunctor->Release();
pCurrent = pCurrent->pNext;
}
m_Allocator.FreeAll( false );
m_pHead = m_pTail = NULL;
}
void QueueFunctor( CFunctor *pFunctor )
{
Assert( pFunctor );
QueueFunctorInternal( RetAddRef( pFunctor ) );
}
void Flush()
{
if ( !m_pHead )
{
return;
}
CFunctor *pFunctor;
Elem_t *pCurrent = m_pHead;
while ( pCurrent )
{
pFunctor = pCurrent->pFunctor;
pFunctor->Release();
pCurrent = pCurrent->pNext;
}
m_Allocator.FreeAll( false );
m_pHead = m_pTail = NULL;
}
#define DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL(N) \
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
#define DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
#define DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
void QueueCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
QueueFunctorInternal( m_FunctorFactory.CreateFunctor( pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ) ); \
}
//-------------------------------------
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_NONMEMBER_QUEUE_CALL );
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_MEMBER_QUEUE_CALL );
FUNC_GENERATE_ALL( DEFINE_MATCALLQUEUE_CONST_MEMBER_QUEUE_CALL );
private:
void QueueFunctorInternal( CFunctor *pFunctor )
{
#ifdef _DEBUG
pFunctor->m_nUserID = m_nCurSerialNumber++;
#endif
MEM_ALLOC_CREDIT_( "CMatCallQueue.m_Allocator" );
Elem_t *pNew = (Elem_t *)m_Allocator.Alloc( sizeof(Elem_t) );
if ( m_pTail )
{
m_pTail->pNext = pNew;
m_pTail = pNew;
}
else
{
m_pHead = m_pTail = pNew;
}
pNew->pNext = NULL;
pNew->pFunctor = pFunctor;
}
struct Elem_t
{
Elem_t *pNext;
CFunctor *pFunctor;
};
Elem_t *m_pHead;
Elem_t *m_pTail;
CMemoryStack m_Allocator;
CCustomizedFunctorFactory<CMemoryStack, CRefCounted1<CFunctor, CRefCountServiceDestruct< CRefST > > > m_FunctorFactory;
unsigned m_nCurSerialNumber;
unsigned m_nBreakSerialNumber;
};
class IMaterialProxy;
//-----------------------------------------------------------------------------
// Additional interfaces used internally to the library
//-----------------------------------------------------------------------------
abstract_class IMaterialSystemInternal : public IMaterialSystem
{
public:
// Returns the current material
virtual IMaterial* GetCurrentMaterial() = 0;
virtual int GetLightmapPage( void ) = 0;
// Gets the maximum lightmap page size...
virtual int GetLightmapWidth( int lightmap ) const = 0;
virtual int GetLightmapHeight( int lightmap ) const = 0;
virtual ITexture *GetLocalCubemap( void ) = 0;
// virtual bool RenderZOnlyWithHeightClipEnabled( void ) = 0;
virtual void ForceDepthFuncEquals( bool bEnable ) = 0;
virtual enum MaterialHeightClipMode_t GetHeightClipMode( void ) = 0;
// FIXME: Remove? Here for debugging shaders in CShaderSystem
virtual void AddMaterialToMaterialList( IMaterialInternal *pMaterial ) = 0;
virtual void RemoveMaterial( IMaterialInternal *pMaterial ) = 0;
virtual void RemoveMaterialSubRect( IMaterialInternal *pMaterial ) = 0;
virtual bool InFlashlightMode() const = 0;
// Can we use editor materials?
virtual bool CanUseEditorMaterials() const = 0;
virtual const char *GetForcedTextureLoadPathID() = 0;
virtual CMatCallQueue *GetRenderCallQueue() = 0;
virtual void UnbindMaterial( IMaterial *pMaterial ) = 0;
virtual ThreadId_t GetRenderThreadId() const = 0 ;
virtual IMaterialProxy *DetermineProxyReplacements( IMaterial *pMaterial, KeyValues *pFallbackKeyValues ) = 0;
};
#endif // IMATERIALSYSTEMINTERNAL_H