summaryrefslogtreecommitdiff
path: root/indra/llmath/llvolumemgr.h
blob: c28ffce6311e50506edcaaf9ec847114d907eda5 (plain)
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
/** 
 * @file llvolumemgr.h
 * @brief LLVolumeMgr class.
 *
 * $LicenseInfo:firstyear=2002&license=viewergpl$
 * 
 * Copyright (c) 2002-2007, Linden Research, Inc.
 * 
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlife.com/developers/opensource/gplv2
 * 
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at http://secondlife.com/developers/opensource/flossexception
 * 
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 * 
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#ifndef LL_LLVOLUMEMGR_H
#define LL_LLVOLUMEMGR_H

#include <map>

#include "llvolume.h"
#include "llmemory.h"
#include "llthread.h"

class LLVolumeParams;
class LLVolumeLODGroup;

class LLVolumeLODGroup : public LLThreadSafeRefCount
{
public:
	enum
	{
		NUM_LODS = 4
	};

	LLVolumeLODGroup(const LLVolumeParams &params);

	BOOL derefLOD(LLVolume *volumep);
	static S32 getDetailFromTan(const F32 tan_angle);
	static void getDetailProximity(const F32 tan_angle, F32 &to_lower, F32& to_higher);
	static F32 getVolumeScaleFromDetail(const S32 detail);

	LLVolume *getLOD(const S32 detail);
	const LLVolumeParams& getParams() const { return mParams; };

	F32	dump();
	friend std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup);

#ifdef DEBUG_VOLUME
	S32 getTotalVolumeRefCount() const;
#endif

protected:
	virtual ~LLVolumeLODGroup();
	void destroy();
	
protected:
	LLVolumeParams mParams;

	S32 mLODRefs[NUM_LODS];
	LLPointer<LLVolume> mVolumeLODs[NUM_LODS];
	static F32 mDetailThresholds[NUM_LODS];
	static F32 mDetailScales[NUM_LODS];
	S32		mAccessCount[NUM_LODS];
};

class LLVolumeMgr
{
//public:
//	static void initClass();
//	static BOOL cleanupClass();
	
public:
	LLVolumeMgr();
	virtual ~LLVolumeMgr();
	BOOL cleanup();			// Cleanup all volumes being managed, returns TRUE if no dangling references

	virtual LLVolumeLODGroup* getGroup( const LLVolumeParams& volume_params ) const;

	// whatever calls getVolume() never owns the LLVolume* and
	// cannot keep references for long since it may be deleted
	// later.  For best results hold it in an LLPointer<LLVolume>.
	LLVolume *getVolume(const LLVolumeParams &volume_params, const S32 detail);

	void cleanupVolume(LLVolume *volumep);

	void dump();

	// manually call this for mutex magic
	void useMutex();

#ifdef DEBUG_VOLUME
	S32 getTotalRefCount() const;
	S32 getGroupCount() const;
#endif
	friend std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr);

protected:
	virtual LLVolumeLODGroup* createNewGroup(const LLVolumeParams& volume_params);

protected:
	typedef std::map<const LLVolumeParams*, LLVolumeLODGroup*, LLVolumeParams::compare> volume_lod_group_map_t;
	typedef volume_lod_group_map_t::const_iterator volume_lod_group_map_iter;
	volume_lod_group_map_t mVolumeLODGroups;

	LLMutex* mDataMutex;

	// We need to be able to disable threadsafe checks to prevent 
	// some unit_tests from blocking on failure
	bool mThreadSafe;
};

//extern LLVolumeMgr* gVolumeMgr;

#endif // LL_LLVOLUMEMGR_H