//
// Asura_PS3_SPU_Skinning.h
//
// Author: Ben Weston 28/5/2008
//
// TEMPORARY! Really straightforward interface for running skinning code on SPUs
// Todo: use this and whatever Kevin does & Morgan's GeomCulling stuff as a basis for designing some kind of SPU task manager.
//

#if defined ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifndef __ASURA_PS3_SPU_SKINNING_H__
#define __ASURA_PS3_SPU_SKINNING_H__

#include "Core/Asura_RingBuffer.h"
#include "Core/Asura_Maths.h"
#include "Core/Threads/Asura_ProducerConsumerQueue.h"
#include "Animation/Asura_Animation.h"
#include "Rendering/Asura_PS3_CharacterRenderer.h"

#include <cell/sync/barrier.h>

#include "Rendering/Asura_PS3_SPU_SkinningTypes.h"


// Functions for invoking SPU-based skinning instead of vertex programs
class Asura_PS3_SPU_Skinning
{
public:
	static void Initialise( void );
	static void Shutdown( void );
	static void BeginFrame( void );
	static void EndFrame( void );
	static bool ProcessSkin(const Asura_PS3_CharacterRenderer_Skin* pxCharacter,
							Asura_PS3_SPU_SkinningConstants* pxShaderConstants,
							Asura_Platform_Animation_RenderCache* pxRenderCache,
							u_int uSkin, u_int uNumVerts, SPU_SKINNING_MODE eMode );
	static void NotifyBufferUsed( void );
	static bool IsSpuable(const Asura_PS3_CharacterRenderer_Skin* pxCharacter);
	static void WaitForSPUs();
	
	static void SetSPUSkinningEnabled(bool bEnable);
	static bool GetSPUSkinningEnabled();

	static void TryKickSPUs( void ) { KickSPUs(false); }
	static void ForceKickSPUs( void ) { KickSPUs(true); }

private:
	static void KickSPUs( bool bForce );
	static void PostRender( void );
	static inline size_t GetVertexSize( SPU_SKINNING_MODE eMode );
	static Asura_ProducerConsumerQueue	s_xSPUKickerThread;

	static u_int						s_uWriteBuffer;
	static int							s_iRSXBufferReads;
	static int							s_iRSXReadyValue;
	static bool							s_bFirstCharacter;
	static bool							s_bRanLastFrame;
	static bool							s_bRanThisFrame;
	static volatile bool				s_bStartedRunning;
};


#endif //#ifndef __ASURA_PS3_SPU_SKINNING_H__
