//
// Asura_PS3_SwapChain.h
//
// Created by Catalin Arsenescu - 29 April 2008
//
// Copyright (C) 2005 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
#pragma once
#endif

#ifndef __ASURA_PS3_SWAP_CHIAN_H__
#define __ASURA_PS3_SWAP_CHIAN_H__

#include <sys/synchronization.h>
#include <sys/spinlock.h>
#include "Rendering/Asura_PS3_Graphics.h"
#include "Debugging/Asura_PS3_CommandBufferInspector.h"

class Asura_PS3_SwapChain
{
friend class Asura_PS3_Graphics;
#if defined(ASURA_PS3_USE_COMMAND_BUFFER_INSPECTOR)
friend class Asura_PS3_CommandBufferInspector;
#endif

public:
	static void	Initialise( void );
	static void	Shutdown( void );
	static void Create( void );

	// swaps and presents
	static void	Present( u_int uDisplayID );
	static void BlockUntilIdle( void );
	static void SkipFlip( void );

	static u_int GetWhich( void ) { return s_uWhich; } // handy 0 or 1 number
	static u_int GetTotalSize( void ) { return s_uTotalSize; }

	static u_int GetPresentInterval( void ) { return s_uPresentationInterval; };
	static void SetPresentInterval( u_int uPresentInterval ) { s_uPresentationInterval = uPresentInterval; }
	static void SetIsInFMV( bool bIsinFMV )	{ s_bIsInFMV = bIsinFMV; }

#ifdef ASURA_ASSERT
	static void SetDefaultCommandBuffer( void );
	static void RestoreCommandBuffer( void );
	static void PresentAssert( u_int uDisplayID );
#endif

protected:
	static void	FlipHandler( const u_int Value );
	static void	VSyncHandler( const u_int Value );
	static void	TryFlipImmediate( void );
	static int	CommandBufferCallback( struct CellGcmContextData* pContextData, unsigned int Amount );
	static void	BlockOnFlip(unsigned int FlipDelta);

	//BW moved so's I can see em. hacky hack hackity hack-hack
	static u_int*				s_pxDefaultCommandBuffer;	// small ring buffer
	static u_int				s_uTotalSize;

private:
	static volatile u_int		s_uFlipCounter;
	static volatile u_int		s_uVSyncCounter;
	static volatile u_int		s_uVSyncNext;
	static volatile u_int		s_uLastFlipId;
	static volatile u_int		s_uFinishRC;

	static u_int*				s_paxCommandBuffer[2];		// large per-frame command buffers
	static u_int				s_uWhich;
	static u_int				s_uRingBufferSize;
	static u_int				s_uCommandBufferSize;
	static u_int				s_uLastFlipCounter;
	static u_int				s_uPresentationInterval;

	static CellGcmContextData	s_xCurrentCmdCtxt;			// current command buffer context
	static sys_lwmutex_t		s_xMutex;					// prevent the render thread and the interrupt thread from colliding!
	static bool					s_bIsInFMV;

	//Private Constructor & Destructor
	Asura_PS3_SwapChain( void );
	~Asura_PS3_SwapChain( void );
};


#endif//__ASURA_PS3_SWAP_CHIAN_H__
