[Bf-blender-cvs] [e167140e5d8] temp-gpu-texture-partial-updates: WIP: partial update image.

Jeroen Bakker noreply at git.blender.org
Wed Nov 17 15:29:44 CET 2021


Commit: e167140e5d8c3d29432d7a8cabd87160082c2738
Author: Jeroen Bakker
Date:   Tue Nov 16 12:59:19 2021 +0100
Branches: temp-gpu-texture-partial-updates
https://developer.blender.org/rBe167140e5d8c3d29432d7a8cabd87160082c2738

WIP: partial update image.

Differential Revision: https://developer.blender.org/D13238

===================================================================

M	source/blender/blenkernel/intern/image_partial_update.cc
M	source/blender/blenkernel/intern/image_partial_update_test.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index 1eb054018b7..4dfbd4fa093 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -108,7 +108,7 @@ struct TileChangeset {
 
   bool has_dirty_tiles() const
   {
-    return has_dirty_tiles();
+    return has_dirty_tiles_;
   }
 
   void init_tiles(int tile_x_len, int tile_y_len)
@@ -167,15 +167,24 @@ struct TileChangeset {
   }
 };
 
-/** \brief Partial update data that is stored inside the image. */
+/**
+ * \brief Partial update changes stored inside the image runtime.
+ *
+ * The PartialUpdateRegisterImpl will keep track of changes over time. Changes are groups inside
+ * TileChangesets.
+ */
 struct PartialUpdateRegisterImpl {
   /* Changes are tracked in tiles. */
   static constexpr int TILE_SIZE = 256;
 
+  /** \brief changeset id of the first changeset kept in #history. */
   ChangesetID first_changeset_id;
-  ChangesetID current_changeset_id;
-  Vector<TileChangeset> history;
+  /** \brief changeset id of the top changeset kept in #history. */
+  ChangesetID last_changeset_id;
 
+  /** \brief history of changesets. */
+  Vector<TileChangeset> history;
+  /** \brief The current changeset. New changes will be added to this changeset only. */
   TileChangeset current_changeset;
 
   int image_width;
@@ -198,9 +207,9 @@ struct PartialUpdateRegisterImpl {
   void mark_full_update()
   {
     history.clear();
-    current_changeset_id++;
+    last_changeset_id++;
     current_changeset.reset();
-    first_changeset_id = current_changeset_id;
+    first_changeset_id = last_changeset_id;
   }
 
   /**
@@ -261,7 +270,7 @@ struct PartialUpdateRegisterImpl {
   {
     history.append_as(std::move(current_changeset));
     current_changeset.reset();
-    current_changeset_id++;
+    last_changeset_id++;
   }
 
   /**
@@ -320,12 +329,12 @@ ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(Image *image,
   partial_updater->ensure_empty_changeset();
 
   if (!partial_updater->can_construct(user_impl->last_changeset_id)) {
-    user_impl->last_changeset_id = partial_updater->current_changeset_id;
+    user_impl->last_changeset_id = partial_updater->last_changeset_id;
     return PARTIAL_UPDATE_NEED_FULL_UPDATE;
   }
 
   /* Check if there are changes since last invocation for the user. */
-  if (user_impl->last_changeset_id == partial_updater->current_changeset_id) {
+  if (user_impl->last_changeset_id == partial_updater->last_changeset_id) {
     return PARTIAL_UPDATE_NO_CHANGES;
   }
 
@@ -336,19 +345,21 @@ ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(Image *image,
   /* Convert tiles in the changeset to rectangles that are dirty. */
   for (int tile_y = 0; tile_y < changed_tiles->tile_y_len_; tile_y++) {
     for (int tile_x = 0; tile_x < changed_tiles->tile_x_len_; tile_x++) {
-      if (changed_tiles->is_tile_dirty(tile_x, tile_y)) {
-        PartialUpdateTile tile;
-        BLI_rcti_init(&tile.region,
-                      tile_x * PartialUpdateRegisterImpl::TILE_SIZE,
-                      (tile_x + 1) * PartialUpdateRegisterImpl::TILE_SIZE,
-                      tile_y * PartialUpdateRegisterImpl::TILE_SIZE,
-                      (tile_y + 1) * PartialUpdateRegisterImpl::TILE_SIZE);
-        user_impl->updated_tiles.append_as(tile);
+      if (!changed_tiles->is_tile_dirty(tile_x, tile_y)) {
+        continue;
       }
+
+      PartialUpdateTile tile;
+      BLI_rcti_init(&tile.region,
+                    tile_x * PartialUpdateRegisterImpl::TILE_SIZE,
+                    (tile_x + 1) * PartialUpdateRegisterImpl::TILE_SIZE,
+                    tile_y * PartialUpdateRegisterImpl::TILE_SIZE,
+                    (tile_y + 1) * PartialUpdateRegisterImpl::TILE_SIZE);
+      user_impl->updated_tiles.append_as(tile);
     }
   }
 
-  user_impl->last_changeset_id = partial_updater->current_changeset_id;
+  user_impl->last_changeset_id = partial_updater->last_changeset_id;
   return PARTIAL_UPDATE_CHANGES_AVAILABLE;
 }
 
diff --git a/source/blender/blenkernel/intern/image_partial_update_test.cc b/source/blender/blenkernel/intern/image_partial_update_test.cc
index 84cf3454d2f..91a74b8107e 100644
--- a/source/blender/blenkernel/intern/image_partial_update_test.cc
+++ b/source/blender/blenkernel/intern/image_partial_update_test.cc
@@ -326,4 +326,34 @@ TEST_F(ImagePartialUpdateTest, sequential_mark_region)
   }
 }
 
+TEST_F(ImagePartialUpdateTest, mark_multiple_tiles)
+{
+  ePartialUpdateCollectResult result;
+  /* First tile should always return a full update. */
+  result = BKE_image_partial_update_collect_tiles(image, image_buffer, partial_update_user);
+  EXPECT_EQ(result, PARTIAL_UPDATE_NEED_FULL_UPDATE);
+  /* Second invoke should now detect no changes. */
+  result = BKE_image_partial_update_collect_tiles(image, image_buffer, partial_update_user);
+  EXPECT_EQ(result, PARTIAL_UPDATE_NO_CHANGES);
+
+  /* Mark region. */
+  rcti region;
+  BLI_rcti_init(&region, 300, 700, 300, 700);
+  BKE_image_partial_update_register_mark_region(image, image_buffer, &region);
+
+  /* Partial Update should be available. */
+  result = BKE_image_partial_update_collect_tiles(image, image_buffer, partial_update_user);
+  EXPECT_EQ(result, PARTIAL_UPDATE_CHANGES_AVAILABLE);
+
+  /* Check tiles. */
+  PartialUpdateTile changed_tile;
+  int num_tiles_found = 0;
+  while (BKE_image_partial_update_next_tile(partial_update_user, &changed_tile) ==
+         PARTIAL_UPDATE_ITER_TILE_LOADED) {
+    BLI_rcti_isect(&changed_tile.region, &region, nullptr);
+    num_tiles_found++;
+  }
+  EXPECT_EQ(num_tiles_found, 4);
+}
+
 }  // namespace blender::bke::image



More information about the Bf-blender-cvs mailing list