mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 00:06:44 -04:00
gobj: Implement texture modification tracking for individual pages
Part of #1168, GL implementation in following commit
This commit is contained in:
parent
77f486a07b
commit
494631ac54
@ -357,8 +357,6 @@ INLINE bool Texture::
|
||||
load(const PNMImage &pnmimage, const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
do_clear(cdata);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
if (do_load_one(cdata, pnmimage, get_name(), 0, 0, options)) {
|
||||
bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0);
|
||||
consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true);
|
||||
@ -374,7 +372,7 @@ INLINE bool Texture::
|
||||
load(const PNMImage &pnmimage, int z, int n, const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
cdata->inc_image_page_modified(z);
|
||||
if (do_load_one(cdata, pnmimage, get_name(), z, n, options)) {
|
||||
return true;
|
||||
}
|
||||
@ -388,8 +386,6 @@ INLINE bool Texture::
|
||||
load(const PfmFile &pfm, const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
do_clear(cdata);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
if (do_load_one(cdata, pfm, get_name(), 0, 0, options)) {
|
||||
bool generate_mipmaps = ((options.get_texture_flags() & LoaderOptions::TF_generate_mipmaps) != 0);
|
||||
consider_auto_process_ram_image(generate_mipmaps || uses_mipmaps(), true);
|
||||
@ -405,7 +401,7 @@ INLINE bool Texture::
|
||||
load(const PfmFile &pfm, int z, int n, const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
cdata->inc_image_page_modified(z);
|
||||
if (do_load_one(cdata, pfm, get_name(), z, n, options)) {
|
||||
return true;
|
||||
}
|
||||
@ -2460,11 +2456,14 @@ inc_properties_modified() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Marks the whole image as modified.
|
||||
*/
|
||||
INLINE void Texture::CData::
|
||||
inc_image_modified() {
|
||||
++_image_modified;
|
||||
_modified_pages.resize(1);
|
||||
_modified_pages[0]._z_end = (size_t)-1;
|
||||
_modified_pages[0]._modified = _image_modified;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -551,8 +551,6 @@ bool Texture::
|
||||
read(const Filename &fullpath, const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
do_clear(cdata);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
return do_read(cdata, fullpath, Filename(), 0, 0, 0, 0, false, false,
|
||||
options, nullptr);
|
||||
}
|
||||
@ -570,8 +568,6 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
do_clear(cdata);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
return do_read(cdata, fullpath, alpha_fullpath, primary_file_num_channels,
|
||||
alpha_file_channel, 0, 0, false, false,
|
||||
options, nullptr);
|
||||
@ -585,12 +581,15 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
* the various parameters.
|
||||
*/
|
||||
bool Texture::
|
||||
read(const Filename &fullpath, int z, int n,
|
||||
bool read_pages, bool read_mipmaps,
|
||||
read(const Filename &fullpath, int z, int n, bool read_pages, bool read_mipmaps,
|
||||
const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
if (read_pages) {
|
||||
cdata->inc_image_modified();
|
||||
} else {
|
||||
cdata->inc_image_page_modified(z);
|
||||
}
|
||||
return do_read(cdata, fullpath, Filename(), 0, 0, z, n, read_pages, read_mipmaps,
|
||||
options, nullptr);
|
||||
}
|
||||
@ -655,7 +654,11 @@ read(const Filename &fullpath, const Filename &alpha_fullpath,
|
||||
const LoaderOptions &options) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->inc_properties_modified();
|
||||
cdata->inc_image_modified();
|
||||
if (read_pages) {
|
||||
cdata->inc_image_modified();
|
||||
} else {
|
||||
cdata->inc_image_page_modified(z);
|
||||
}
|
||||
return do_read(cdata, fullpath, alpha_fullpath, primary_file_num_channels,
|
||||
alpha_file_channel, z, n, read_pages, read_mipmaps,
|
||||
options, record);
|
||||
@ -1422,6 +1425,39 @@ peek() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SparseArray containing all the image pages that have been modified
|
||||
* since the given UpdateSeq value.
|
||||
*/
|
||||
SparseArray Texture::
|
||||
get_image_modified_pages(UpdateSeq since, int n) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
SparseArray result;
|
||||
if (since == cdata->_image_modified) {
|
||||
// Early-out since no range is more recent than _image_modified.
|
||||
return result;
|
||||
}
|
||||
|
||||
if (n > 0 && cdata->_texture_type == Texture::TT_3d_texture) {
|
||||
// Don't bother handling this special case, just consider all mipmap pages
|
||||
// modified.
|
||||
result.set_range(0, do_get_expected_mipmap_z_size(cdata, n));
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const ModifiedPageRange &range : cdata->_modified_pages) {
|
||||
if (range._z_begin >= cdata->_z_size) {
|
||||
break;
|
||||
}
|
||||
if (since < range._modified) {
|
||||
result.set_range(range._z_begin, std::min(range._z_end, (size_t)cdata->_z_size) - range._z_begin);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that the texture should be enqueued to be prepared in the
|
||||
* indicated prepared_objects at the beginning of the next frame. This will
|
||||
@ -3541,7 +3577,7 @@ do_load_sub_image(CData *cdata, const PNMImage &image, int x, int y, int z, int
|
||||
// Flip y
|
||||
y = cdata->_y_size - (image.get_y_size() + y);
|
||||
|
||||
cdata->inc_image_modified();
|
||||
cdata->inc_image_page_modified(z);
|
||||
do_modify_ram_mipmap_image(cdata, n);
|
||||
convert_from_pnmimage(cdata->_ram_images[n]._image,
|
||||
do_get_expected_ram_mipmap_page_size(cdata, n),
|
||||
@ -10619,6 +10655,10 @@ CData() {
|
||||
_simple_ram_image._page_size = 0;
|
||||
|
||||
_has_clear_color = false;
|
||||
|
||||
_modified_pages.resize(1);
|
||||
_modified_pages[0]._z_end = (size_t)-1;
|
||||
_modified_pages[0]._modified = _image_modified;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -10633,6 +10673,7 @@ CData(const Texture::CData ©) {
|
||||
_properties_modified = copy._properties_modified;
|
||||
_image_modified = copy._image_modified;
|
||||
_simple_image_modified = copy._simple_image_modified;
|
||||
_modified_pages = copy._modified_pages;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -10690,6 +10731,46 @@ do_assign(const Texture::CData *copy) {
|
||||
_simple_ram_image = copy->_simple_ram_image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a single page of the image as modified.
|
||||
*/
|
||||
void Texture::CData::
|
||||
inc_image_page_modified(int z) {
|
||||
++_image_modified;
|
||||
|
||||
ModifiedPageRanges::iterator it = _modified_pages.begin();
|
||||
while (it != _modified_pages.end() && (*it)._z_end <= z) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
nassertv(it != _modified_pages.end());
|
||||
|
||||
size_t orig_z_end = (*it)._z_end;
|
||||
UpdateSeq orig_modified = (*it)._modified;
|
||||
|
||||
if (z > (*it)._z_begin) {
|
||||
// Split prefix.
|
||||
ModifiedPageRange copy(*it);
|
||||
copy._z_end = z;
|
||||
it = _modified_pages.insert(it, copy);
|
||||
++it;
|
||||
}
|
||||
|
||||
(*it)._z_begin = z;
|
||||
(*it)._z_end = z + 1;
|
||||
(*it)._modified = _image_modified;
|
||||
|
||||
if (z + 1 < orig_z_end) {
|
||||
// Split suffix.
|
||||
ModifiedPageRange copy(*it);
|
||||
copy._z_begin = z + 1;
|
||||
copy._z_end = orig_z_end;
|
||||
copy._modified = orig_modified;
|
||||
++it;
|
||||
_modified_pages.insert(it, copy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the contents of this object to the datagram for shipping out to a
|
||||
* Bam file.
|
||||
|
@ -525,6 +525,8 @@ PUBLISHED:
|
||||
MAKE_PROPERTY(image_modified, get_image_modified);
|
||||
MAKE_PROPERTY(simple_image_modified, get_simple_image_modified);
|
||||
|
||||
SparseArray get_image_modified_pages(UpdateSeq since, int n = 0) const;
|
||||
|
||||
INLINE bool has_auto_texture_scale() const;
|
||||
INLINE AutoTextureScale get_auto_texture_scale() const;
|
||||
INLINE void set_auto_texture_scale(AutoTextureScale scale);
|
||||
@ -932,6 +934,13 @@ private:
|
||||
protected:
|
||||
typedef pvector<RamImage> RamImages;
|
||||
|
||||
struct ModifiedPageRange {
|
||||
size_t _z_begin = 0;
|
||||
size_t _z_end;
|
||||
UpdateSeq _modified;
|
||||
};
|
||||
typedef pvector<ModifiedPageRange> ModifiedPageRanges;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA_GOBJ CData : public CycleData {
|
||||
public:
|
||||
@ -949,6 +958,7 @@ protected:
|
||||
void do_assign(const CData *copy);
|
||||
INLINE void inc_properties_modified();
|
||||
INLINE void inc_image_modified();
|
||||
void inc_image_page_modified(int z);
|
||||
INLINE void inc_simple_image_modified();
|
||||
|
||||
Filename _filename;
|
||||
@ -1020,6 +1030,8 @@ protected:
|
||||
UpdateSeq _image_modified;
|
||||
UpdateSeq _simple_image_modified;
|
||||
|
||||
ModifiedPageRanges _modified_pages;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
|
@ -76,6 +76,15 @@ was_simple_image_modified() const {
|
||||
return _simple_image_modified != get_texture()->get_simple_image_modified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given page of the texture image has been modified since
|
||||
* the last time mark_loaded() was called.
|
||||
*/
|
||||
INLINE bool TextureContext::
|
||||
was_image_page_modified(int z, int n) const {
|
||||
return get_texture()->get_image_modified_pages(_image_modified, n).get_bit(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sequence number which is guaranteed to change at least every time
|
||||
* the texture properties (unrelated to the image) are modified.
|
||||
@ -103,6 +112,15 @@ get_simple_image_modified() const {
|
||||
return _simple_image_modified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a SparseArray indicating which pages of the texture have been
|
||||
* modified since the last call to mark_loaded().
|
||||
*/
|
||||
INLINE SparseArray TextureContext::
|
||||
get_image_modified_pages(int n) const {
|
||||
return get_texture()->get_image_modified_pages(_image_modified, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called (usually by a derived class) when the on-card size of this
|
||||
* object has changed.
|
||||
|
@ -44,11 +44,14 @@ PUBLISHED:
|
||||
INLINE bool was_properties_modified() const;
|
||||
INLINE bool was_image_modified() const;
|
||||
INLINE bool was_simple_image_modified() const;
|
||||
INLINE bool was_image_page_modified(int z, int n) const;
|
||||
|
||||
INLINE UpdateSeq get_properties_modified() const;
|
||||
INLINE UpdateSeq get_image_modified() const;
|
||||
INLINE UpdateSeq get_simple_image_modified() const;
|
||||
|
||||
INLINE SparseArray get_image_modified_pages(int n = 0) const;
|
||||
|
||||
public:
|
||||
INLINE void update_data_size_bytes(size_t new_data_size_bytes);
|
||||
INLINE void mark_loaded();
|
||||
|
Loading…
x
Reference in New Issue
Block a user