about summary refs log tree commit diff
path: root/src/engine/client/graphics_threaded.h
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2011-12-31 01:11:24 +0100
committerMagnus Auvinen <magnus.auvinen@gmail.com>2011-12-31 01:11:24 +0100
commit09b785a290c8394422b1334e5e07714c7e994521 (patch)
treec3e4e17a203a919c8a0584a966d4e7ff70a62eb0 /src/engine/client/graphics_threaded.h
parent8e568857959291f442ba8f11abac059b6bd6a9e9 (diff)
downloadzcatch-09b785a290c8394422b1334e5e07714c7e994521.tar.gz
zcatch-09b785a290c8394422b1334e5e07714c7e994521.zip
splitted out the graphics threaded into a separate header
Diffstat (limited to 'src/engine/client/graphics_threaded.h')
-rw-r--r--src/engine/client/graphics_threaded.h343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h
new file mode 100644
index 00000000..876e9410
--- /dev/null
+++ b/src/engine/client/graphics_threaded.h
@@ -0,0 +1,343 @@
+#pragma once
+
+#include <base/tl/threading.h>
+
+class CCommandBuffer
+{
+	class CBuffer
+	{
+		unsigned char *m_pData;
+		unsigned m_Size;
+		unsigned m_Used;
+	public:
+		CBuffer(unsigned BufferSize)
+		{
+			m_Size = BufferSize;
+			m_pData = new unsigned char[m_Size];
+			m_Used = 0;
+		}
+
+		~CBuffer()
+		{
+			delete [] m_pData;
+			m_pData = 0x0;
+			m_Used = 0;
+			m_Size = 0;
+		}
+
+		void Reset()
+		{
+			m_Used = 0;
+		}
+
+		void *Alloc(unsigned Requested)
+		{
+			if(Requested + m_Used > m_Size)
+				return 0;
+			void *pPtr = &m_pData[m_Used];
+			m_Used += Requested;
+			return pPtr;
+		}
+
+		unsigned char *DataPtr() { return m_pData; }
+		unsigned DataSize() { return m_Size; }
+		unsigned DataUsed() { return m_Used; }
+	};
+
+	CBuffer m_CmdBuffer;
+	CBuffer m_DataBuffer;
+public:
+	enum
+	{
+		//
+		CMD_NOP = 0,
+
+		//
+		CMD_INIT,
+		CMD_SHUTDOWN,
+
+		//
+		CMD_RUNBUFFER,
+
+		// syncronization
+		CMD_SIGNAL,
+
+		// texture commands
+		CMD_TEXTURE_CREATE,
+		CMD_TEXTURE_DESTROY,
+
+		// rendering
+		CMD_CLEAR,
+		CMD_RENDER,
+
+		// swap
+		CMD_SWAP,
+	};
+
+	enum
+	{
+		//
+		PRIMTYPE_INVALID = 0,
+		PRIMTYPE_LINES,	
+		PRIMTYPE_QUADS,
+	};
+
+	enum
+	{
+		BLEND_NONE = 0,
+		BLEND_ALPHA,
+		BLEND_ADDITIVE,
+	};
+
+	struct SPoint { float x, y, z; };
+	struct STexCoord { float u, v; };
+	struct SColor { float r, g, b, a; };
+
+	struct SVertex
+	{
+		SPoint m_Pos;
+		STexCoord m_Tex;
+		SColor m_Color;
+	} ;
+
+	struct SCommand
+	{
+	public:
+		SCommand(unsigned Cmd) : m_Cmd(Cmd), m_Size(0) {}
+		unsigned m_Cmd;
+		unsigned m_Size;
+	};
+
+	struct SState
+	{
+		int m_BlendMode;
+		int m_Texture;
+		SPoint m_ScreenTL;
+		SPoint m_ScreenBR;
+
+		// clip
+		bool m_ClipEnable;
+		int m_ClipX;
+		int m_ClipY;
+		int m_ClipW;
+		int m_ClipH;
+	};
+		
+	struct SCommand_Clear : public SCommand
+	{
+		SCommand_Clear() : SCommand(CMD_CLEAR) {}
+		SColor m_Color;
+	};
+
+
+	struct SCommand_Init : public SCommand
+	{
+		SCommand_Init() : SCommand(CMD_INIT) {}
+		volatile int *m_pResult;
+	};
+
+	struct SCommand_RunBuffer : public SCommand
+	{
+		SCommand_RunBuffer() : SCommand(CMD_RUNBUFFER) {}
+		CCommandBuffer *m_pOtherBuffer;
+	};
+
+	struct SCommand_Render : public SCommand
+	{
+		SCommand_Render() : SCommand(CMD_RENDER) {}
+		SState m_State;
+		unsigned m_PrimType;
+		unsigned m_PrimCount;
+		SVertex *m_pVertices;
+	};
+
+	struct SCommand_Swap : public SCommand
+	{
+		SCommand_Swap() : SCommand(CMD_SWAP) {}
+	};
+	
+	//
+	CCommandBuffer(unsigned CmdBufferSize, unsigned DataBufferSize)
+	: m_CmdBuffer(CmdBufferSize), m_DataBuffer(DataBufferSize)
+	{
+	}
+
+	void *AllocData(unsigned WantedSize)
+	{
+		return m_DataBuffer.Alloc(WantedSize);
+	}
+
+	template<class T>
+	void AddCommand(const T &Command)
+	{
+		SCommand *pCmd = (SCommand *)m_CmdBuffer.Alloc(sizeof(Command));
+		if(!pCmd)
+			return;
+
+		mem_copy(pCmd, &Command, sizeof(Command));
+		pCmd->m_Size = sizeof(Command);
+	}
+
+	SCommand *GetCommand(unsigned *pIndex)
+	{
+		if(*pIndex >= m_CmdBuffer.DataUsed())
+			return NULL;
+
+		SCommand *pCommand = (SCommand *)&m_CmdBuffer.DataPtr()[*pIndex];
+		*pIndex += pCommand->m_Size;
+		return pCommand;
+	}
+
+	void Reset()
+	{
+		m_CmdBuffer.Reset();
+		m_DataBuffer.Reset();
+	}	
+};
+
+class ICommandProcessor
+{
+public:
+	virtual ~ICommandProcessor() {}
+	virtual void RunBuffer(CCommandBuffer *pBuffer) = 0;
+};
+
+
+class CCommandProcessorHandler
+{
+	ICommandProcessor *m_pProcessor;
+	CCommandBuffer * volatile m_pBuffer;
+	volatile bool m_Shutdown;
+	semaphore m_Activity;
+	semaphore m_BufferDone;
+	void *m_pThread;
+
+	static void ThreadFunc(void *pUser);
+
+public:
+	CCommandProcessorHandler();
+	void Start(ICommandProcessor *pProcessor);
+	void RunBuffer(CCommandBuffer *pBuffer);
+	bool IsIdle() const { return m_pBuffer == 0; }
+	void WaitForIdle();
+};
+
+class CGraphics_Threaded : public IEngineGraphics
+{
+	CCommandBuffer::SState m_State;
+	CCommandProcessorHandler m_Handler;
+
+	CCommandBuffer *m_apCommandBuffers[2];
+	CCommandBuffer *m_pCommandBuffer;
+	unsigned m_CurrentCommandBuffer;
+
+	//
+	class IStorage *m_pStorage;
+	class IConsole *m_pConsole;
+
+	enum
+	{
+		MAX_VERTICES = 32*1024,
+		MAX_TEXTURES = 1024*4,
+		
+		DRAWING_QUADS=1,
+		DRAWING_LINES=2
+	};
+
+	CCommandBuffer::SVertex m_aVertices[MAX_VERTICES];
+	int m_NumVertices;
+
+	CCommandBuffer::SColor m_aColor[4];
+	CCommandBuffer::STexCoord m_aTexture[4];
+
+	bool m_RenderEnable;
+
+	float m_Rotation;
+	int m_Drawing;
+	bool m_DoScreenshot;
+	char m_aScreenshotName[128];
+
+	int m_InvalidTexture;
+
+	struct CTexture
+	{
+		GLuint m_Tex;
+		int m_MemSize;
+		int m_Flags;
+		int m_Next;
+	};
+
+	CTexture m_aTextures[MAX_TEXTURES];
+	int m_FirstFreeTexture;
+	int m_TextureMemoryUsage;
+
+	void Flush();
+	void AddVertices(int Count);
+	void Rotate4(const CCommandBuffer::SPoint &rCenter, CCommandBuffer::SVertex *pPoints);
+
+	static unsigned char Sample(int w, int h, const unsigned char *pData, int u, int v, int Offset, int ScaleW, int ScaleH, int Bpp);
+	static unsigned char *Rescale(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
+public:
+	CGraphics_Threaded();
+
+	virtual void ClipEnable(int x, int y, int w, int h);
+	virtual void ClipDisable();
+
+	virtual void BlendNone();
+	virtual void BlendNormal();
+	virtual void BlendAdditive();
+
+	virtual int MemoryUsage() const;
+
+	virtual void MapScreen(float TopLeftX, float TopLeftY, float BottomRightX, float BottomRightY);
+	virtual void GetScreen(float *pTopLeftX, float *pTopLeftY, float *pBottomRightX, float *pBottomRightY);
+
+	virtual void LinesBegin();
+	virtual void LinesEnd();
+	virtual void LinesDraw(const CLineItem *pArray, int Num);
+
+	virtual int UnloadTexture(int Index);
+	virtual int LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags);
+
+	// simple uncompressed RGBA loaders
+	virtual int LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags);
+	virtual int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType);
+
+	void ScreenshotDirect(const char *pFilename);
+
+	virtual void TextureSet(int TextureID);
+
+	virtual void Clear(float r, float g, float b);
+
+	virtual void QuadsBegin();
+	virtual void QuadsEnd();
+	virtual void QuadsSetRotation(float Angle);
+
+	virtual void SetColorVertex(const CColorVertex *pArray, int Num);
+	virtual void SetColor(float r, float g, float b, float a);
+
+	virtual void QuadsSetSubset(float TlU, float TlV, float BrU, float BrV);
+	virtual void QuadsSetSubsetFree(
+		float x0, float y0, float x1, float y1,
+		float x2, float y2, float x3, float y3);
+
+	virtual void QuadsDraw(CQuadItem *pArray, int Num);
+	virtual void QuadsDrawTL(const CQuadItem *pArray, int Num);
+	virtual void QuadsDrawFreeform(const CFreeformItem *pArray, int Num);
+	virtual void QuadsText(float x, float y, float Size, float r, float g, float b, float a, const char *pText);
+
+	virtual void Minimize();
+	virtual void Maximize();
+
+	virtual int WindowActive();
+	virtual int WindowOpen();
+
+	virtual bool Init();
+	virtual void Shutdown();
+
+	virtual void TakeScreenshot(const char *pFilename);
+	virtual void Swap();
+
+	virtual int GetVideoModes(CVideoMode *pModes, int MaxModes);
+
+};
\ No newline at end of file