[Bf-blender-cvs] [152ad1c2088] temp-gpu-texture-partial-updates: Clearing history.
Jeroen Bakker
noreply at git.blender.org
Fri Nov 19 15:23:18 CET 2021
Commit: 152ad1c2088747aa18dc82683f351de8bdf2b00d
Author: Jeroen Bakker
Date: Fri Nov 19 14:06:41 2021 +0100
Branches: temp-gpu-texture-partial-updates
https://developer.blender.org/rB152ad1c2088747aa18dc82683f351de8bdf2b00d
Clearing history.
===================================================================
M source/blender/blenkernel/BKE_image.h
M source/blender/blenkernel/intern/image_gpu.c
M source/blender/blenkernel/intern/image_partial_update.cc
M source/blender/blenkernel/intern/image_partial_update_test.cc
M source/blender/imbuf/intern/moviecache.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 9b3bc89a0e7..5efc5e53ff2 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -483,9 +483,9 @@ struct PartialUpdateRegister;
void BKE_image_partial_update_register_free(struct Image *image);
/** \brief Mark a region of the image to update. */
void BKE_image_partial_update_mark_region(struct Image *image,
- struct ImageTile *image_tile,
- struct ImBuf *image_buffer,
- rcti *updated_region);
+ const struct ImageTile *image_tile,
+ const struct ImBuf *image_buffer,
+ const rcti *updated_region);
/** \brief Mark the whole image to be updated. */
void BKE_image_partial_update_mark_full_update(struct Image *image);
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
index 15444dcf7c5..c980d945946 100644
--- a/source/blender/blenkernel/intern/image_gpu.c
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -945,7 +945,8 @@ void BKE_image_update_gputexture_delayed(struct Image *ima,
int h)
{
/* Check for full refresh. */
- if (ibuf && image_tile->tile_number == 0 && x == 0 && y == 0 && w == ibuf->x && h == ibuf->y) {
+ if (ibuf != NULL && ima->source != IMA_SRC_TILED && x == 0 && y == 0 && w == ibuf->x &&
+ h == ibuf->y) {
BKE_image_partial_update_mark_full_update(ima);
}
else {
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index b12b83bae9e..63e6ef7feb2 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -60,6 +60,18 @@ namespace blender::bke::image::partial_update {
/** \brief Size of chunks to track changes. */
constexpr int CHUNK_SIZE = 256;
+/**
+ * \brief Max number of changesets to keep in history.
+ *
+ * A higher number would need more memory and processing
+ * to calculate a changeset, but would lead to do partial updates for requests that don't happen
+ * every frame.
+ *
+ * A to small number would lead to more full updates when changes couldn't be reconstructed from
+ * the available history.
+ */
+constexpr int MAX_HISTORY_LEN = 4;
+
/**
* \brief get the chunk number for the give pixel coordinate.
*
@@ -154,16 +166,18 @@ struct TileChangeset {
public:
/** \brief Width of the tile in pixels. */
int tile_width;
- /** \brief Hieght of the tile in pixels. */
+ /** \brief Height of the tile in pixels. */
int tile_height;
/** \brief Number of chunks along the x-axis. */
- int chunk_x_len_;
+ int chunk_x_len;
/** \brief Number of chunks along the y-axis. */
- int chunk_y_len_;
+ int chunk_y_len;
+
+ TileNumber tile_number;
void clear()
{
- init_chunks(chunk_x_len_, chunk_y_len_);
+ init_chunks(chunk_x_len, chunk_y_len);
}
/**
@@ -172,7 +186,7 @@ struct TileChangeset {
* \returns true: resolution has been updated.
* false: resolution was unchanged.
*/
- bool update_resolution(ImBuf *image_buffer)
+ bool update_resolution(const ImBuf *image_buffer)
{
if (tile_width == image_buffer->x && tile_height == image_buffer->y) {
return false;
@@ -187,7 +201,7 @@ struct TileChangeset {
return true;
}
- void mark_region(rcti *updated_region)
+ void mark_region(const rcti *updated_region)
{
int start_x_chunk = chunk_number_for_pixel(updated_region->xmin);
int end_x_chunk = chunk_number_for_pixel(updated_region->xmax - 1);
@@ -197,14 +211,14 @@ struct TileChangeset {
/* Clamp tiles to tiles in image. */
start_x_chunk = max_ii(0, start_x_chunk);
start_y_chunk = max_ii(0, start_y_chunk);
- end_x_chunk = min_ii(chunk_x_len_ - 1, end_x_chunk);
- end_y_chunk = min_ii(chunk_y_len_ - 1, end_y_chunk);
+ end_x_chunk = min_ii(chunk_x_len - 1, end_x_chunk);
+ end_y_chunk = min_ii(chunk_y_len - 1, end_y_chunk);
/* Early exit when no tiles need to be updated. */
- if (start_x_chunk >= chunk_x_len_) {
+ if (start_x_chunk >= chunk_x_len) {
return;
}
- if (start_y_chunk >= chunk_y_len_) {
+ if (start_y_chunk >= chunk_y_len) {
return;
}
if (end_x_chunk < 0) {
@@ -221,7 +235,7 @@ struct TileChangeset {
{
for (int chunk_y = start_y_chunk; chunk_y <= end_y_chunk; chunk_y++) {
for (int chunk_x = start_x_chunk; chunk_x <= end_x_chunk; chunk_x++) {
- int chunk_index = chunk_y * chunk_x_len_ + chunk_x;
+ int chunk_index = chunk_y * chunk_x_len + chunk_x;
chunk_dirty_flags_[chunk_index] = true;
}
}
@@ -233,10 +247,10 @@ struct TileChangeset {
return has_dirty_chunks_;
}
- void init_chunks(int chunk_x_len, int chunk_y_len)
+ void init_chunks(int chunk_x_len_, int chunk_y_len_)
{
- chunk_x_len_ = chunk_x_len;
- chunk_y_len_ = chunk_y_len;
+ chunk_x_len = chunk_x_len_;
+ chunk_y_len = chunk_y_len_;
const int chunk_len = chunk_x_len * chunk_y_len;
const int previous_chunk_len = chunk_dirty_flags_.size();
@@ -254,9 +268,9 @@ struct TileChangeset {
/** \brief Merge the given changeset into the receiver. */
void merge(const TileChangeset &other)
{
- BLI_assert(chunk_x_len_ == other.chunk_x_len_);
- BLI_assert(chunk_y_len_ == other.chunk_y_len_);
- const int chunk_len = chunk_x_len_ * chunk_y_len_;
+ BLI_assert(chunk_x_len == other.chunk_x_len);
+ BLI_assert(chunk_y_len == other.chunk_y_len);
+ const int chunk_len = chunk_x_len * chunk_y_len;
for (int chunk_index = 0; chunk_index < chunk_len; chunk_index++) {
chunk_dirty_flags_[chunk_index] = chunk_dirty_flags_[chunk_index] |
@@ -268,27 +282,56 @@ struct TileChangeset {
/** \brief has a chunk changed inside this changeset. */
bool is_chunk_dirty(int chunk_x, int chunk_y) const
{
- const int chunk_index = chunk_y * chunk_x_len_ + chunk_x;
+ const int chunk_index = chunk_y * chunk_x_len + chunk_x;
return chunk_dirty_flags_[chunk_index];
}
};
+/** \brief Changeset keeping track of changes for an image */
struct Changeset {
private:
- TileChangeset tile_changeset;
+ Vector<TileChangeset> tiles;
public:
+ /** \brief Keep track if any of the tiles have dirty chunks. */
bool has_dirty_chunks;
public:
- TileChangeset &operator[](ImageTile *UNUSED(image_tile))
+ /**
+ * \brief Retrieve the TileChangeset for the given ImageTile.
+ *
+ * When the TileChangeset isn't found, it will be added.
+ */
+ TileChangeset &operator[](const ImageTile *image_tile)
+ {
+ for (TileChangeset &tile_changeset : tiles) {
+ if (tile_changeset.tile_number == image_tile->tile_number) {
+ return tile_changeset;
+ }
+ }
+
+ TileChangeset tile_changeset;
+ tile_changeset.tile_number = image_tile->tile_number;
+ tiles.append_as(tile_changeset);
+
+ return tiles.last();
+ }
+
+ /** \brief Does this changeset contain data for the given tile. */
+ bool has_tile(const ImageTile *image_tile)
{
- return tile_changeset;
+ for (TileChangeset &tile_changeset : tiles) {
+ if (tile_changeset.tile_number == image_tile->tile_number) {
+ return true;
+ }
+ }
+ return false;
}
+ /** \brief Clear this changeset. */
void clear()
{
- tile_changeset.clear();
+ tiles.clear();
has_dirty_chunks = false;
}
};
@@ -307,10 +350,10 @@ struct PartialUpdateRegisterImpl {
/** \brief history of changesets. */
Vector<Changeset> history;
- /** \brief The current changeset. New changes will be added to this changeset only. */
+ /** \brief The current changeset. New changes will be added to this changeset. */
Changeset current_changeset;
- void update_resolution(ImageTile *image_tile, ImBuf *image_buffer)
+ void update_resolution(const ImageTile *image_tile, const ImBuf *image_buffer)
{
TileChangeset &tile_changeset = current_changeset[image_tile];
const bool has_dirty_chunks = tile_changeset.has_dirty_chunks();
@@ -329,7 +372,7 @@ struct PartialUpdateRegisterImpl {
first_changeset_id = last_changeset_id;
}
- void mark_region(ImageTile *image_tile, rcti *updated_region)
+ void mark_region(const ImageTile *image_tile, const rcti *updated_region)
{
TileChangeset &tile_changeset = current_changeset[image_tile];
tile_changeset.mark_region(updated_region);
@@ -344,9 +387,10 @@ struct PartialUpdateRegisterImpl {
return;
}
commit_current_changeset();
+ limit_history();
}
- /** Move the current changeset to the history and resets the current changeset. */
+ /** \brief Move the current changeset to the history and resets the current changeset. */
void commit_current_changeset()
{
history.append_as(std::move(current_changeset));
@@ -354,6 +398,16 @@ struct PartialUpdateRegisterImpl {
last_changeset_id++;
}
+ /** \brief Limit the number of items in the changeset. */
+ void limit_history()
+ {
+ const int num_items_to_remove = max_ii(history.size() - MAX_HISTORY_LEN, 0);
+ if (num_items_to_remove == 0) {
+ return;
+ }
+ history.remove(0, num_items_to_remove);
+ }
+
/**
* /brief Check if data is available to construct the update tiles for the given
* changeset_id.
@@ -368,15 +422,9 @@ struct PartialUpdateRegisterImpl {
/**
* \brief collect all historic changes since a given changeset.
*/
- // TODO(jbakker): add tile_number as parameter.
- std::optional<TileChangeset> changed_tile_chunks_since(const TileNumber UNUSED(tile_number),
+ std::optional<TileChangeset> changed_tile_chunks_since(const ImageTile *image_tile,
const ChangesetID from_changeset)
{
- std::unique_ptr<TileChangeset> changed_tiles = std::make_unique<TileChangeset>();
- int chunk_x_len = image_width / CHUNK_SIZE;
-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list