aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/togl/linuxwin/glmgrbasics.h
blob: a32938ad086f055e55f0ca8e2faf972f668267a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
//========= Copyright Valve Corporation, All rights reserved. ============//
//                       TOGL CODE LICENSE
//
//  Copyright 2011-2014 Valve Corporation
//  All Rights Reserved.
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//
// glmgrbasics.h
//	types, common headers, forward declarations, utilities
//
//===============================================================================

#ifndef GLMBASICS_H
#define	GLMBASICS_H

#pragma once

#ifdef USE_SDL
#include "SDL_opengl.h"
#endif

#ifdef OSX
	#include <OpenGL/CGLTypes.h>
	#include <OpenGL/CGLRenderers.h>
	#include <OpenGL/CGLCurrent.h>
	#include <AvailabilityMacros.h>

#ifndef MAC_OS_X_VERSION_10_9
	#include <OpenGL/CGLProfiler.h>
	#include <ApplicationServices/ApplicationServices.h>
#endif
#endif

#include "tier0/platform.h"

#include "bitmap/imageformat.h"
#include "bitvec.h"
#include "tier1/checksum_md5.h"
#include "tier1/utlvector.h"
#include "tier1/convar.h"

#include <sys/stat.h>

#include "dxabstract_types.h"

struct GLMRect;
typedef void *PseudoGLContextPtr;

// types

	// 3-d integer box (used for texture lock/unlock etc)
struct	GLMRegion
{
	int	xmin,xmax;
	int	ymin,ymax;
	int zmin,zmax;
};

struct GLMRect	// follows GL convention - if coming from the D3D rect you will need to fiddle the Y's
{
    int xmin;	// left
    int ymin;	// bottom
    int xmax;	// right
    int ymax;	// top
};

// macros

//#define	GLMassert(x)	assert(x)

// forward decls
class	GLMgr;				// singleton
class	GLMContext;			// GL context
class	CGLMContextTester;	// testing class
class	CGLMTex;
class	CGLMFBO;
class	CGLMProgram;
class	CGLMBuffer;


// utilities

typedef enum
{
	// D3D codes
	eD3D_DEVTYPE,
	eD3D_FORMAT,
	eD3D_RTYPE,
	eD3D_USAGE,
	eD3D_RSTATE,	// render state
	eD3D_SIO,		// D3D shader bytecode
	eD3D_VTXDECLUSAGE,
	
	// CGL codes
	eCGL_RENDID,
	
	// OpenGL error codes
	eGL_ERROR,
	
	// OpenGL enums
	eGL_ENUM,
	eGL_RENDERER

}	GLMThing_t;

// these will look at the string to guess its flavor: <, >, ---, -M-, -S- 
#ifdef TOGL_DLL_EXPORT
	DLL_EXPORT const char* GLMDecode( GLMThing_t type, unsigned long value );		// decode a numeric const
#else
	DLL_IMPORT const char* GLMDecode( GLMThing_t type, unsigned long value );		// decode a numeric const
#endif
		
const char* GLMDecodeMask( GLMThing_t type, unsigned long value );	// decode a bitmask

FORCEINLINE void GLMStop( void ) { DXABSTRACT_BREAK_ON_ERROR(); }

void GLMEnableTrace( bool on );

//===============================================================================
// output functions

// expose these in release now
// Mimic PIX events so we can decorate debug spew
DLL_EXPORT void	GLMBeginPIXEvent( const char *str );
DLL_EXPORT void	GLMEndPIXEvent( void );

class CScopedGLMPIXEvent
{
	CScopedGLMPIXEvent( const CScopedGLMPIXEvent & );
	CScopedGLMPIXEvent& operator= ( const CScopedGLMPIXEvent & );
public:
	inline CScopedGLMPIXEvent( const char *pName ) { GLMBeginPIXEvent( pName ); }
	inline ~CScopedGLMPIXEvent() { GLMEndPIXEvent( ); }
};

#if GLMDEBUG


//===============================================================================
// classes

// helper class making function tracking easier to wire up

class GLMFuncLogger
{
	public:
	
		// simple function log
		GLMFuncLogger( const char *funcName )
		{
			m_funcName = funcName;
			m_earlyOut = false;
			
			GLMPrintf( ">%s", m_funcName );
		};
		
		// more advanced version lets you pass args (i.e. called parameters or anything else of interest)
		// no macro for this one, since no easy way to pass through the args as well as the funcname
		GLMFuncLogger( const char *funcName, char *fmt, ... )
		{
			m_funcName = funcName;
			m_earlyOut = false;

			// this acts like GLMPrintf here
			// all the indent policy is down in GLMPrintfVA
			// which means we need to inject a ">" at the front of the format string to make this work... sigh.
			
			char modifiedFmt[2000];
			modifiedFmt[0] = '>';
			strcpy( modifiedFmt+1, fmt );
			
			va_list	vargs;
			va_start(vargs, fmt);
			GLMPrintfVA( modifiedFmt, vargs );
			va_end( vargs );
		}
		
		~GLMFuncLogger( )
		{
			if (m_earlyOut)
			{
				GLMPrintf( "<%s (early out)", m_funcName );
			}
			else
			{
				GLMPrintf( "<%s", m_funcName );
			}
		};
	
		void EarlyOut( void )
		{
			m_earlyOut = true;
		};
		
		const char *m_funcName;				// set at construction time
		bool m_earlyOut;
};

// handy macro to go with the function tracking class
#define	GLM_FUNC			GLMFuncLogger _logger_ ( __FUNCTION__ )
#else
#define	GLM_FUNC            tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "%s", __FUNCTION__ )
#endif


// class to keep an in-memory mirror of a file which may be getting edited during run
class CGLMFileMirror
{
public:
	CGLMFileMirror( char *fullpath );		// just associates mirror with file. if file exists it will be read.
											//if non existent it will be created with size zero
	~CGLMFileMirror( );
	
	bool		HasData( void );								// see if data avail
	void		GetData( char **dataPtr, uint *dataSizePtr );	// read it out
	void		SetData( char *data, uint dataSize );			// put data in (and write it to disk)
	bool		PollForChanges( void );							// check disk copy.  If different, read it back in and return true.
	
	void		UpdateStatInfo( void );		// make sure stat info is current for our file
	void		ReadFile( void );
	void		WriteFile( void );

	void		OpenInEditor( bool foreground=false );			// pass TRUE if you would like the editor to pop to foreground
	
	/// how about a "wait for change" method..

	char		*m_path;	// fullpath to file
	bool		m_exists;
	struct stat	m_stat;		// stat results for the file (last time checked)
	
	char		*m_data;	// content of file
	uint		m_size;		// length of content

};

// class based on the file mirror, that makes it easy to edit them outside the app.

// it receives an initial block of text from the engine, and hashes it. ("orig")
// it munges it by duplicating all the text after the "!!" line, and appending it in commented form. ("munged")
// a mirror file is activated, using a filename based on the hash from the orig text.
// if there is already content on disk matching that filename, use that content *unless* the 'blitz' parameter is set.
//		(i.e. engine is instructing this subsystem to wipe out any old/modified variants of the text)


class CGLMEditableTextItem
{
public:
					CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix = NULL );		// create a text blob from text source, optional filename suffix
					~CGLMEditableTextItem( );

	bool			HasData( void );
	bool			PollForChanges( void );									// return true if stale i.e. you need to get a new edition
	void			GetCurrentText( char **textOut, uint *sizeOut );		// query for read access to the active blob (could be the original, could be external edited copy)
	void			OpenInEditor( bool foreground=false );									// call user attention to this text

	// internal methods
	void			GenHashOfOrigText( void );
	void			GenBaseNameAndFullPath( char *prefix, char *suffix );
	void			GenMungedText( bool fromMirror );

	// members
	// orig
	uint			m_origSize;
	char			*m_origText;						// what was submitted
	unsigned char	m_origDigest[MD5_DIGEST_LENGTH];	// digest of what was submitted
	
	// munged
	uint			m_mungedSize;
	char			*m_mungedText;						// re-processed edition, initial content submission to the file mirror

	// mirror
	char			*m_mirrorBaseName;					// generated from the hash of the orig text, plus the label / prefix
	char			*m_mirrorFullPath;					// base name 
	CGLMFileMirror	*m_mirror;							// file mirror itself.  holds "official" copy for GetCurrentText to return.
};


// debug font
extern unsigned char g_glmDebugFontMap[16384];

// class for cracking multi-part text blobs
// sections are demarcated by beginning-of-line markers submitted in a table by the caller

struct GLMTextSection
{
	int		m_markerIndex;		// based on table of markers passed in to constructor
	uint	m_textOffset;		// where is the text - offset
	int		m_textLength;		// how big is the section
};

class CGLMTextSectioner
{
public:
					CGLMTextSectioner( char *text, int textSize, const char **markers );		// constructor finds all the sections
					~CGLMTextSectioner( );
					
	int				Count( void );			// how many sections found
	void			GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut );
		// find section, size, what marker
		// note that more than one section can be marked similarly.
		// so policy isn't made here, you walk the sections and decide what to do if there are dupes.
	
	//members
	
	//section table
	CUtlVector< GLMTextSection >	m_sectionTable;
};

#ifndef OSX
void GLMGPUTimestampManagerInit();
void GLMGPUTimestampManagerDeinit();
void GLMGPUTimestampManagerTick();
#endif

#endif // GLMBASICS_H