Panda3D
vertexDataBook.cxx
1 // Filename: vertexDataBook.cxx
2 // Created by: drose (16May07)
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 "vertexDataBook.h"
16 #include "mutexHolder.h"
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: VertexDataBook::Constructor
20 // Access: Published
21 // Description:
22 ////////////////////////////////////////////////////////////////////
23 VertexDataBook::
24 VertexDataBook(size_t block_size) {
25  // Make sure the block_size is an integer multiple of the system's
26  // page size.
27  _block_size = memory_hook->round_up_to_page_size(block_size);
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: VertexDataBook::Destructor
32 // Access: Published
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 VertexDataBook::
36 ~VertexDataBook() {
37 }
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: VertexDataBook::count_total_page_size
41 // Access: Published
42 // Description: Returns the total size of all bytes owned by all
43 // pages owned by this book.
44 ////////////////////////////////////////////////////////////////////
45 size_t VertexDataBook::
47  MutexHolder holder(_lock);
48 
49  size_t total = 0;
50  Pages::const_iterator pi;
51  for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
52  total += (*pi)->get_max_size();
53  }
54  return total;
55 }
56 
57 ////////////////////////////////////////////////////////////////////
58 // Function: VertexDataBook::count_total_page_size
59 // Access: Published
60 // Description: Returns the total size of all bytes owned by all
61 // pages owned by this book that have the indicated ram
62 // class.
63 ////////////////////////////////////////////////////////////////////
64 size_t VertexDataBook::
65 count_total_page_size(VertexDataPage::RamClass ram_class) const {
66  MutexHolder holder(_lock);
67 
68  size_t total = 0;
69  Pages::const_iterator pi;
70  for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
71  if ((*pi)->get_ram_class() == ram_class) {
72  total += (*pi)->get_max_size();
73  }
74  }
75  return total;
76 }
77 
78 ////////////////////////////////////////////////////////////////////
79 // Function: VertexDataBook::count_allocated_size
80 // Access: Published
81 // Description: Returns the total size of all bytes allocated within
82 // pages owned by this book.
83 ////////////////////////////////////////////////////////////////////
84 size_t VertexDataBook::
86  MutexHolder holder(_lock);
87 
88  size_t total = 0;
89  Pages::const_iterator pi;
90  for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
91  total += (*pi)->get_total_size();
92  }
93  return total;
94 }
95 
96 ////////////////////////////////////////////////////////////////////
97 // Function: VertexDataBook::count_allocated_size
98 // Access: Published
99 // Description: Returns the total size of all bytes allocated within
100 // pages owned by this book that have the indicated ram
101 // class.
102 ////////////////////////////////////////////////////////////////////
103 size_t VertexDataBook::
104 count_allocated_size(VertexDataPage::RamClass ram_class) const {
105  MutexHolder holder(_lock);
106 
107  size_t total = 0;
108  Pages::const_iterator pi;
109  for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
110  if ((*pi)->get_ram_class() == ram_class) {
111  total += (*pi)->get_total_size();
112  }
113  }
114  return total;
115 }
116 
117 ////////////////////////////////////////////////////////////////////
118 // Function: VertexDataBook::save_to_disk
119 // Access: Published
120 // Description: Writes all pages to disk immediately, just in case
121 // they get evicted later. It makes sense to make this
122 // call just before taking down a loading screen, to
123 // minimize chugs from saving pages inadvertently later.
124 ////////////////////////////////////////////////////////////////////
125 void VertexDataBook::
127  MutexHolder holder(_lock);
128 
129  Pages::iterator pi;
130  for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
131  (*pi)->save_to_disk();
132  }
133 }
134 
135 
136 ////////////////////////////////////////////////////////////////////
137 // Function: VertexDataBook::do_alloc
138 // Access: Private
139 // Description: Allocates and returns a new VertexDataBuffer of the
140 // requested size.
141 //
142 // Assumes the lock is already held.
143 ////////////////////////////////////////////////////////////////////
144 VertexDataBlock *VertexDataBook::
145 do_alloc(size_t size) {
146  // Look for an empty page of the appropriate size. The _pages set
147  // is sorted so that the pages with the smallest available blocks
148  // are at the front.
149 
150  // Create a dummy page to use to search the set.
151  VertexDataPage size_page(size);
152  Pages::iterator pi = _pages.lower_bound(&size_page);
153 
154  // Now we can start from the first element of the set that is
155  // possibly large enough to contain this block, and work up from
156  // there.
157  while (pi != _pages.end()) {
158  Pages::iterator pnext = pi;
159  ++pnext;
160 
161  VertexDataPage *page = (*pi);
162 
163  // Allocating a block may change the page's available contiguous
164  // size, and thereby change its position in the set, invalidating
165  // the iterator pi. This is why we've already computed pnext.
166  VertexDataBlock *block = page->do_alloc(size);
167 
168  if (block != (VertexDataBlock *)NULL) {
169  // This page worked.
170  return block;
171  }
172 
173  // Try the next page.
174  pi = pnext;
175  }
176 
177  // No page was good enough. Create a new page. Make it at least
178  // large enough to hold this requested block.
179  VertexDataPage *page = create_new_page(size);
180  _pages.insert(page);
181 
182  VertexDataBlock *block = page->do_alloc(size);
183  return block;
184 }
A block of bytes that holds one or more VertexDataBlocks.
size_t count_allocated_size() const
Returns the total size of all bytes allocated within pages owned by this book.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition: mutexHolder.h:29
void save_to_disk()
Writes all pages to disk immediately, just in case they get evicted later.
A block of bytes that stores the actual raw vertex data referenced by a GeomVertexArrayData object...
size_t count_total_page_size() const
Returns the total size of all bytes owned by all pages owned by this book.
size_t round_up_to_page_size(size_t size) const
Rounds the indicated size request up to the next larger multiple of page_size, to qualify it for a ca...
Definition: memoryHook.I:128