Browse Source

add preload-textures

David Rose 19 years ago
parent
commit
69d203fe40

+ 10 - 0
panda/src/gobj/config_gobj.cxx

@@ -83,6 +83,16 @@ ConfigVariableBool keep_texture_ram
           "texture image from disk; but it will consume memory somewhat "
           "texture image from disk; but it will consume memory somewhat "
           "wastefully."));
           "wastefully."));
 
 
+ConfigVariableBool preload_textures
+("preload-textures", true,
+ PRC_DESC("When this is true, texture images are loaded from disk as soon "
+          "as the Texture is created from the TexturePool.  When this is "
+          "false, the Texture is created immediately, but the image data "
+          "is not loaded from disk until the Texture is actually rendered "
+          "(or otherwise prepared) on the GSG.  This can help reduce "
+          "wasted memory from Textures that are created but never used "
+          "to render."));
+
 ConfigVariableBool compressed_textures
 ConfigVariableBool compressed_textures
 ("compressed-textures", false,
 ("compressed-textures", false,
  PRC_DESC("Set this to true to compress textures as they are loaded into "
  PRC_DESC("Set this to true to compress textures as they are loaded into "

+ 1 - 0
panda/src/gobj/config_gobj.h

@@ -39,6 +39,7 @@ EXPCL_PANDA istream &operator >> (istream &in, AutoTextureScale &ats);
 // Configure variables for gobj package.
 // Configure variables for gobj package.
 extern EXPCL_PANDA ConfigVariableInt max_texture_dimension;
 extern EXPCL_PANDA ConfigVariableInt max_texture_dimension;
 extern EXPCL_PANDA ConfigVariableBool keep_texture_ram;
 extern EXPCL_PANDA ConfigVariableBool keep_texture_ram;
+extern EXPCL_PANDA ConfigVariableBool preload_textures;
 extern EXPCL_PANDA ConfigVariableBool compressed_textures;
 extern EXPCL_PANDA ConfigVariableBool compressed_textures;
 extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
 extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
 extern EXPCL_PANDA ConfigVariableBool vertex_arrays;
 extern EXPCL_PANDA ConfigVariableBool vertex_arrays;

+ 6 - 4
panda/src/gobj/texture.I

@@ -134,7 +134,8 @@ setup_cube_map(int size, ComponentType component_type,
 INLINE bool Texture::
 INLINE bool Texture::
 read(const Filename &fullpath) {
 read(const Filename &fullpath) {
   clear();
   clear();
-  return do_read(fullpath, Filename(), 0, 0, 0, 0, false, false, NULL);
+  return do_read(fullpath, Filename(), 0, 0, 0, 0, false, false, 
+                 !preload_textures, NULL);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -153,7 +154,8 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
      int primary_file_num_channels, int alpha_file_channel) {
      int primary_file_num_channels, int alpha_file_channel) {
   clear();
   clear();
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
-		 alpha_file_channel, 0, 0, false, false, NULL);
+		 alpha_file_channel, 0, 0, false, false, !preload_textures, 
+                 NULL);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -172,7 +174,7 @@ read(const Filename &fullpath, int z, int n,
   ++_properties_modified;
   ++_properties_modified;
   ++_image_modified;
   ++_image_modified;
   return do_read(fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps,
   return do_read(fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps,
-                 NULL);
+                 !preload_textures, NULL);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -253,7 +255,7 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
   ++_image_modified;
   ++_image_modified;
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
   return do_read(fullpath, alpha_fullpath, primary_file_num_channels,
 		 alpha_file_channel, z, n, read_pages, read_mipmaps,
 		 alpha_file_channel, z, n, read_pages, read_mipmaps,
-                 record);
+                 !preload_textures, record);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 38 - 12
panda/src/gobj/texture.cxx

@@ -1747,7 +1747,11 @@ bool Texture::
 do_read(const Filename &fullpath, const Filename &alpha_fullpath,
 do_read(const Filename &fullpath, const Filename &alpha_fullpath,
         int primary_file_num_channels, int alpha_file_channel,
         int primary_file_num_channels, int alpha_file_channel,
         int z, int n, bool read_pages, bool read_mipmaps,
         int z, int n, bool read_pages, bool read_mipmaps,
-        BamCacheRecord *record) {
+        bool header_only, BamCacheRecord *record) {
+  if (record != (BamCacheRecord *)NULL) {
+    header_only = false;
+  }
+
   if ((z == 0 || read_pages) && (n == 0 || read_mipmaps)) {
   if ((z == 0 || read_pages) && (n == 0 || read_mipmaps)) {
     // When we re-read the page 0 of the base image, we clear
     // When we re-read the page 0 of the base image, we clear
     // everything and start over.
     // everything and start over.
@@ -1829,7 +1833,7 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
       while ((z_size == 0 && (vfs->exists(file) || z == 0)) ||
       while ((z_size == 0 && (vfs->exists(file) || z == 0)) ||
              (z_size != 0 && z < z_size)) {
              (z_size != 0 && z < z_size)) {
         if (!do_read_one(file, alpha_file, z, n, primary_file_num_channels,
         if (!do_read_one(file, alpha_file, z, n, primary_file_num_channels,
-                         alpha_file_channel, record)) {
+                         alpha_file_channel, header_only, record)) {
           return false;
           return false;
         }
         }
         ++z;
         ++z;
@@ -1866,7 +1870,7 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
     while ((z_size == 0 && (vfs->exists(file) || z == 0)) ||
     while ((z_size == 0 && (vfs->exists(file) || z == 0)) ||
            (z_size != 0 && z < z_size)) {
            (z_size != 0 && z < z_size)) {
       if (!do_read_one(file, alpha_file, z, 0, primary_file_num_channels,
       if (!do_read_one(file, alpha_file, z, 0, primary_file_num_channels,
-                       alpha_file_channel, record)) {
+                       alpha_file_channel, header_only, record)) {
         return false;
         return false;
       }
       }
       ++z;
       ++z;
@@ -1894,7 +1898,7 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
            (n_size != 0 && n < n_size)) {
            (n_size != 0 && n < n_size)) {
       if (!do_read_one(file, alpha_file, z, n, 
       if (!do_read_one(file, alpha_file, z, n, 
                        primary_file_num_channels, alpha_file_channel,
                        primary_file_num_channels, alpha_file_channel,
-                       record)) {
+                       header_only, record)) {
         return false;
         return false;
       }
       }
       ++n;
       ++n;
@@ -1913,7 +1917,7 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
     // Just an ordinary read of one file.
     // Just an ordinary read of one file.
     if (!do_read_one(fullpath, alpha_fullpath, z, n, 
     if (!do_read_one(fullpath, alpha_fullpath, z, n, 
                      primary_file_num_channels, alpha_file_channel,
                      primary_file_num_channels, alpha_file_channel,
-                     record)) {
+                     header_only, record)) {
       return false;
       return false;
     }
     }
   }    
   }    
@@ -1922,6 +1926,13 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
   _has_read_mipmaps = read_mipmaps;
   _has_read_mipmaps = read_mipmaps;
   _num_mipmap_levels_read = _ram_images.size();
   _num_mipmap_levels_read = _ram_images.size();
 
 
+  if (header_only) {
+    // If we were only supposed to be checking the image header
+    // information, don't let the Texture think that it's got the
+    // image now.
+    clear_ram_image();
+  }
+
   return true;
   return true;
 }
 }
 
 
@@ -1935,20 +1946,29 @@ do_read(const Filename &fullpath, const Filename &alpha_fullpath,
 bool Texture::
 bool Texture::
 do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
 do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
             int z, int n, int primary_file_num_channels, int alpha_file_channel,
             int z, int n, int primary_file_num_channels, int alpha_file_channel,
-            BamCacheRecord *record) {
+            bool header_only, BamCacheRecord *record) {
   if (record != (BamCacheRecord *)NULL) {
   if (record != (BamCacheRecord *)NULL) {
+    nassertr(!header_only, false);
     record->add_dependent_file(fullpath);
     record->add_dependent_file(fullpath);
   }
   }
 
 
   PNMImage image;
   PNMImage image;
-  if (textures_header_only) {
+  if (header_only || textures_header_only) {
     if (!image.read_header(fullpath)) {
     if (!image.read_header(fullpath)) {
       gobj_cat.error()
       gobj_cat.error()
         << "Texture::read() - couldn't read: " << fullpath << endl;
         << "Texture::read() - couldn't read: " << fullpath << endl;
       return false;
       return false;
     }
     }
-    image = PNMImage(1, 1, image.get_num_channels(), image.get_maxval(),
-                     image.get_type());
+    int x_size = image.get_x_size();
+    int y_size = image.get_y_size();
+    if (textures_header_only) {
+      // In this mode, we never intend to load the actual texture
+      // image anyway, so we don't even need to make the size right.
+      x_size = 1;
+      y_size = 1;
+    }
+    image = PNMImage(x_size, y_size, image.get_num_channels(), 
+                     image.get_maxval(), image.get_type());
     image.fill(0.2, 0.3, 1.0);
     image.fill(0.2, 0.3, 1.0);
     if (image.has_alpha()) {
     if (image.has_alpha()) {
       image.alpha_fill(1.0);
       image.alpha_fill(1.0);
@@ -1968,13 +1988,19 @@ do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
       record->add_dependent_file(alpha_fullpath);
       record->add_dependent_file(alpha_fullpath);
     }
     }
 
 
-    if (textures_header_only) {
+    if (header_only || textures_header_only) {
       if (!alpha_image.read_header(alpha_fullpath)) {
       if (!alpha_image.read_header(alpha_fullpath)) {
         gobj_cat.error()
         gobj_cat.error()
           << "Texture::read() - couldn't read: " << alpha_fullpath << endl;
           << "Texture::read() - couldn't read: " << alpha_fullpath << endl;
         return false;
         return false;
       }
       }
-      alpha_image = PNMImage(1, 1, alpha_image.get_num_channels(),
+      int x_size = alpha_image.get_x_size();
+      int y_size = alpha_image.get_y_size();
+      if (textures_header_only) {
+        x_size = 1;
+        y_size = 1;
+      }
+      alpha_image = PNMImage(x_size, y_size, alpha_image.get_num_channels(),
                              alpha_image.get_maxval(),
                              alpha_image.get_maxval(),
                              alpha_image.get_type());
                              alpha_image.get_type());
       alpha_image.fill(1.0);
       alpha_image.fill(1.0);
@@ -2333,7 +2359,7 @@ reload_ram_image() {
 
 
   do_read(get_fullpath(), get_alpha_fullpath(),
   do_read(get_fullpath(), get_alpha_fullpath(),
           _primary_file_num_channels, _alpha_file_channel,
           _primary_file_num_channels, _alpha_file_channel,
-          z, n, _has_read_pages, _has_read_mipmaps, NULL);
+          z, n, _has_read_pages, _has_read_mipmaps, false, NULL);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 3 - 2
panda/src/gobj/texture.h

@@ -29,6 +29,7 @@
 #include "updateSeq.h"
 #include "updateSeq.h"
 #include "pStatCollectorForward.h"
 #include "pStatCollectorForward.h"
 #include "pmap.h"
 #include "pmap.h"
+#include "config_gobj.h"
 
 
 class PNMImage;
 class PNMImage;
 class TextureContext;
 class TextureContext;
@@ -377,10 +378,10 @@ protected:
   virtual bool do_read(const Filename &fullpath, const Filename &alpha_fullpath,
   virtual bool do_read(const Filename &fullpath, const Filename &alpha_fullpath,
                        int primary_file_num_channels, int alpha_file_channel,
                        int primary_file_num_channels, int alpha_file_channel,
                        int z, int n, bool read_pages, bool read_mipmaps,
                        int z, int n, bool read_pages, bool read_mipmaps,
-                       BamCacheRecord *record);
+                       bool header_only, BamCacheRecord *record);
   virtual bool do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
   virtual bool do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
                            int z, int n, int primary_file_num_channels, int alpha_file_channel,
                            int z, int n, int primary_file_num_channels, int alpha_file_channel,
-                           BamCacheRecord *record);
+                           bool header_only, BamCacheRecord *record);
   bool do_write(const Filename &fullpath, int z, int n, 
   bool do_write(const Filename &fullpath, int z, int n, 
                 bool write_pages, bool write_mipmaps) const;
                 bool write_pages, bool write_mipmaps) const;
   bool do_write_one(const Filename &fullpath, int z, int n) const;
   bool do_write_one(const Filename &fullpath, int z, int n) const;