Panda3D
 All Classes Functions Variables Enumerations
bufferResidencyTracker.cxx
1 // Filename: bufferResidencyTracker.cxx
2 // Created by: drose (16Mar06)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "bufferResidencyTracker.h"
16 #include "bufferContext.h"
17 #include "clockObject.h"
18 #include "indent.h"
19 
20 PStatCollector BufferResidencyTracker::_gmem_collector("Graphics memory");
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: BufferResidencyTracker::Constructor
24 // Access: Public
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 BufferResidencyTracker::
28 BufferResidencyTracker(const string &pgo_name, const string &type_name) :
29  _pgo_collector(_gmem_collector, pgo_name),
30  _active_resident_collector(PStatCollector(_pgo_collector, "Active"), type_name),
31  _active_nonresident_collector(PStatCollector(_pgo_collector, "Thrashing"), type_name),
32  _inactive_resident_collector(PStatCollector(_pgo_collector, "Inactive"), type_name),
33  _inactive_nonresident_collector(PStatCollector(_pgo_collector, "Nonresident"), type_name),
34  _active_frame(0)
35 {
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: BufferResidencyTracker::Destructor
40 // Access: Public
41 // Description:
42 ////////////////////////////////////////////////////////////////////
43 BufferResidencyTracker::
44 ~BufferResidencyTracker() {
45  _inactive_nonresident_collector.set_level(0);
46  _active_nonresident_collector.set_level(0);
47  _inactive_resident_collector.set_level(0);
48  _active_resident_collector.set_level(0);
49 }
50 
51 ////////////////////////////////////////////////////////////////////
52 // Function: BufferResidencyTracker::begin_frame
53 // Access: Public
54 // Description: To be called at the beginning of a frame, this
55 // initializes the active/inactive status.
56 ////////////////////////////////////////////////////////////////////
58 begin_frame(Thread *current_thread) {
59  int this_frame = ClockObject::get_global_clock()->get_frame_count(current_thread);
60  if (_active_frame != this_frame) {
61  _active_frame = this_frame;
62 
63  // Move all of the previously "active" objects into "inactive".
64  // They'll get re-added to "active" as they get rendered.
65  move_inactive(_chains[S_inactive_nonresident],
66  _chains[S_active_nonresident]);
67  move_inactive(_chains[S_inactive_resident],
68  _chains[S_active_resident]);
69  }
70 }
71 
72 ////////////////////////////////////////////////////////////////////
73 // Function: BufferResidencyTracker::end_frame
74 // Access: Public
75 // Description: To be called at the end of a frame, this
76 // updates the PStatCollectors appropriately.
77 ////////////////////////////////////////////////////////////////////
79 end_frame(Thread *current_thread) {
80  _inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size());
81  _active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size());
82  _inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size());
83  _active_resident_collector.set_level(_chains[S_active_resident].get_total_size());
84 }
85 
86 ////////////////////////////////////////////////////////////////////
87 // Function: BufferResidencyTracker::set_levels
88 // Access: Public
89 // Description: Resets the pstats levels to their appropriate values,
90 // possibly in the middle of a frame.
91 ////////////////////////////////////////////////////////////////////
94  _inactive_nonresident_collector.set_level(_chains[S_inactive_nonresident].get_total_size());
95  _active_nonresident_collector.set_level(_chains[S_active_nonresident].get_total_size());
96  _inactive_resident_collector.set_level(_chains[S_inactive_resident].get_total_size());
97  _active_resident_collector.set_level(_chains[S_active_resident].get_total_size());
98 }
99 
100 ////////////////////////////////////////////////////////////////////
101 // Function: BufferResidencyTracker::write
102 // Access: Public
103 // Description:
104 ////////////////////////////////////////////////////////////////////
105 void BufferResidencyTracker::
106 write(ostream &out, int indent_level) const {
107  if (_chains[S_inactive_nonresident].get_count() != 0) {
108  indent(out, indent_level) << "Inactive nonresident:\n";
109  _chains[S_inactive_nonresident].write(out, indent_level + 2);
110  }
111 
112  if (_chains[S_active_nonresident].get_count() != 0) {
113  indent(out, indent_level) << "Active nonresident:\n";
114  _chains[S_active_nonresident].write(out, indent_level + 2);
115  }
116 
117  if (_chains[S_inactive_resident].get_count() != 0) {
118  indent(out, indent_level) << "Inactive resident:\n";
119  _chains[S_inactive_resident].write(out, indent_level + 2);
120  }
121 
122  if (_chains[S_active_resident].get_count() != 0) {
123  indent(out, indent_level) << "Active resident:\n";
124  _chains[S_active_resident].write(out, indent_level + 2);
125  }
126 }
127 
128 ////////////////////////////////////////////////////////////////////
129 // Function: BufferResidencyTracker::move_inactive
130 // Access: Private
131 // Description: Moves all of the "active" objects into "inactive".
132 ////////////////////////////////////////////////////////////////////
133 void BufferResidencyTracker::
134 move_inactive(BufferContextChain &inactive, BufferContextChain &active) {
135  BufferContext *node = active.get_first();
136  while (node != (BufferContext *)NULL) {
137  nassertv((node->_residency_state & S_active) != 0);
138  node->_residency_state &= ~S_active;
139  node = node->get_next();
140  }
141 
142  inactive.take_from(active);
143 }
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
Definition: clockObject.I:271
BufferContext * get_next() const
This can be used along with BufferContextChain::get_first() to walk through the list of objects store...
void set_levels()
Resets the pstats levels to their appropriate values, possibly in the middle of a frame...
This is a base class for those kinds of SavedContexts that occupy an easily-measured (and substantial...
Definition: bufferContext.h:41
This class maintains a linked list of BufferContexts that might be allocated on the graphics card in ...
A lightweight class that represents a single element that may be timed and/or counted via stats...
BufferContext * get_first()
Returns the first BufferContext object stored in the tracker.
int get_frame_count(Thread *current_thread=Thread::get_current_thread()) const
Returns the number of times tick() has been called since the ClockObject was created, or since it was last reset.
Definition: clockObject.I:113
A thread; that is, a lightweight process.
Definition: thread.h:51
void take_from(BufferContextChain &other)
Moves all of the BufferContexts from the other tracker onto this one.
void begin_frame(Thread *current_thread)
To be called at the beginning of a frame, this initializes the active/inactive status.
void end_frame(Thread *current_thread)
To be called at the end of a frame, this updates the PStatCollectors appropriately.