Jelajahi Sumber

better thread-handling in textures

David Rose 17 tahun lalu
induk
melakukan
3bd0d132b3

+ 432 - 102
panda/src/gobj/texture.I

@@ -13,6 +13,54 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::make_copy
+//       Access: Published
+//  Description: Returns a new copy of the same Texture.  This copy,
+//               if applied to geometry, will be copied into texture
+//               as a separate texture from the original, so it will
+//               be duplicated in texture memory (and may be
+//               independently modified if desired).
+//
+//               If the Texture is a VideoTexture, the resulting
+//               duplicate may be animated independently of the
+//               original.
+////////////////////////////////////////////////////////////////////
+INLINE PT(Texture) Texture::
+make_copy() {
+  MutexHolder holder(_lock);
+  return do_make_copy();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::clear
+//       Access: Published, Virtual
+//  Description: Reinitializes the texture to its default, empty
+//               state (except for the name).
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+clear() {
+  MutexHolder holder(_lock);
+  do_clear();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::setup_texture
+//       Access: Published
+//  Description: Sets the texture to the indicated type and
+//               dimensions, presumably in preparation for calling
+//               read() or load(), or set_ram_image() or
+//               modify_ram_image().
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+setup_texture(Texture::TextureType texture_type, int x_size, int y_size,
+              int z_size, Texture::ComponentType component_type,
+              Texture::Format format) {
+  MutexHolder holder(_lock);
+  do_setup_texture(texture_type, x_size, y_size, z_size,
+                   component_type, format);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::setup_1d_texture
 //     Function: Texture::setup_1d_texture
 //       Access: Published
 //       Access: Published
@@ -129,7 +177,7 @@ setup_cube_map(int size, ComponentType component_type,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 write(const Filename &fullpath) {
 write(const Filename &fullpath) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return do_write(fullpath, 0, 0, false, false);
   return do_write(fullpath, 0, 0, false, false);
 }
 }
 
 
@@ -190,7 +238,7 @@ write(const Filename &fullpath) {
 INLINE bool Texture::
 INLINE bool Texture::
 write(const Filename &fullpath, int z, int n, 
 write(const Filename &fullpath, int z, int n, 
       bool write_pages, bool write_mipmaps) {
       bool write_pages, bool write_mipmaps) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return do_write(fullpath, z, n, write_pages, write_mipmaps);
   return do_write(fullpath, z, n, write_pages, write_mipmaps);
 }
 }
 
 
@@ -201,8 +249,8 @@ write(const Filename &fullpath, int z, int n,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 load(const PNMImage &pnmimage) {
 load(const PNMImage &pnmimage) {
-  ReMutexHolder holder(_lock);
-  clear();
+  MutexHolder holder(_lock);
+  do_clear();
   return do_load_one(pnmimage, get_name(), 0, 0);
   return do_load_one(pnmimage, get_name(), 0, 0);
 }
 }
 
 
@@ -214,7 +262,7 @@ load(const PNMImage &pnmimage) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 load(const PNMImage &pnmimage, int z, int n) {
 load(const PNMImage &pnmimage, int z, int n) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   ++_properties_modified;
   ++_properties_modified;
   ++_image_modified;
   ++_image_modified;
   return do_load_one(pnmimage, get_name(), z, n);
   return do_load_one(pnmimage, get_name(), z, n);
@@ -228,7 +276,7 @@ load(const PNMImage &pnmimage, int z, int n) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 store(PNMImage &pnmimage) const {
 store(PNMImage &pnmimage) const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return do_store_one(pnmimage, 0, 0);
   return do_store_one(pnmimage, 0, 0);
 }
 }
 
 
@@ -240,7 +288,7 @@ store(PNMImage &pnmimage) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 store(PNMImage &pnmimage, int z, int n) const {
 store(PNMImage &pnmimage, int z, int n) const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return do_store_one(pnmimage, z, n);
   return do_store_one(pnmimage, z, n);
 }
 }
 
 
@@ -252,7 +300,7 @@ store(PNMImage &pnmimage, int z, int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_filename() const {
 has_filename() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return !_filename.empty();
   return !_filename.empty();
 }
 }
 
 
@@ -265,7 +313,7 @@ has_filename() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const Filename &Texture::
 INLINE const Filename &Texture::
 get_filename() const {
 get_filename() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _filename;
   return _filename;
 }
 }
 
 
@@ -277,7 +325,7 @@ get_filename() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_alpha_filename() const {
 has_alpha_filename() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return !_alpha_filename.empty();
   return !_alpha_filename.empty();
 }
 }
 
 
@@ -291,7 +339,7 @@ has_alpha_filename() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const Filename &Texture::
 INLINE const Filename &Texture::
 get_alpha_filename() const {
 get_alpha_filename() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _alpha_filename;
   return _alpha_filename;
 }
 }
 
 
@@ -303,7 +351,7 @@ get_alpha_filename() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_fullpath() const {
 has_fullpath() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return !_fullpath.empty();
   return !_fullpath.empty();
 }
 }
 
 
@@ -316,7 +364,7 @@ has_fullpath() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const Filename &Texture::
 INLINE const Filename &Texture::
 get_fullpath() const {
 get_fullpath() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _fullpath;
   return _fullpath;
 }
 }
 
 
@@ -328,7 +376,7 @@ get_fullpath() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_alpha_fullpath() const {
 has_alpha_fullpath() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return !_alpha_fullpath.empty();
   return !_alpha_fullpath.empty();
 }
 }
 
 
@@ -342,7 +390,7 @@ has_alpha_fullpath() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE const Filename &Texture::
 INLINE const Filename &Texture::
 get_alpha_fullpath() const {
 get_alpha_fullpath() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _alpha_fullpath;
   return _alpha_fullpath;
 }
 }
 
 
@@ -428,13 +476,8 @@ get_pad_z_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_pad_size(int x, int y, int z) {
 set_pad_size(int x, int y, int z) {
-  ReMutexHolder holder(_lock);
-  if (x > _x_size) x = _x_size;
-  if (y > _y_size) y = _y_size;
-  if (z > _z_size) z = _z_size;
-  _pad_x_size = x;
-  _pad_y_size = y;
-  _pad_z_size = z;
+  MutexHolder holder(_lock);
+  do_set_pad_size(x, y, z);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -655,11 +698,8 @@ get_compression() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_compression() const {
 has_compression() const {
-  if (_compression == CM_default) {
-    return compressed_textures;
-  } else {
-    return (_compression != CM_off);
-  }
+  MutexHolder holder(_lock);
+  return do_has_compression();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -703,6 +743,105 @@ get_quality_level() const {
   return _quality_level;
   return _quality_level;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_expected_num_mipmap_levels
+//       Access: Published
+//  Description: Returns the number of mipmap levels that should be
+//               defined for this texture, given the texture's size.
+//
+//               Note that this returns a number appropriate for
+//               mipmapping, even if the texture does not currently
+//               have mipmapping enabled.
+////////////////////////////////////////////////////////////////////
+INLINE int Texture::
+get_expected_num_mipmap_levels() const {
+  MutexHolder holder(_lock);
+  return do_get_expected_num_mipmap_levels();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_expected_mipmap_x_size
+//       Access: Published
+//  Description: Returns the x_size that the nth mipmap level should
+//               have, based on the texture's size.
+////////////////////////////////////////////////////////////////////
+INLINE int Texture::
+get_expected_mipmap_x_size(int n) const {
+  MutexHolder holder(_lock);
+  return do_get_expected_mipmap_x_size(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_expected_mipmap_y_size
+//       Access: Published
+//  Description: Returns the y_size that the nth mipmap level should
+//               have, based on the texture's size.
+////////////////////////////////////////////////////////////////////
+INLINE int Texture::
+get_expected_mipmap_y_size(int n) const {
+  MutexHolder holder(_lock);
+  return do_get_expected_mipmap_y_size(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_expected_mipmap_z_size
+//       Access: Published
+//  Description: Returns the z_size that the nth mipmap level should
+//               have, based on the texture's size.
+////////////////////////////////////////////////////////////////////
+INLINE int Texture::
+get_expected_mipmap_z_size(int n) const {
+  MutexHolder holder(_lock);
+  return do_get_expected_mipmap_z_size(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::has_ram_image
+//       Access: Published
+//  Description: Returns true if the Texture has its image contents
+//               available in main RAM, false if it exists only in
+//               texture memory or in the prepared GSG context.
+//
+//               Note that this has nothing to do with whether
+//               get_ram_image() will fail or not.  Even if
+//               has_ram_image() returns false, get_ram_image() may
+//               still return a valid RAM image, because
+//               get_ram_image() will automatically load the texture
+//               from disk if necessary.  The only thing
+//               has_ram_image() tells you is whether the texture is
+//               available right now without hitting the disk first.
+//
+//               Note also that if an application uses only one GSG,
+//               it may appear that has_ram_image() returns true if
+//               the texture has not yet been loaded by the GSG, but
+//               this correlation is not true in general and should
+//               not be depended on.  Specifically, if an application
+//               ever uses multiple GSG's in its lifetime (for
+//               instance, by opening more than one window, or by
+//               closing its window and opening another one later),
+//               then has_ram_image() may well return false on
+//               textures that have never been loaded on the current
+//               GSG.
+////////////////////////////////////////////////////////////////////
+INLINE bool Texture::
+has_ram_image() const {
+  MutexHolder holder(_lock);
+  return do_has_ram_image();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::has_uncompressed_ram_image
+//       Access: Published
+//  Description: Returns true if the Texture has its image contents
+//               available in main RAM and is uncompressed, false
+//               otherwise.  See has_ram_image().
+////////////////////////////////////////////////////////////////////
+INLINE bool Texture::
+has_uncompressed_ram_image() const {
+  MutexHolder holder(_lock);
+  return do_has_uncompressed_ram_image();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::might_have_ram_image
 //     Function: Texture::might_have_ram_image
 //       Access: Published
 //       Access: Published
@@ -715,8 +854,8 @@ get_quality_level() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 might_have_ram_image() const {
 might_have_ram_image() const {
-  ReMutexHolder holder(_lock);
-  return (has_ram_image() || has_filename());
+  MutexHolder holder(_lock);
+  return (do_has_ram_image() || !_fullpath.empty());
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -727,11 +866,8 @@ might_have_ram_image() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_ram_image_size() const {
 get_ram_image_size() const {
-  ReMutexHolder holder(_lock);
-  if (_ram_images.empty()) {
-    return 0;
-  }
-  return _ram_images[0]._image.size();
+  MutexHolder holder(_lock);
+  return do_get_ram_image_size();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -748,9 +884,9 @@ get_ram_image_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_ram_page_size() const {
 get_ram_page_size() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   if (_ram_image_compression == CM_off || _ram_images.empty()) {
   if (_ram_image_compression == CM_off || _ram_images.empty()) {
-    return get_expected_ram_page_size();
+    return do_get_expected_ram_page_size();
   } else {
   } else {
     return _ram_images[0]._page_size;
     return _ram_images[0]._page_size;
   }
   }
@@ -765,8 +901,8 @@ get_ram_page_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_expected_ram_image_size() const {
 get_expected_ram_image_size() const {
-  ReMutexHolder holder(_lock);
-  return get_expected_ram_page_size() * (size_t)_z_size;
+  MutexHolder holder(_lock);
+  return do_get_expected_ram_image_size();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -779,8 +915,42 @@ get_expected_ram_image_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_expected_ram_page_size() const {
 get_expected_ram_page_size() const {
-  ReMutexHolder holder(_lock);
-  return (size_t)(_x_size * _y_size * _num_components * _component_width);
+  MutexHolder holder(_lock);
+  return do_get_expected_ram_page_size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_ram_image
+//       Access: Published
+//  Description: Returns the system-RAM image data associated with the
+//               texture.  If the texture does not currently have an
+//               associated RAM image, and the texture was generated
+//               by loading an image from a disk file (the most common
+//               case), this forces the reload of the same texture.
+//               This can happen if keep_texture_ram is configured to
+//               false, and we have previously prepared this texture
+//               with a GSG.
+//
+//               Note that it is not correct to call has_ram_image()
+//               first to test whether this function will fail.  A
+//               false return value from has_ram_image() indicates
+//               only that get_ram_image() may need to reload the
+//               texture from disk, which it will do automatically.
+//               However, you can call might_have_ram_image(), which
+//               will return true if the ram image exists, or there is
+//               a reasonable reason to believe it can be loaded.
+//
+//               On the other hand, it is possible that the texture
+//               cannot be found on disk or is otherwise unavailable.
+//               If that happens, this function will return NULL.
+//               There is no way to predict with 100% accuracy whether
+//               get_ram_image() will return NULL without calling it
+//               first; might_have_ram_image() is the closest.
+////////////////////////////////////////////////////////////////////
+INLINE CPTA_uchar Texture::
+get_ram_image() {
+  MutexHolder holder(_lock);
+  return do_get_ram_image();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -810,10 +980,34 @@ get_ram_image_compression() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 modify_ram_image() {
 modify_ram_image() {
-  ReMutexHolder holder(_lock);
-  do_modify_ram_image();
+  MutexHolder holder(_lock);
   ++_image_modified;
   ++_image_modified;
-  return _ram_images[0]._image;
+  return do_modify_ram_image();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::get_uncompressed_ram_image
+//       Access: Published
+//  Description: Returns the system-RAM image associated with the
+//               texture, in an uncompressed form if at all possible.
+//
+//               If get_ram_image_compression() is CM_off, then the
+//               system-RAM image is already uncompressed, and this
+//               returns the same thing as get_ram_image().
+//
+//               If get_ram_image_compression() is anything else, then
+//               the system-RAM image is compressed.  In this case,
+//               the image will be reloaded from the *original* file
+//               (not from the cache), in the hopes that an
+//               uncompressed image will be found there.
+//
+//               If an uncompressed image cannot be found, returns
+//               NULL.
+////////////////////////////////////////////////////////////////////
+INLINE CPTA_uchar Texture::
+get_uncompressed_ram_image() {
+  MutexHolder holder(_lock);
+  return do_get_uncompressed_ram_image();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -827,10 +1021,20 @@ modify_ram_image() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 make_ram_image() {
 make_ram_image() {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   ++_image_modified;
   ++_image_modified;
-  do_make_ram_image();
-  return _ram_images[0]._image;
+  return do_make_ram_image();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::clear_ram_image
+//       Access: Published
+//  Description: Discards the current system-RAM image.
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+clear_ram_image() {
+  MutexHolder holder(_lock);
+  do_clear_ram_image();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -866,7 +1070,7 @@ set_keep_ram_image(bool keep_ram_image) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE int Texture::
 INLINE int Texture::
 get_num_ram_mipmap_images() const {
 get_num_ram_mipmap_images() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _ram_images.size();
   return _ram_images.size();
 }
 }
 
 
@@ -882,8 +1086,8 @@ get_num_ram_mipmap_images() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_ram_mipmap_image(int n) const {
 has_ram_mipmap_image(int n) const {
-  ReMutexHolder holder(_lock);
-  return (n >= 0 && n < (int)_ram_images.size() && !_ram_images[n]._image.empty());
+  MutexHolder holder(_lock);
+  return do_has_ram_mipmap_image(n);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -895,7 +1099,7 @@ has_ram_mipmap_image(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_ram_mipmap_image_size(int n) const {
 get_ram_mipmap_image_size(int n) const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   if (n >= 0 && n < (int)_ram_images.size()) {
   if (n >= 0 && n < (int)_ram_images.size()) {
     return _ram_images[n]._image.size();
     return _ram_images[n]._image.size();
   }
   }
@@ -917,15 +1121,8 @@ get_ram_mipmap_image_size(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_ram_mipmap_page_size(int n) const {
 get_ram_mipmap_page_size(int n) const {
-  ReMutexHolder holder(_lock);
-  if (_ram_image_compression != CM_off) {
-    if (n >= 0 && n < (int)_ram_images.size()) {
-      return _ram_images[n]._page_size;
-    }
-    return 0;
-  } else {
-    return get_expected_ram_mipmap_page_size(n);
-  }
+  MutexHolder holder(_lock);
+  return do_get_ram_mipmap_page_size(n);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -937,8 +1134,8 @@ get_ram_mipmap_page_size(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_expected_ram_mipmap_image_size(int n) const {
 get_expected_ram_mipmap_image_size(int n) const {
-  ReMutexHolder holder(_lock);
-  return get_expected_ram_mipmap_page_size(n) * (size_t)get_expected_mipmap_z_size(n);
+  MutexHolder holder(_lock);
+  return do_get_expected_ram_mipmap_page_size(n) * (size_t)do_get_expected_mipmap_z_size(n);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -951,8 +1148,8 @@ get_expected_ram_mipmap_image_size(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_expected_ram_mipmap_page_size(int n) const {
 get_expected_ram_mipmap_page_size(int n) const {
-  ReMutexHolder holder(_lock);
-  return (size_t)(get_expected_mipmap_x_size(n) * get_expected_mipmap_y_size(n) * _num_components * _component_width);
+  MutexHolder holder(_lock);
+  return do_get_expected_ram_mipmap_page_size(n);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -967,10 +1164,37 @@ get_expected_ram_mipmap_page_size(int n) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE PTA_uchar Texture::
 INLINE PTA_uchar Texture::
 modify_ram_mipmap_image(int n) {
 modify_ram_mipmap_image(int n) {
-  ReMutexHolder holder(_lock);
-  do_modify_ram_mipmap_image(n);
+  MutexHolder holder(_lock);
   ++_image_modified;
   ++_image_modified;
-  return _ram_images[n]._image;
+  return do_modify_ram_mipmap_image(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::make_ram_mipmap_image
+//       Access: Published
+//  Description: Discards the current system-RAM image for the
+//               nth mipmap level, if any, and allocates a new buffer
+//               of the appropriate size.  Returns the new buffer.
+//
+//               This does *not* affect keep_ram_image.
+////////////////////////////////////////////////////////////////////
+INLINE PTA_uchar Texture::
+make_ram_mipmap_image(int n) {
+  MutexHolder holder(_lock);
+  ++_image_modified;
+  return do_make_ram_mipmap_image(n);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::clear_ram_mipmap_images
+//       Access: Published
+//  Description: Discards the current system-RAM image for all
+//               mipmap levels, except level 0 (the base image).
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+clear_ram_mipmap_images() {
+  MutexHolder holder(_lock);
+  do_clear_ram_mipmap_images();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1001,7 +1225,7 @@ get_simple_y_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool Texture::
 INLINE bool Texture::
 has_simple_ram_image() const {
 has_simple_ram_image() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return !_simple_ram_image._image.empty();
   return !_simple_ram_image._image.empty();
 }
 }
 
 
@@ -1013,7 +1237,7 @@ has_simple_ram_image() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE size_t Texture::
 INLINE size_t Texture::
 get_simple_ram_image_size() const {
 get_simple_ram_image_size() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _simple_ram_image._image.size();
   return _simple_ram_image._image.size();
 }
 }
 
 
@@ -1036,10 +1260,47 @@ get_simple_ram_image_size() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE CPTA_uchar Texture::
 INLINE CPTA_uchar Texture::
 get_simple_ram_image() const {
 get_simple_ram_image() const {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   return _simple_ram_image._image;
   return _simple_ram_image._image;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::set_simple_ram_image
+//       Access: Published
+//  Description: Replaces the internal "simple" texture image.  This
+//               can be used as an option to display while the main
+//               texture image is being loaded from disk.  It is
+//               normally a very small image, 16x16 or smaller (and
+//               maybe even 1x1), that is designed to give just enough
+//               sense of color to serve as a placeholder until the
+//               full texture is available.
+//
+//               The "simple" image is always 4 components, 1 byte
+//               each, regardless of the parameters of the full
+//               texture.  The simple image is only supported for
+//               ordinary 2-d textures.
+//
+//               Also see generate_simple_ram_image(),
+//               modify_simple_ram_image(), and
+//               new_simple_ram_image().
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+set_simple_ram_image(PTA_uchar image, int x_size, int y_size) {
+  MutexHolder holder(_lock);
+  do_set_simple_ram_image(image, x_size, y_size);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::clear_simple_ram_image
+//       Access: Published
+//  Description: Discards the current "simple" image.
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+clear_simple_ram_image() {
+  MutexHolder holder(_lock);
+  do_clear_simple_ram_image();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::get_properties_modified
 //     Function: Texture::get_properties_modified
 //       Access: Published
 //       Access: Published
@@ -1091,7 +1352,7 @@ get_simple_image_modified() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_filename(const Filename &filename) {
 set_filename(const Filename &filename) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _filename = filename;
   _filename = filename;
 }
 }
 
 
@@ -1103,7 +1364,7 @@ set_filename(const Filename &filename) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 clear_filename() {
 clear_filename() {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _filename = Filename();
   _filename = Filename();
 }
 }
 
 
@@ -1125,7 +1386,7 @@ clear_filename() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_alpha_filename(const Filename &alpha_filename) {
 set_alpha_filename(const Filename &alpha_filename) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _alpha_filename = alpha_filename;
   _alpha_filename = alpha_filename;
 }
 }
 
 
@@ -1137,7 +1398,7 @@ set_alpha_filename(const Filename &alpha_filename) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 clear_alpha_filename() {
 clear_alpha_filename() {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _alpha_filename = Filename();
   _alpha_filename = Filename();
 }
 }
 
 
@@ -1151,7 +1412,7 @@ clear_alpha_filename() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_fullpath(const Filename &fullpath) {
 set_fullpath(const Filename &fullpath) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _fullpath = fullpath;
   _fullpath = fullpath;
 }
 }
 
 
@@ -1163,7 +1424,7 @@ set_fullpath(const Filename &fullpath) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 clear_fullpath() {
 clear_fullpath() {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _fullpath = Filename();
   _fullpath = Filename();
 }
 }
 
 
@@ -1178,7 +1439,7 @@ clear_fullpath() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_alpha_fullpath(const Filename &alpha_fullpath) {
 set_alpha_fullpath(const Filename &alpha_fullpath) {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _alpha_fullpath = alpha_fullpath;
   _alpha_fullpath = alpha_fullpath;
 }
 }
 
 
@@ -1190,7 +1451,7 @@ set_alpha_fullpath(const Filename &alpha_fullpath) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 clear_alpha_fullpath() {
 clear_alpha_fullpath() {
-  ReMutexHolder holder(_lock);
+  MutexHolder holder(_lock);
   _alpha_fullpath = Filename();
   _alpha_fullpath = Filename();
 }
 }
 
 
@@ -1203,13 +1464,8 @@ clear_alpha_fullpath() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_x_size(int x_size) {
 set_x_size(int x_size) {
-  ReMutexHolder holder(_lock);
-  if (_x_size != x_size) {
-    _x_size = x_size;
-    ++_image_modified;
-    clear_ram_image();
-    set_pad_size();
-  }
+  MutexHolder holder(_lock);
+  do_set_x_size(x_size);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1221,14 +1477,8 @@ set_x_size(int x_size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_y_size(int y_size) {
 set_y_size(int y_size) {
-  ReMutexHolder holder(_lock);
-  if (_y_size != y_size) {
-    nassertv(_texture_type != Texture::TT_1d_texture || y_size == 1);
-    _y_size = y_size;
-    ++_image_modified;
-    clear_ram_image();
-    set_pad_size();
-  }
+  MutexHolder holder(_lock);
+  do_set_y_size(y_size);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1240,16 +1490,32 @@ set_y_size(int y_size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE void Texture::
 INLINE void Texture::
 set_z_size(int z_size) {
 set_z_size(int z_size) {
-  ReMutexHolder holder(_lock);
-  if (_z_size != z_size) {
-    nassertv(_texture_type == Texture::TT_3d_texture ||
-             (_texture_type == Texture::TT_cube_map && z_size == 6) ||
-             (z_size == 1));
-    _z_size = z_size;
-    ++_image_modified;
-    clear_ram_image();
-    set_pad_size();
-  }
+  MutexHolder holder(_lock);
+  do_set_z_size(z_size);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::set_format
+//       Access: Published
+//  Description: Changes the format value for the texture components.
+//               This implicitly sets num_components as well.
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+set_format(Texture::Format format) {
+  MutexHolder holder(_lock);
+  do_set_format(format);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::set_component_type
+//       Access: Published
+//  Description: Changes the data value for the texture components.
+//               This implicitly sets component_width as well.
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+set_component_type(Texture::ComponentType component_type) {
+  MutexHolder holder(_lock);
+  do_set_component_type(component_type);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1365,6 +1631,70 @@ set_post_load_store_cache(bool flag) {
   _post_load_store_cache = flag;
   _post_load_store_cache = flag;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_get_ram_image_size
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE size_t Texture::
+do_get_ram_image_size() const {
+  if (_ram_images.empty()) {
+    return 0;
+  }
+  return _ram_images[0]._image.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_has_ram_mipmap_image
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE bool Texture::
+do_has_ram_mipmap_image(int n) const {
+  return (n >= 0 && n < (int)_ram_images.size() && !_ram_images[n]._image.empty());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_get_expected_ram_image_size
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE size_t Texture::
+do_get_expected_ram_image_size() const {
+  return do_get_expected_ram_page_size() * (size_t)_z_size;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_get_expected_ram_page_size
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE size_t Texture::
+do_get_expected_ram_page_size() const {
+  return (size_t)(_x_size * _y_size * _num_components * _component_width);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_get_expected_ram_mipmap_page_size
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE size_t Texture::
+do_get_expected_ram_mipmap_page_size(int n) const {
+  return (size_t)(do_get_expected_mipmap_x_size(n) * do_get_expected_mipmap_y_size(n) * _num_components * _component_width);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::do_clear_ram_image
+//       Access: Protected
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE void Texture::
+do_clear_ram_image() {
+  _ram_image_compression = CM_off;
+  _ram_images.clear();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::store_unscaled_byte
 //     Function: Texture::store_unscaled_byte
 //       Access: Private, Static
 //       Access: Private, Static

File diff ditekan karena terlalu besar
+ 98 - 647
panda/src/gobj/texture.cxx


+ 92 - 43
panda/src/gobj/texture.h

@@ -26,8 +26,9 @@
 #include "pmap.h"
 #include "pmap.h"
 #include "config_gobj.h"
 #include "config_gobj.h"
 #include "pStatCollector.h"
 #include "pStatCollector.h"
-#include "reMutex.h"
-#include "reMutexHolder.h"
+#include "pmutex.h"
+#include "mutexHolder.h"
+#include "conditionVarFull.h"
 #include "loaderOptions.h"
 #include "loaderOptions.h"
 #include "string_utils.h"
 #include "string_utils.h"
 
 
@@ -192,12 +193,12 @@ protected:
 PUBLISHED:
 PUBLISHED:
   virtual ~Texture();
   virtual ~Texture();
 
 
-  virtual PT(Texture) make_copy();
-  virtual void clear();
+  INLINE PT(Texture) make_copy();
+  INLINE void clear();
 
 
-  void setup_texture(TextureType texture_type,
-                     int x_size, int y_size, int z_size,
-                     ComponentType component_type, Format format);
+  INLINE void setup_texture(TextureType texture_type,
+                            int x_size, int y_size, int z_size,
+                            ComponentType component_type, Format format);
 
 
   INLINE void setup_1d_texture();
   INLINE void setup_1d_texture();
   INLINE void setup_1d_texture(int x_size,
   INLINE void setup_1d_texture(int x_size,
@@ -288,26 +289,26 @@ PUBLISHED:
   void set_quality_level(QualityLevel quality_level);
   void set_quality_level(QualityLevel quality_level);
   INLINE QualityLevel get_quality_level() const;
   INLINE QualityLevel get_quality_level() const;
 
 
-  int get_expected_num_mipmap_levels() const;
-  int get_expected_mipmap_x_size(int n) const;
-  int get_expected_mipmap_y_size(int n) const;
-  int get_expected_mipmap_z_size(int n) const;
+  INLINE int get_expected_num_mipmap_levels() const;
+  INLINE int get_expected_mipmap_x_size(int n) const;
+  INLINE int get_expected_mipmap_y_size(int n) const;
+  INLINE int get_expected_mipmap_z_size(int n) const;
 
 
-  virtual bool has_ram_image() const;
-  virtual bool has_uncompressed_ram_image() const;
+  INLINE bool has_ram_image() const;
+  INLINE bool has_uncompressed_ram_image() const;
   INLINE bool might_have_ram_image() const;
   INLINE bool might_have_ram_image() const;
   INLINE size_t get_ram_image_size() const;
   INLINE size_t get_ram_image_size() const;
   INLINE size_t get_ram_page_size() const;
   INLINE size_t get_ram_page_size() const;
   INLINE size_t get_expected_ram_image_size() const;
   INLINE size_t get_expected_ram_image_size() const;
   INLINE size_t get_expected_ram_page_size() const;
   INLINE size_t get_expected_ram_page_size() const;
-  CPTA_uchar get_ram_image();
+  INLINE CPTA_uchar get_ram_image();
   INLINE CompressionMode get_ram_image_compression() const;
   INLINE CompressionMode get_ram_image_compression() const;
-  CPTA_uchar get_uncompressed_ram_image();
+  INLINE CPTA_uchar get_uncompressed_ram_image();
   INLINE PTA_uchar modify_ram_image();
   INLINE PTA_uchar modify_ram_image();
   INLINE PTA_uchar make_ram_image();
   INLINE PTA_uchar make_ram_image();
   void set_ram_image(PTA_uchar image, CompressionMode compression = CM_off,
   void set_ram_image(PTA_uchar image, CompressionMode compression = CM_off,
                      size_t page_size = 0);
                      size_t page_size = 0);
-  void clear_ram_image();
+  INLINE void clear_ram_image();
   INLINE void set_keep_ram_image(bool keep_ram_image);
   INLINE void set_keep_ram_image(bool keep_ram_image);
   virtual bool get_keep_ram_image() const;
   virtual bool get_keep_ram_image() const;
 
 
@@ -321,10 +322,10 @@ PUBLISHED:
   INLINE size_t get_expected_ram_mipmap_page_size(int n) const;
   INLINE size_t get_expected_ram_mipmap_page_size(int n) const;
   CPTA_uchar get_ram_mipmap_image(int n);
   CPTA_uchar get_ram_mipmap_image(int n);
   INLINE PTA_uchar modify_ram_mipmap_image(int n);
   INLINE PTA_uchar modify_ram_mipmap_image(int n);
-  PTA_uchar make_ram_mipmap_image(int n);
+  INLINE PTA_uchar make_ram_mipmap_image(int n);
   void set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size = 0);
   void set_ram_mipmap_image(int n, PTA_uchar image, size_t page_size = 0);
   void clear_ram_mipmap_image(int n);
   void clear_ram_mipmap_image(int n);
-  void clear_ram_mipmap_images();
+  INLINE void clear_ram_mipmap_images();
   void generate_ram_mipmap_images();
   void generate_ram_mipmap_images();
 
 
   INLINE int get_simple_x_size() const;
   INLINE int get_simple_x_size() const;
@@ -332,11 +333,11 @@ PUBLISHED:
   INLINE bool has_simple_ram_image() const;
   INLINE bool has_simple_ram_image() const;
   INLINE size_t get_simple_ram_image_size() const;
   INLINE size_t get_simple_ram_image_size() const;
   INLINE CPTA_uchar get_simple_ram_image() const;
   INLINE CPTA_uchar get_simple_ram_image() const;
-  void set_simple_ram_image(PTA_uchar image, int x_size, int y_size);
+  INLINE void set_simple_ram_image(PTA_uchar image, int x_size, int y_size);
   PTA_uchar modify_simple_ram_image();
   PTA_uchar modify_simple_ram_image();
   PTA_uchar new_simple_ram_image(int x_size, int y_size);
   PTA_uchar new_simple_ram_image(int x_size, int y_size);
   void generate_simple_ram_image();
   void generate_simple_ram_image();
-  void clear_simple_ram_image();
+  INLINE void clear_simple_ram_image();
 
 
   PT(TexturePeeker) peek();
   PT(TexturePeeker) peek();
 
 
@@ -393,8 +394,8 @@ PUBLISHED:
 
 
   void set_orig_file_size(int x, int y, int z = 1);
   void set_orig_file_size(int x, int y, int z = 1);
   
   
-  void set_format(Format format);
-  void set_component_type(ComponentType component_type);
+  INLINE void set_format(Format format);
+  INLINE void set_component_type(ComponentType component_type);
   INLINE void set_loaded_from_image();
   INLINE void set_loaded_from_image();
   INLINE bool get_loaded_from_image() const;
   INLINE bool get_loaded_from_image() const;
 
 
@@ -434,6 +435,16 @@ public:
   static bool adjust_size(int &x_size, int &y_size, const string &name);
   static bool adjust_size(int &x_size, int &y_size, const string &name);
 
 
 protected:
 protected:
+  virtual void reconsider_dirty();
+
+  // All of the functions in this class that begin "do_" are protected
+  // methods.  Many of them are implementations of public-facing
+  // versions of the same methods.
+
+  // All of these assume the lock is already held; generally, they
+  // also avoid adjusting the _properties_modified and _image_modified
+  // semaphores.
+
   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,
@@ -441,24 +452,63 @@ protected:
   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,
                            bool header_only, BamCacheRecord *record);
                            bool header_only, BamCacheRecord *record);
+  virtual bool do_load_one(const PNMImage &pnmimage, const string &name,
+                           int z, int n);
+  bool do_read_txo_file(const Filename &fullpath);
+  bool do_read_txo(istream &in, const string &filename);
+  bool do_read_dds_file(const Filename &fullpath, bool header_only);
+  bool do_read_dds(istream &in, const string &filename, bool header_only);
+
   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;
-
-  virtual bool do_load_one(const PNMImage &pnmimage, const string &name,
-                           int z, int n);
   bool do_store_one(PNMImage &pnmimage, int z, int n) const;
   bool do_store_one(PNMImage &pnmimage, int z, int n) const;
-
-  virtual void reconsider_dirty();
-  virtual void reload_ram_image(bool allow_compression);
-
-  void do_modify_ram_image();
-  void do_make_ram_image();
-  void do_modify_ram_mipmap_image(int n);
-
-  bool reconsider_z_size(int z);
-  bool reconsider_image_properties(int x_size, int y_size, int num_components,
-           ComponentType component_type, int z);
+  bool do_write_txo_file(const Filename &fullpath) const;
+  bool do_write_txo(ostream &out, const string &filename) const;
+
+  void do_unlock_and_reload_ram_image(bool allow_compression);
+  virtual void do_reload_ram_image(bool allow_compression);
+  PTA_uchar do_modify_ram_image();
+  PTA_uchar do_make_ram_image();
+  PTA_uchar do_modify_ram_mipmap_image(int n);
+  PTA_uchar do_make_ram_mipmap_image(int n);
+
+  bool do_reconsider_z_size(int z);
+  bool do_reconsider_image_properties(int x_size, int y_size, int num_components,
+                                      ComponentType component_type, int z);
+
+  virtual PT(Texture) do_make_copy();
+  void do_assign(const Texture &copy);
+  virtual void do_clear();
+  void do_setup_texture(TextureType texture_type, int x_size, int y_size,
+                        int z_size, ComponentType component_type,
+                        Format format);
+  void do_set_format(Format format);
+  void do_set_component_type(ComponentType component_type);
+  void do_set_x_size(int x_size);
+  void do_set_y_size(int y_size);
+  void do_set_z_size(int z_size);
+
+  bool do_has_compression() const;
+  virtual bool do_has_ram_image() const;
+  virtual bool do_has_uncompressed_ram_image() const;
+  CPTA_uchar do_get_ram_image();
+  CPTA_uchar do_get_uncompressed_ram_image();
+  void do_set_simple_ram_image(PTA_uchar image, int x_size, int y_size);
+  INLINE size_t do_get_ram_image_size() const;
+  INLINE bool do_has_ram_mipmap_image(int n) const;
+  int do_get_expected_num_mipmap_levels() const;
+  INLINE size_t do_get_expected_ram_image_size() const;
+  INLINE size_t do_get_expected_ram_page_size() const;
+  size_t do_get_ram_mipmap_page_size(int n) const;
+  INLINE size_t do_get_expected_ram_mipmap_page_size(int n) const;
+  int do_get_expected_mipmap_x_size(int n) const;
+  int do_get_expected_mipmap_y_size(int n) const;
+  int do_get_expected_mipmap_z_size(int n) const;
+  INLINE void do_clear_ram_image();
+  void do_clear_simple_ram_image();
+  void do_clear_ram_mipmap_images();
+  void do_set_pad_size(int x, int y, int z);
 
 
   // This nested class declaration is used below.
   // This nested class declaration is used below.
   class RamImage {
   class RamImage {
@@ -498,8 +548,8 @@ private:
 
 
   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
   void clear_prepared(PreparedGraphicsObjects *prepared_objects);
 
 
-  void consider_rescale(PNMImage &pnmimage, const string &name);
-  void consider_downgrade(PNMImage &pnmimage, int num_channels);
+  static void consider_rescale(PNMImage &pnmimage, const string &name);
+  static void consider_downgrade(PNMImage &pnmimage, int num_channels, const string &name);
 
 
   static bool compare_images(const PNMImage &a, const PNMImage &b);
   static bool compare_images(const PNMImage &a, const PNMImage &b);
 
 
@@ -511,11 +561,7 @@ private:
   INLINE static double get_unsigned_short(const unsigned char *&p);
   INLINE static double get_unsigned_short(const unsigned char *&p);
 
 
   INLINE static bool is_txo_filename(const Filename &fullpath);
   INLINE static bool is_txo_filename(const Filename &fullpath);
-  bool read_txo_file(const Filename &fullpath);
-  bool write_txo_file(const Filename &fullpath) const;
-
   INLINE static bool is_dds_filename(const Filename &fullpath);
   INLINE static bool is_dds_filename(const Filename &fullpath);
-  bool read_dds_file(const Filename &fullpath, bool header_only);
 
 
   void filter_2d_mipmap_pages(RamImage &to, const RamImage &from,
   void filter_2d_mipmap_pages(RamImage &to, const RamImage &from,
                               int x_size, int y_size);
                               int x_size, int y_size);
@@ -550,7 +596,10 @@ private:
 
 
 protected:
 protected:
   // Protects all of the members of this class.
   // Protects all of the members of this class.
-  ReMutex _lock;
+  Mutex _lock;
+  // Used to implement do_unlock_and_reload_ram_image()
+  ConditionVarFull _cvar;  // condition: _reloading is true.
+  bool _reloading;
 
 
   Filename _filename;
   Filename _filename;
   Filename _alpha_filename;
   Filename _alpha_filename;

+ 5 - 2
panda/src/gobj/texturePeeker.cxx

@@ -19,6 +19,9 @@
 //     Function: TexturePeeker::Constructor
 //     Function: TexturePeeker::Constructor
 //       Access: Private
 //       Access: Private
 //  Description: Use Texture::peek() to construct a TexturePeeker.
 //  Description: Use Texture::peek() to construct a TexturePeeker.
+//
+//               This constructor is called only by Texture::peek(),
+//               and assumes the texture's lock is already held.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 TexturePeeker::
 TexturePeeker::
 TexturePeeker(Texture *tex) {
 TexturePeeker(Texture *tex) {
@@ -41,7 +44,7 @@ TexturePeeker(Texture *tex) {
     // Regular 1-d, 2-d, or 3-d texture.  The coordinates map
     // Regular 1-d, 2-d, or 3-d texture.  The coordinates map
     // directly.  Simple ram images are possible if it is a 2-d
     // directly.  Simple ram images are possible if it is a 2-d
     // texture.
     // texture.
-    if (!(tex->has_ram_image() && tex->get_ram_image_compression() == Texture::CM_off) && tex->has_simple_ram_image()) {
+    if (!(tex->do_has_ram_image() && tex->_ram_image_compression == Texture::CM_off) && !tex->_simple_ram_image._image.empty()) {
       _image = tex->_simple_ram_image._image;
       _image = tex->_simple_ram_image._image;
       _x_size = tex->_simple_x_size;
       _x_size = tex->_simple_x_size;
       _y_size = tex->_simple_y_size;
       _y_size = tex->_simple_y_size;
@@ -53,7 +56,7 @@ TexturePeeker(Texture *tex) {
       _component_type = Texture::T_unsigned_byte;
       _component_type = Texture::T_unsigned_byte;
 
 
     } else {
     } else {
-      _image = tex->get_uncompressed_ram_image();
+      _image = tex->do_get_uncompressed_ram_image();
     }
     }
   }
   }
 
 

+ 8 - 0
panda/src/gobj/textureReloadRequest.cxx

@@ -37,6 +37,14 @@ do_task() {
       } else {
       } else {
         _texture->get_uncompressed_ram_image();
         _texture->get_uncompressed_ram_image();
       }
       }
+
+      // Now that we've loaded the texture, we should ensure it
+      // actually gets prepared--even if it's no longer visible in the
+      // frame--or it may become a kind of a leak (if the texture is
+      // never rendered again on this GSG, we'll just end up carrying
+      // the texture memory in RAM forever, instead of dumping it as
+      // soon as it gets prepared).
+      _texture->prepare(_pgo);
     }
     }
   }
   }
   _is_ready = true;
   _is_ready = true;

+ 18 - 18
panda/src/gobj/videoTexture.cxx

@@ -55,22 +55,6 @@ VideoTexture(const VideoTexture &copy) :
 {
 {
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: VideoTexture::has_ram_image
-//       Access: Published, Virtual
-//  Description: Returns true if the Texture has its image contents
-//               available in main RAM, false if it exists only in
-//               texture memory or in the prepared GSG context.
-////////////////////////////////////////////////////////////////////
-bool VideoTexture::
-has_ram_image() const {
-  int this_frame = ClockObject::get_global_clock()->get_frame_count();
-  if (this_frame != _last_frame_update) {
-    return false;
-  }
-  return !_ram_images.empty() && !_ram_images[0]._image.empty();
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: VideoTexture::get_keep_ram_image
 //     Function: VideoTexture::get_keep_ram_image
 //       Access: Published, Virtual
 //       Access: Published, Virtual
@@ -123,6 +107,22 @@ cull_callback(CullTraverser *, const CullTraverserData &) const {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: VideoTexture::do_has_ram_image
+//       Access: Protected, Virtual
+//  Description: Returns true if the Texture has its image contents
+//               available in main RAM, false if it exists only in
+//               texture memory or in the prepared GSG context.
+////////////////////////////////////////////////////////////////////
+bool VideoTexture::
+do_has_ram_image() const {
+  int this_frame = ClockObject::get_global_clock()->get_frame_count();
+  if (this_frame != _last_frame_update) {
+    return false;
+  }
+  return !_ram_images.empty() && !_ram_images[0]._image.empty();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: VideoTexture::reconsider_dirty
 //     Function: VideoTexture::reconsider_dirty
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
@@ -135,7 +135,7 @@ reconsider_dirty() {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: VideoTexture::reload_ram_image
+//     Function: VideoTexture::do_reload_ram_image
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
 //  Description: Called when the Texture image is required but the ram
 //  Description: Called when the Texture image is required but the ram
 //               image is not available, this will reload it from disk
 //               image is not available, this will reload it from disk
@@ -143,7 +143,7 @@ reconsider_dirty() {
 //               available, if possible.
 //               available, if possible.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void VideoTexture::
 void VideoTexture::
-reload_ram_image() {
+do_reload_ram_image() {
   consider_update();
   consider_update();
 }
 }
 
 

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

@@ -34,7 +34,6 @@ protected:
   VideoTexture(const VideoTexture &copy);
   VideoTexture(const VideoTexture &copy);
 
 
 PUBLISHED:
 PUBLISHED:
-  virtual bool has_ram_image() const;
   virtual bool get_keep_ram_image() const;
   virtual bool get_keep_ram_image() const;
 
 
   INLINE int get_video_width() const;
   INLINE int get_video_width() const;
@@ -48,8 +47,10 @@ public:
 protected:
 protected:
   INLINE void set_video_size(int video_width, int video_height);
   INLINE void set_video_size(int video_width, int video_height);
 
 
+  virtual bool do_has_ram_image() const;
+
   virtual void reconsider_dirty();
   virtual void reconsider_dirty();
-  virtual void reload_ram_image();
+  virtual void do_reload_ram_image();
 
 
   INLINE void consider_update();
   INLINE void consider_update();
   INLINE void clear_current_frame();
   INLINE void clear_current_frame();

+ 73 - 58
panda/src/grutil/movieTexture.cxx

@@ -108,34 +108,7 @@ MovieTexture::
 MovieTexture(const MovieTexture &copy) : 
 MovieTexture(const MovieTexture &copy) : 
   Texture(copy)
   Texture(copy)
 {
 {
-  // Since 'make_copy' can be a slow operation, 
-  // I release the read lock before calling make_copy.
-  
-  pvector<MovieVideoCursor *> color;
-  pvector<MovieVideoCursor *> alpha;
-  {
-    CDReader copy_cdata(copy._cycler);
-    color.resize(copy_cdata->_pages.size());
-    alpha.resize(copy_cdata->_pages.size());
-    for (int i=0; i<(int)(color.size()); i++) {
-      color[i] = copy_cdata->_pages[i]._color;
-      alpha[i] = copy_cdata->_pages[i]._alpha;
-    }
-  }
-  
-  {
-    CDWriter cdata(_cycler);
-    cdata->_pages.resize(color.size());
-    for (int i=0; i<(int)(color.size()); i++) {
-      if (color[i]) {
-        cdata->_pages[i]._color = color[i]->get_source()->open();
-      }
-      if (alpha[i]) {
-        cdata->_pages[i]._alpha = alpha[i]->get_source()->open();
-      }
-    }
-    recalculate_image_properties(cdata);
-  }
+  nassertv(false);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -148,24 +121,6 @@ MovieTexture::
   clear();
   clear();
 }
 }
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: MovieTexture::make_copy
-//       Access: Published, Virtual
-//  Description: Returns a new copy of the same Texture.  This copy,
-//               if applied to geometry, will be copied into texture
-//               as a separate texture from the original, so it will
-//               be duplicated in texture memory (and may be
-//               independently modified if desired).
-//               
-//               If the Texture is an MovieTexture, the resulting
-//               duplicate may be animated independently of the
-//               original.
-////////////////////////////////////////////////////////////////////
-PT(Texture) MovieTexture::
-make_copy() {
-  return new MovieTexture(*this);
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MovieTexture::make_texture
 //     Function: MovieTexture::make_texture
 //       Access: Public, Static
 //       Access: Public, Static
@@ -190,14 +145,16 @@ VideoPage() :
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: MovieTexture::recalculate_image_properties
+//     Function: MovieTexture::do_recalculate_image_properties
 //       Access: Protected
 //       Access: Protected
 //  Description: Resizes the texture, and adjusts the format,
 //  Description: Resizes the texture, and adjusts the format,
 //               based on the source movies.  The resulting texture
 //               based on the source movies.  The resulting texture
 //               will be large enough to hold all the videos.
 //               will be large enough to hold all the videos.
+//
+//               Assumes the lock is already held.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void MovieTexture::
 void MovieTexture::
-recalculate_image_properties(CDWriter &cdata) {
+do_recalculate_image_properties(CDWriter &cdata) {
   int x_max = 1;
   int x_max = 1;
   int y_max = 1;
   int y_max = 1;
   bool alpha = false;
   bool alpha = false;
@@ -224,7 +181,7 @@ recalculate_image_properties(CDWriter &cdata) {
   cdata->_video_height = y_max;
   cdata->_video_height = y_max;
   cdata->_video_length = len;
   cdata->_video_length = len;
   
   
-  if (get_texture_type() == TT_cube_map) {
+  if (_texture_type == TT_cube_map) {
     // Texture must be square.
     // Texture must be square.
     if (x_max > y_max) y_max = x_max;
     if (x_max > y_max) y_max = x_max;
     if (y_max > x_max) x_max = y_max;
     if (y_max > x_max) x_max = y_max;
@@ -237,9 +194,9 @@ recalculate_image_properties(CDWriter &cdata) {
     y_max = up_to_power_2(y_max);
     y_max = up_to_power_2(y_max);
   }
   }
   
   
-  reconsider_image_properties(x_max, y_max, alpha?4:3, 
-                              T_unsigned_byte, cdata->_pages.size());
-  set_pad_size(x_max - x_size, y_max - y_size);
+  do_reconsider_image_properties(x_max, y_max, alpha?4:3, 
+                                 T_unsigned_byte, cdata->_pages.size());
+  do_set_pad_size(x_max - x_size, y_max - y_size, 0);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -280,12 +237,12 @@ do_read_one(const Filename &fullpath, const Filename &alpha_fullpath,
       set_name(fullpath.get_basename_wo_extension());
       set_name(fullpath.get_basename_wo_extension());
     }
     }
     if (!has_filename()) {
     if (!has_filename()) {
-      set_filename(fullpath);
-      set_alpha_filename(alpha_fullpath);
+      _filename = fullpath;
+      _alpha_filename = alpha_fullpath;
     }
     }
     
     
-    set_fullpath(fullpath);
-    set_alpha_fullpath(alpha_fullpath);
+    _fullpath = fullpath;
+    _alpha_fullpath = alpha_fullpath;
   }
   }
 
 
   _primary_file_num_channels = primary_file_num_channels;
   _primary_file_num_channels = primary_file_num_channels;
@@ -314,7 +271,7 @@ do_load_one(PT(MovieVideoCursor) color, PT(MovieVideoCursor) alpha, int z) {
     cdata->_pages.resize(z+1);
     cdata->_pages.resize(z+1);
     cdata->_pages[z]._color = color;
     cdata->_pages[z]._color = color;
     cdata->_pages[z]._alpha = alpha;
     cdata->_pages[z]._alpha = alpha;
-    recalculate_image_properties(cdata);
+    do_recalculate_image_properties(cdata);
   }
   }
   
   
   return true;
   return true;
@@ -436,6 +393,64 @@ get_keep_ram_image() const {
   return true;
   return true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: MovieTexture::do_make_copy
+//       Access: Protected, Virtual
+//  Description: Returns a new copy of the same Texture.  This copy,
+//               if applied to geometry, will be copied into texture
+//               as a separate texture from the original, so it will
+//               be duplicated in texture memory (and may be
+//               independently modified if desired).
+//               
+//               If the Texture is an MovieTexture, the resulting
+//               duplicate may be animated independently of the
+//               original.
+////////////////////////////////////////////////////////////////////
+PT(Texture) MovieTexture::
+do_make_copy() {
+  PT(MovieTexture) tex = new MovieTexture(get_name());
+  tex->do_assign(*this);
+
+  return tex.p();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MovieTexture::do_assign
+//       Access: Protected
+//  Description: Implements make_copy().
+////////////////////////////////////////////////////////////////////
+void MovieTexture::
+do_assign(const MovieTexture &copy) {
+  // Since 'make_copy' can be a slow operation, 
+  // I release the read lock before calling make_copy.
+  
+  pvector<MovieVideoCursor *> color;
+  pvector<MovieVideoCursor *> alpha;
+  {
+    CDReader copy_cdata(copy._cycler);
+    color.resize(copy_cdata->_pages.size());
+    alpha.resize(copy_cdata->_pages.size());
+    for (int i=0; i<(int)(color.size()); i++) {
+      color[i] = copy_cdata->_pages[i]._color;
+      alpha[i] = copy_cdata->_pages[i]._alpha;
+    }
+  }
+  
+  {
+    CDWriter cdata(_cycler);
+    cdata->_pages.resize(color.size());
+    for (int i=0; i<(int)(color.size()); i++) {
+      if (color[i]) {
+        cdata->_pages[i]._color = color[i]->get_source()->open();
+      }
+      if (alpha[i]) {
+        cdata->_pages[i]._alpha = alpha[i]->get_source()->open();
+      }
+    }
+    do_recalculate_image_properties(cdata);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MovieTexture::reload_ram_image
 //     Function: MovieTexture::reload_ram_image
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
@@ -444,7 +459,7 @@ get_keep_ram_image() const {
 //               source MovieVideo.
 //               source MovieVideo.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void MovieTexture::
 void MovieTexture::
-reload_ram_image() {
+do_reload_ram_image() {
   // A MovieTexture should never dump its RAM image.
   // A MovieTexture should never dump its RAM image.
   // Therefore, this is not needed.
   // Therefore, this is not needed.
 }
 }

+ 6 - 5
panda/src/grutil/movieTexture.h

@@ -32,13 +32,11 @@ class EXPCL_PANDA_GRUTIL MovieTexture : public Texture {
 PUBLISHED:
 PUBLISHED:
   MovieTexture(const string &name);
   MovieTexture(const string &name);
   MovieTexture(PT(MovieVideo) video);
   MovieTexture(PT(MovieVideo) video);
-protected:
+private:
   MovieTexture(const MovieTexture &copy);
   MovieTexture(const MovieTexture &copy);
 PUBLISHED:
 PUBLISHED:
   virtual ~MovieTexture();
   virtual ~MovieTexture();
 
 
-  virtual PT(Texture) make_copy();
-
   INLINE int get_video_width() const;
   INLINE int get_video_width() const;
   INLINE int get_video_height() const;
   INLINE int get_video_height() const;
   INLINE LVecBase2f get_tex_scale() const;
   INLINE LVecBase2f get_tex_scale() const;
@@ -64,7 +62,10 @@ public:
   virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
   virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
  
  
 protected:
 protected:
-  virtual void reload_ram_image();
+  virtual PT(Texture) do_make_copy();
+  void do_assign(const MovieTexture &copy);
+
+  virtual void do_reload_ram_image();
   virtual bool get_keep_ram_image() const;
   virtual bool get_keep_ram_image() const;
   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,
@@ -108,7 +109,7 @@ protected:
   typedef CycleDataReader<CData> CDReader;
   typedef CycleDataReader<CData> CDReader;
   typedef CycleDataWriter<CData> CDWriter;
   typedef CycleDataWriter<CData> CDWriter;
   
   
-  void recalculate_image_properties(CDWriter &cdata);
+  void do_recalculate_image_properties(CDWriter &cdata);
 
 
 public:
 public:
   static void register_with_read_factory();
   static void register_with_read_factory();

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini