fix crashing bug with compressed texture

This commit is contained in:
David Rose 2009-09-09 18:06:46 +00:00
parent fd62333192
commit c07d10f74b
4 changed files with 92 additions and 78 deletions

View File

@ -8458,8 +8458,9 @@ upload_texture_image(CLP(TextureContext) *gtc,
// we grab the mipmap pointer first, if it is NULL we grab the
// normal mipmap image pointer which is a PTA_uchar
const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
CPTA_uchar ptimage;
if (image_ptr == (const unsigned char *)NULL) {
CPTA_uchar ptimage = tex->get_ram_mipmap_image(n);
ptimage = tex->get_ram_mipmap_image(n);
if (ptimage == (const unsigned char *)NULL) {
GLCAT.warning()
<< "No mipmap level " << n << " defined for " << tex->get_name()
@ -8587,9 +8588,10 @@ upload_texture_image(CLP(TextureContext) *gtc,
}
for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
const unsigned char * image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
CPTA_uchar ptimage;
if (image_ptr == (const unsigned char *)NULL) {
CPTA_uchar ptimage = tex->get_ram_mipmap_image(n);
ptimage = tex->get_ram_mipmap_image(n);
if (ptimage == (const unsigned char *)NULL) {
GLCAT.warning()
<< "No mipmap level " << n << " defined for " << tex->get_name()

View File

@ -2199,3 +2199,14 @@ have_textures_power_2() {
return (_textures_power_2 != ATS_UNSPECIFIED);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::RamImage::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE Texture::RamImage::
RamImage() :
_page_size(0),
_pointer_image(NULL)
{
}

View File

@ -830,7 +830,6 @@ set_ram_image(CPTA_uchar image, Texture::CompressionMode compression,
nassertv(compression != CM_off || image.size() == do_get_expected_ram_image_size());
if (_ram_images.empty()) {
_ram_images.push_back(RamImage());
_ram_images.back()._pointer_image = NULL;
} else {
do_clear_ram_mipmap_images();
}
@ -925,6 +924,71 @@ get_ram_mipmap_image(int n) {
return CPTA_uchar(get_class_type());
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_ram_mipmap_pointer
// Access: Published
// Description: Similiar to get_ram_mipmap_image(), however, in this
// case the void pointer for the given ram image is
// returned. This will be NULL unless it has been
// explicitly set.
////////////////////////////////////////////////////////////////////
void *Texture::
get_ram_mipmap_pointer(int n) {
MutexHolder holder(_lock);
if (n < (int)_ram_images.size()) {
return _ram_images[n]._pointer_image;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_mipmap_pointer
// Access: Published
// Description: Sets an explicit void pointer as the texture's mipmap
// image for the indicated level. This is a special
// call to direct a texture to reference some external
// image location, for instance from a webcam input.
//
// The texture will henceforth reference this pointer
// directly, instead of its own internal storage; the
// user is responsible for ensuring the data at this
// address remains allocated and valid, and in the
// correct format, during the lifetime of the texture.
////////////////////////////////////////////////////////////////////
void Texture::
set_ram_mipmap_pointer(int n, void *image, size_t page_size) {
MutexHolder holder(_lock);
nassertv(_ram_image_compression != CM_off || page_size == get_expected_ram_mipmap_image_size(n));
while (n >= (int)_ram_images.size()) {
_ram_images.push_back(RamImage());
}
//if (page_size == 0) {
// page_size = image.size();
//}
_ram_images[n]._page_size = page_size;
_ram_images[n]._image.clear();
_ram_images[n]._pointer_image = image;
++_image_modified;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_mipmap_pointer_from_int
// Access: Published
// Description: Accepts a raw pointer cast as an int, which is then
// passed to set_ram_mipmap_pointer(); see the
// documentation for that method.
//
// This variant is particularly useful to set an
// external pointer from a language like Python, which
// doesn't support void pointers directly.
////////////////////////////////////////////////////////////////////
void Texture::
set_ram_mipmap_pointer_from_int(long long pointer, int n, int page_size) {
set_ram_mipmap_pointer(n, (void*)pointer, (size_t)page_size);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::clear_ram_mipmap_image
// Access: Published
@ -937,8 +1001,8 @@ clear_ram_mipmap_image(int n) {
if (n >= (int)_ram_images.size()) {
return;
}
_ram_images[n]._image.clear();
_ram_images[n]._page_size = 0;
_ram_images[n]._image.clear();
_ram_images[n]._pointer_image = NULL;
}
@ -3260,8 +3324,8 @@ do_make_ram_image() {
_ram_images.push_back(RamImage());
_ram_images[0]._page_size = do_get_expected_ram_page_size();
_ram_images[0]._image = PTA_uchar::empty_array(do_get_expected_ram_image_size(), get_class_type());
_ram_image_compression = CM_off;
_ram_images[0]._pointer_image = NULL;
_ram_image_compression = CM_off;
return _ram_images[0]._image;
}
@ -3293,13 +3357,11 @@ do_make_ram_mipmap_image(int n) {
while (n >= (int)_ram_images.size()) {
_ram_images.push_back(RamImage());
_ram_images.back()._page_size = 0;
_ram_images.back()._pointer_image = NULL;
}
_ram_images[n]._image = PTA_uchar::empty_array(do_get_expected_ram_mipmap_image_size(n), get_class_type());
_ram_images[n]._page_size = do_get_expected_ram_mipmap_page_size(n);
_ram_images[n]._pointer_image = NULL;
_ram_images[n]._page_size = do_get_expected_ram_mipmap_page_size(n);
return _ram_images[n]._image;
}
@ -3314,8 +3376,6 @@ do_set_ram_mipmap_image(int n, CPTA_uchar image, size_t page_size) {
while (n >= (int)_ram_images.size()) {
_ram_images.push_back(RamImage());
_ram_images.back()._page_size = 0;
_ram_images.back()._pointer_image = NULL;
}
if (page_size == 0) {
page_size = image.size();
@ -3324,72 +3384,12 @@ do_set_ram_mipmap_image(int n, CPTA_uchar image, size_t page_size) {
if (_ram_images[n]._image != image ||
_ram_images[n]._page_size != page_size) {
_ram_images[n]._image = image.cast_non_const();
_ram_images[n]._page_size = page_size;
_ram_images[n]._pointer_image = NULL;
_ram_images[n]._page_size = page_size;
++_image_modified;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_mipmap_pointer
// Access: Published
// Description: Sets this textures ram pointer image. This
////
//
////////////////////////////////////////////////////////////////////
void Texture::
set_ram_mipmap_pointer(int n, void *image, size_t page_size) {
nassertv(_ram_image_compression != CM_off || page_size == get_expected_ram_mipmap_image_size(n));
while (n >= (int)_ram_images.size()) {
_ram_images.push_back(RamImage());
_ram_images.back()._page_size = 0;
_ram_images.back()._pointer_image = NULL;
}
//if (page_size == 0) {
// page_size = image.size();
//}
_ram_images[n]._page_size = page_size;
_ram_images[n]._pointer_image = image;
++_image_modified;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_mipmap_pointer
// Access: Published
// Description: Takes in an int and casts it to a pointer which
// is then used as the textures raw pointer image
////////////////////////////////////////////////////////////////////
void Texture::
set_ram_mipmap_pointer_from_int(long long pointer, int n, int page_size) {
set_ram_mipmap_pointer(n,(void*)pointer,(size_t)page_size);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_ram_mipmap_pointer
// Access: Published
// Description: Returns the system-RAM image data associated with the
// nth mipmap level, if present. Returns NULL if the
// nth mipmap level is not present.
// Similiar to the function above, however, in this case
// the void pointer for the given ram image is
// returned. This will be NULL unless it has been
// explicitly set
////////////////////////////////////////////////////////////////////
void *Texture::
get_ram_mipmap_pointer(int n) {
if (n < (int)_ram_images.size()) {
return _ram_images[n]._pointer_image;
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::consider_auto_process_ram_image
// Access: Protected
@ -4519,7 +4519,6 @@ do_generate_ram_mipmap_images() {
int n = 0;
while (x_size > 1 || y_size > 1 || z_size > 1) {
_ram_images.push_back(RamImage());
_ram_images.back()._pointer_image = NULL;
filter_3d_mipmap_level(_ram_images[n + 1], _ram_images[n],
x_size, y_size, z_size);
x_size = max(x_size >> 1, 1);
@ -4535,7 +4534,6 @@ do_generate_ram_mipmap_images() {
int n = 0;
while (x_size > 1 || y_size > 1) {
_ram_images.push_back(RamImage());
_ram_images.back()._pointer_image = NULL;
filter_2d_mipmap_pages(_ram_images[n + 1], _ram_images[n],
x_size, y_size);
x_size = max(x_size >> 1, 1);
@ -6092,7 +6090,6 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
for (int n = 0; n < num_ram_images; ++n) {
_ram_images.push_back(RamImage());
_ram_images[n]._page_size = get_expected_ram_page_size();
_ram_images[n]._pointer_image = NULL;
if (manager->get_file_minor_ver() >= 1) {
_ram_images[n]._page_size = scan.get_uint32();
}

View File

@ -336,7 +336,7 @@ PUBLISHED:
INLINE size_t get_expected_ram_mipmap_image_size(int n) const;
INLINE size_t get_expected_ram_mipmap_page_size(int n) const;
CPTA_uchar get_ram_mipmap_image(int n);
void * get_ram_mipmap_pointer(int n);
void *get_ram_mipmap_pointer(int n);
INLINE PTA_uchar modify_ram_mipmap_image(int n);
INLINE PTA_uchar make_ram_mipmap_image(int n);
void set_ram_mipmap_pointer(int n, void *image, size_t page_size = 0);
@ -559,10 +559,14 @@ protected:
// This nested class declaration is used below.
class RamImage {
public:
INLINE RamImage();
PTA_uchar _image;
size_t _page_size;
void *_pointer_image; // we will allow the ram image to accept a void* (basically a block of memory)
// instead of a PTA_uchar
// If _pointer_image is non-NULL, it represents an external block
// of memory that is used instead of the above PTA_uchar.
void *_pointer_image;
};
private: