Panda3D
Loading...
Searching...
No Matches
graphicsStateGuardianBase.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file graphicsStateGuardianBase.cxx
10 * @author drose
11 * @date 1999-10-06
12 */
13
15#include "lightMutexHolder.h"
16#include <algorithm>
17
18AtomicAdjust::Pointer GraphicsStateGuardianBase::_gsg_list;
19UpdateSeq GraphicsStateGuardianBase::_generated_shader_seq;
20TypeHandle GraphicsStateGuardianBase::_type_handle;
21
22/**
23 * Returns a pointer to the "default" GSG. This is typically the first GSG
24 * created in an application; in a single-window application, it will be the
25 * only GSG. This GSG is used to determine default optimization choices for
26 * loaded geometry.
27 *
28 * The return value may be NULL if a GSG has not been created.
29 */
32 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
33 if (gsg_list == nullptr) {
34 // Nobody created a GSG list, so we won't have any GSGs either.
35 return nullptr;
36 }
37 LightMutexHolder holder(gsg_list->_lock);
38 return gsg_list->_default_gsg;
39}
40
41/**
42 * Specifies a particular GSG to use as the "default" GSG. See
43 * get_default_gsg().
44 */
47 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
48 if (gsg_list == nullptr) {
49 // Nobody ever created a GSG list. How could we have a GSG?
50 nassertv(false);
51 return;
52 }
53
54 LightMutexHolder holder(gsg_list->_lock);
55 if (find(gsg_list->_gsgs.begin(), gsg_list->_gsgs.end(), default_gsg) == gsg_list->_gsgs.end()) {
56 // The specified GSG doesn't exist or it has already destructed.
57 nassert_raise("GSG not found or already destructed");
58 return;
59 }
60
61 gsg_list->_default_gsg = default_gsg;
62}
63
64/**
65 * Returns the total number of GSG's in the universe.
66 */
69 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
70 if (gsg_list == nullptr) {
71 // Nobody created a GSG list, so we won't have any GSGs either.
72 return 0;
73 }
74 LightMutexHolder holder(gsg_list->_lock);
75 return gsg_list->_gsgs.size();
76}
77
78/**
79 * Returns the nth GSG in the universe. GSG's automatically add themselves
80 * and remove themselves from this list as they are created and destroyed.
81 */
83get_gsg(size_t n) {
84 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
85 nassertr(gsg_list != nullptr, nullptr);
86
87 LightMutexHolder holder(gsg_list->_lock);
88 nassertr(n < gsg_list->_gsgs.size(), nullptr);
89 return gsg_list->_gsgs[n];
90}
91
92/**
93 * Called by a GSG after it has been initialized, to add a new GSG to the
94 * available list.
95 */
98 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
99 if (gsg_list == nullptr) {
100 gsg_list = new GSGList;
101 gsg_list->_default_gsg = nullptr;
102
103 GSGList *orig_gsg_list = (GSGList *)
104 AtomicAdjust::compare_and_exchange_ptr(_gsg_list, nullptr, gsg_list);
105
106 if (orig_gsg_list != nullptr) {
107 // Another thread beat us to it. No problem, we'll use that.
108 delete gsg_list;
109 gsg_list = orig_gsg_list;
110 }
111 }
112
113 LightMutexHolder holder(gsg_list->_lock);
114
115 if (find(gsg_list->_gsgs.begin(), gsg_list->_gsgs.end(), gsg) != gsg_list->_gsgs.end()) {
116 // Already on the list.
117 return;
118 }
119
120 gsg_list->_gsgs.push_back(gsg);
121
122 if (gsg_list->_default_gsg == nullptr) {
123 gsg_list->_default_gsg = gsg;
124 }
125}
126
127/**
128 * Called by a GSG destructor to remove a GSG from the available list.
129 */
132 GSGList *gsg_list = (GSGList *)AtomicAdjust::get_ptr(_gsg_list);
133 if (gsg_list == nullptr) {
134 // No GSGs were added yet, or the program is destructing anyway.
135 return;
136 }
137
138 LightMutexHolder holder(gsg_list->_lock);
139
140 GSGList::GSGs::iterator gi;
141 gi = find(gsg_list->_gsgs.begin(), gsg_list->_gsgs.end(), gsg);
142 if (gi == gsg_list->_gsgs.end()) {
143 // Already removed, or never added.
144 return;
145 }
146
147 gsg_list->_gsgs.erase(gi);
148
149 if (gsg_list->_default_gsg == gsg) {
150 if (!gsg_list->_gsgs.empty()) {
151 gsg_list->_default_gsg = *gsg_list->_gsgs.begin();
152 } else {
153 gsg_list->_default_gsg = nullptr;
154 }
155 }
156}
static Pointer compare_and_exchange_ptr(Pointer &mem, Pointer old_value, Pointer new_value)
Atomic compare and exchange.
static Pointer get_ptr(const Pointer &var)
Atomically retrieves the snapshot value of the indicated variable.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
get_num_gsgs
Returns the total number of GSG's in the universe.
static void set_default_gsg(GraphicsStateGuardianBase *default_gsg)
Specifies a particular GSG to use as the "default" GSG.
static GraphicsStateGuardianBase * get_default_gsg()
Returns a pointer to the "default" GSG.
static void remove_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG destructor to remove a GSG from the available list.
get_gsg
Returns the nth GSG in the universe.
static void add_gsg(GraphicsStateGuardianBase *gsg)
Called by a GSG after it has been initialized, to add a new GSG to the available list.
Similar to MutexHolder, but for a light mutex.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is a sequence number that increments monotonically.
Definition updateSeq.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.