don't consume all available memory when running opt-pal

This commit is contained in:
David Rose 2004-11-26 23:51:45 +00:00
parent 024da67802
commit 760cdde42d
7 changed files with 172 additions and 25 deletions

View File

@ -49,10 +49,11 @@ TypeHandle EggFile::_type_handle;
EggFile::
EggFile() {
_data = (EggData *)NULL;
_first_txa_match = false;
_default_group = (PaletteGroup *)NULL;
_is_surprise = true;
_is_stale = true;
_first_txa_match = false;
_had_data = false;
}
////////////////////////////////////////////////////////////////////
@ -67,6 +68,7 @@ from_command_line(EggData *data,
const Filename &dest_filename,
const string &egg_comment) {
_data = data;
_had_data = true;
remove_backstage(_data);
// We save the current directory at the time the egg file appeared
@ -468,14 +470,25 @@ choose_placements() {
////////////////////////////////////////////////////////////////////
// Function: EggFile::has_data
// Access: Public
// Description: Returns true if the EggData for this EggFile has ever
// been loaded.
// Description: Returns true if the EggData for this EggFile has
// been loaded, and not yet released.
////////////////////////////////////////////////////////////////////
bool EggFile::
has_data() const {
return (_data != (EggData *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::had_data
// Access: Public
// Description: Returns true if the EggData for this EggFile has ever
// been loaded.
////////////////////////////////////////////////////////////////////
bool EggFile::
had_data() const {
return _had_data;
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::update_egg
// Access: Public
@ -485,6 +498,8 @@ has_data() const {
////////////////////////////////////////////////////////////////////
void EggFile::
update_egg() {
nassertv(_data != (EggData *)NULL);
Textures::iterator ti;
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
TextureReference *reference = (*ti);
@ -515,6 +530,10 @@ remove_egg() {
// is only valid to call this if it has not already been
// read in, e.g. from the command line. Returns true if
// successful, false if there is an error.
//
// This may also be called after a previous call to
// release_egg_data(), in order to re-read the same egg
// file.
////////////////////////////////////////////////////////////////////
bool EggFile::
read_egg() {
@ -529,13 +548,24 @@ read_egg() {
return false;
}
EggData *data = new EggData;
PT(EggData) data = new EggData;
if (!data->read(_source_filename, user_source_filename)) {
// Failure reading.
delete data;
return false;
}
// Extract the set of textures referenced by this egg file.
EggTextureCollection tc;
tc.find_used_textures(_data);
// Make sure each tref name is unique within a given file.
tc.uniquify_trefs();
// Now build up a list of new TextureReference objects that
// represent the textures actually used and their uv range, etc.
Textures new_textures;
// We want to search for filenames based on the egg directory, and
// also on our current directory from which we originally loaded the
// egg file. This is important because it's possible the egg file
@ -551,20 +581,43 @@ read_egg() {
if (!data->load_externals()) {
// Failure reading an external.
delete data;
return false;
}
_data = data;
_had_data = true;
remove_backstage(_data);
// Replace the comment that shows how we first generated the egg
// file.
_data->insert(_data->begin(), new EggComment("", _egg_comment));
// Insert a comment that shows how we first generated the egg file.
PT(EggNode) comment = new EggComment("", _egg_comment);
_data->insert(_data->begin(), comment);
if (!_textures.empty()) {
// If we already have textures, assume we're re-reading the file.
rescan_textures();
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::release_egg_data
// Access: Public
// Description: Releases the memory that was loaded by a previous
// call to read_egg().
////////////////////////////////////////////////////////////////////
void EggFile::
release_egg_data() {
if (_data != (EggData *)NULL) {
_data = NULL;
}
Textures::iterator ti;
for (ti = _textures.begin(); ti != _textures.end(); ++ti) {
TextureReference *reference = (*ti);
reference->release_egg_data();
}
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::write_egg
// Access: Public
@ -663,6 +716,51 @@ remove_backstage(EggGroupNode *node) {
}
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::rescan_textures
// Access: Private
// Description: After reloading the egg file for the second time in a
// given session, rematches the texture pointers with
// the TextureReference objects.
////////////////////////////////////////////////////////////////////
void EggFile::
rescan_textures() {
nassertv(_data != (EggData *)NULL);
// Extract the set of textures referenced by this egg file.
EggTextureCollection tc;
tc.find_used_textures(_data);
// Make sure each tref name is unique within a given file.
tc.uniquify_trefs();
typedef pmap<string, TextureReference *> ByTRefName;
ByTRefName by_tref_name;
for (Textures::const_iterator ti = _textures.begin();
ti != _textures.end();
++ti) {
TextureReference *ref = (*ti);
by_tref_name[ref->get_tref_name()] = ref;
}
EggTextureCollection::iterator eti;
for (eti = tc.begin(); eti != tc.end(); ++eti) {
EggTexture *egg_tex = (*eti);
ByTRefName::const_iterator tni = by_tref_name.find(egg_tex->get_name());
if (tni == by_tref_name.end()) {
// We didn't find this TRef name last time around!
nout << _source_filename.get_basename()
<< " modified during session--TRef " << egg_tex->get_name()
<< " is new!\n";
} else {
TextureReference *ref = (*tni).second;
ref->rebind_egg_data(_data, egg_tex);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggFile::register_with_read_factory
// Access: Public, Static

View File

@ -23,14 +23,13 @@
#include "paletteGroups.h"
#include "textureReference.h"
#include "eggData.h"
#include "filename.h"
#include "namable.h"
#include "typedWritable.h"
#include "pointerTo.h"
#include "pset.h"
class EggData;
class TextureImage;
////////////////////////////////////////////////////////////////////
@ -71,10 +70,12 @@ public:
void choose_placements();
bool has_data() const;
bool had_data() const;
void update_egg();
void remove_egg();
bool read_egg();
void release_egg_data();
bool write_egg();
void write_description(ostream &out, int indent_level = 0) const;
@ -82,9 +83,10 @@ public:
private:
void remove_backstage(EggGroupNode *node);
void rescan_textures();
private:
EggData *_data;
PT(EggData) _data;
Filename _current_directory;
Filename _source_filename;
Filename _dest_filename;
@ -99,6 +101,7 @@ private:
PaletteGroups _complete_groups;
bool _is_surprise;
bool _is_stale;
bool _had_data;
// The TypedWritable interface follows.

View File

@ -666,6 +666,7 @@ read_stale_eggs(bool redo_all) {
} else {
egg_file->scan_textures();
egg_file->choose_placements();
egg_file->release_egg_data();
}
}
}
@ -697,11 +698,23 @@ write_eggs() {
EggFiles::iterator ei;
for (ei = _egg_files.begin(); ei != _egg_files.end(); ++ei) {
EggFile *egg_file = (*ei).second;
if (egg_file->had_data()) {
if (!egg_file->has_data()) {
// Re-read the egg file.
bool read_ok = egg_file->read_egg();
if (!read_ok) {
nout << "Error! Unable to re-read egg file.\n";
okflag = false;
}
}
if (egg_file->has_data()) {
egg_file->update_egg();
if (!egg_file->write_egg()) {
okflag = false;
}
egg_file->release_egg_data();
}
}
}

View File

@ -78,8 +78,7 @@ add_placement(TexturePlacement *placement) {
} else {
DestTextureImage *dest = placement->get_dest();
nassertv(dest != (DestTextureImage *)NULL);
if (dest != (DestTextureImage *)NULL) {
int bytes = count_bytes(dest);
add_texture(texture, bytes);
@ -87,6 +86,7 @@ add_placement(TexturePlacement *placement) {
_num_unplaced++;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: TextureMemoryCounter::report

View File

@ -862,6 +862,8 @@ fill_image(PNMImage &image) {
}
}
}
_texture->release_source_image();
}
////////////////////////////////////////////////////////////////////

View File

@ -154,6 +154,34 @@ from_egg_quick(const TextureReference &other) {
_egg_data = other._egg_data;
}
////////////////////////////////////////////////////////////////////
// Function: TextureReference::release_egg_data
// Access: Public
// Description: Called to indicate that the EggData previously passed
// to from_egg() is about to be deallocated, and all of
// its pointers should be cleared.
////////////////////////////////////////////////////////////////////
void TextureReference::
release_egg_data() {
_egg_tex = NULL;
_egg_data = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TextureReference::rebind_egg_data
// Access: Public
// Description: After an EggData has previously been released via
// release_egg_data(), this can be called to indicate
// that the egg file has been reloaded and we should
// assign the indicated pointers.
////////////////////////////////////////////////////////////////////
void TextureReference::
rebind_egg_data(EggData *data, EggTexture *egg_tex) {
nassertv(_tref_name == egg_tex->get_name());
_egg_data = data;
_egg_tex = egg_tex;
}
////////////////////////////////////////////////////////////////////
// Function: TextureReference::get_egg_file
// Access: Public

View File

@ -51,6 +51,8 @@ public:
void from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex);
void from_egg_quick(const TextureReference &other);
void release_egg_data();
void rebind_egg_data(EggData *data, EggTexture *egg_tex);
EggFile *get_egg_file() const;
SourceTextureImage *get_source() const;
@ -79,6 +81,7 @@ public:
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
private:
bool get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap);
void update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap);