[Bf-blender-cvs] [c957c87ff07] temp-gpu-texture-partial-updates: Added mark region dirty.

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


Commit: c957c87ff0792361c6ed28198058e6c0624baec2
Author: Jeroen Bakker
Date:   Tue Nov 16 10:55:53 2021 +0100
Branches: temp-gpu-texture-partial-updates
https://developer.blender.org/rBc957c87ff0792361c6ed28198058e6c0624baec2

Added mark region dirty.

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

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.c
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/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index bb600eb3f0c..8d4ab977f43 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -417,8 +417,9 @@ typedef enum ePartialUpdateCollectResult {
  * tiles are requested they are merged with neighboring tiles.
  */
 typedef struct PartialUpdateTile {
-  /** \brief area of the image that has been updated. */
-  struct rcti update_area;
+  /** \brief region of the image that has been updated. Region can be bigger than actual changes.
+   */
+  struct rcti region;
 } PartialUpdateTile;
 
 /**
@@ -429,7 +430,7 @@ typedef enum ePartialUpdateIterResult {
   PARTIAL_UPDATE_ITER_NO_TILES_LEFT = 0,
 
   /** \brief a tile was available and has been loaded. */
-  PARTIAL_UPDATE_ITER_NEW_TILE_LOADED = 1,
+  PARTIAL_UPDATE_ITER_TILE_LOADED = 1,
 } ePartialUpdateIterResult;
 
 /**
@@ -458,6 +459,7 @@ void BKE_image_partial_update_free(struct PartialUpdateUser *user);
  *              using #BKE_image_partial_update_next_tile.
  */
 ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(struct Image *image,
+                                                                   struct ImBuf *image_buffer,
                                                                    struct PartialUpdateUser *user);
 
 ePartialUpdateIterResult BKE_image_partial_update_next_tile(struct PartialUpdateUser *user,
@@ -470,7 +472,9 @@ struct PartialUpdateRegister *BKE_image_partial_update_register_ensure(struct Im
                                                                        struct ImBuf *image_buffer);
 void BKE_image_partial_update_register_free(struct Image *image);
 /** \brief Mark a region of the image to update. */
-void BKE_image_partial_update_register_mark_region(struct Image *image, rcti *updated_region);
+void BKE_image_partial_update_register_mark_region(struct Image *image,
+                                                   struct ImBuf *image_buffer,
+                                                   rcti *updated_region);
 /** \brief Mark the whole image to be updated. */
 void BKE_image_partial_update_register_mark_full_update(struct Image *image,
                                                         struct ImBuf *image_buffer);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index e17d0f33d93..3a7c62e503c 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -134,6 +134,15 @@ static void image_runtime_reset_on_copy(struct Image *image)
   image->runtime.partial_update_register = NULL;
 }
 
+static void image_runtime_free_data(struct Image *image)
+{
+  BLI_mutex_end(image->runtime.cache_mutex);
+  MEM_freeN(image->runtime.cache_mutex);
+  image->runtime.cache_mutex = NULL;
+
+  BKE_image_partial_update_register_free(image);
+}
+
 static void image_init_data(ID *id)
 {
   Image *image = (Image *)id;
@@ -213,8 +222,7 @@ static void image_free_data(ID *id)
   BLI_freelistN(&image->tiles);
   BLI_freelistN(&image->gpu_refresh_areas);
 
-  BLI_mutex_end(image->runtime.cache_mutex);
-  MEM_freeN(image->runtime.cache_mutex);
+  image_runtime_free_data(image);
 }
 
 static void image_foreach_cache(ID *id,
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index 89fa5889c96..12c251ed484 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -107,9 +107,19 @@ struct PartialUpdateTransaction {
     tile_y_len_ = tile_y_len;
     const int tile_len = tile_x_len * tile_y_len;
     tile_validity.resize(tile_len);
+    /* Fast exit. When the transaction was already empty no need to re-init the tile_validity. */
+    if (is_empty()) {
+      return;
+    }
     for (int index = 0; index < tile_len; index++) {
       tile_validity[index] = false;
     }
+    is_empty_ = true;
+  }
+
+  void reset()
+  {
+    init_tiles(tile_x_len_, tile_y_len_);
   }
 
   void add_region(int start_x_tile, int start_y_tile, int end_x_tile, int end_y_tile)
@@ -122,6 +132,28 @@ struct PartialUpdateTransaction {
     }
     is_empty_ = false;
   }
+
+  /** \brief Merge the given transaction into the receiver. */
+  void merge(PartialUpdateTransaction &other)
+  {
+    BLI_assert(tile_x_len_ == other.tile_x_len_);
+    BLI_assert(tile_y_len_ == other.tile_y_len_);
+    const int tile_len = tile_x_len_ * tile_y_len_;
+
+    for (int tile_index = 0; tile_index < tile_len; tile_index++) {
+      tile_validity[tile_index] |= other.tile_validity[tile_index];
+    }
+    if (!other.is_empty()) {
+      is_empty_ = false;
+    }
+  }
+
+  /** \brief has a tile changed inside this transaction. */
+  bool tile_changed(int tile_x, int tile_y)
+  {
+    int tile_index = tile_y * tile_x_len_ + tile_x;
+    return tile_validity[tile_index];
+  }
 };
 
 /** \brief Partial update data that is stored inside the image. */
@@ -138,15 +170,17 @@ struct PartialUpdateRegisterImpl {
   int image_width;
   int image_height;
 
-  void set_resolution(Image *image, ImBuf *image_buffer)
+  void set_resolution(ImBuf *image_buffer)
   {
     if (image_width != image_buffer->x || image_height != image_buffer->y) {
-      mark_full_update();
+      image_width = image_buffer->x;
+      image_height = image_buffer->y;
+
       int tile_x_len = image_width / TILE_SIZE;
       int tile_y_len = image_height / TILE_SIZE;
       current_transaction.init_tiles(tile_x_len, tile_y_len);
-      image_width = image_buffer->x;
-      image_height = image_buffer->y;
+
+      mark_full_update();
     }
   }
 
@@ -154,6 +188,7 @@ struct PartialUpdateRegisterImpl {
   {
     history.clear();
     current_transaction_id++;
+    current_transaction.reset();
     first_transaction_id = current_transaction_id;
   }
 
@@ -200,6 +235,7 @@ struct PartialUpdateRegisterImpl {
   void commit_current_transaction()
   {
     history.append_as(std::move(current_transaction));
+    current_transaction.reset();
     current_transaction_id++;
   }
 
@@ -213,6 +249,21 @@ struct PartialUpdateRegisterImpl {
   {
     return transaction_id >= first_transaction_id;
   }
+
+  std::unique_ptr<PartialUpdateTransaction> changed_tiles_since(
+      const TransactionID from_transaction)
+  {
+    std::unique_ptr<PartialUpdateTransaction> changed_tiles =
+        std::make_unique<PartialUpdateTransaction>();
+    int tile_x_len = image_width / TILE_SIZE;
+    int tile_y_len = image_height / TILE_SIZE;
+    changed_tiles->init_tiles(tile_x_len, tile_y_len);
+
+    for (int index = from_transaction - first_transaction_id; index < history.size(); index++) {
+      changed_tiles->merge(history[index]);
+    }
+    return changed_tiles;
+  }
 };
 
 }  // namespace blender::bke::image::partial_update
@@ -235,17 +286,14 @@ void BKE_image_partial_update_free(PartialUpdateUser *user)
 }
 
 ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(Image *image,
+                                                                   ImBuf *image_buffer,
                                                                    PartialUpdateUser *user)
 {
   PartialUpdateUserImpl *user_impl = unwrap(user);
   user_impl->clear_updated_tiles();
 
   PartialUpdateRegisterImpl *partial_updater = unwrap(
-      BKE_image_partial_update_register_ensure(image));
-
-  if (partial_updater == nullptr) {
-    return PARTIAL_UPDATE_NEED_FULL_UPDATE;
-  }
+      BKE_image_partial_update_register_ensure(image, image_buffer));
   partial_updater->ensure_empty_transaction();
 
   if (!partial_updater->can_construct(user_impl->last_transaction_id)) {
@@ -259,6 +307,22 @@ ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(Image *image,
   }
 
   // TODO: Collect changes between last_transaction_id and current_transaction_id.
+  std::unique_ptr<PartialUpdateTransaction> changed_tiles = partial_updater->changed_tiles_since(
+      user_impl->last_transaction_id);
+  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->tile_changed(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);
+      }
+    }
+  }
+
   // TODO: compress neighboring tiles and store in user.
 
   user_impl->last_transaction_id = partial_updater->current_transaction_id;
@@ -268,7 +332,13 @@ ePartialUpdateCollectResult BKE_image_partial_update_collect_tiles(Image *image,
 ePartialUpdateIterResult BKE_image_partial_update_next_tile(PartialUpdateUser *user,
                                                             PartialUpdateTile *r_tile)
 {
-  return PARTIAL_UPDATE_ITER_NO_TILES_LEFT;
+  PartialUpdateUserImpl *user_impl = unwrap(user);
+  if (user_impl->updated_tiles.is_empty()) {
+    return PARTIAL_UPDATE_ITER_NO_TILES_LEFT;
+  }
+  PartialUpdateTile tile = user_impl->updated_tiles.pop_last();
+  *r_tile = tile;
+  return PARTIAL_UPDATE_ITER_TILE_LOADED;
 }
 
 /* --- Image side --- */
@@ -279,7 +349,7 @@ struct PartialUpdateRegister *BKE_image_partial_update_register_ensure(Image *im
   if (image->runtime.partial_update_register == nullptr) {
     PartialUpdateRegisterImpl *partial_update_register = OBJECT_GUARDED_NEW(
         PartialUpdateRegisterImpl);
-    partial_update_register->set_resolution(image, image_buffer);
+    partial_update_register->set_resolution(image_buffer);
     image->runtime.partial_update_register = wrap(partial_update_register);
   }
   return image->runtime.partial_update_register;
@@ -295,18 +365,19 @@ void BKE_image_partial_update_register_free(Image *image)
   image->runtime.partial_update_register = nullptr;
 }
 
-void BKE_image_partial_update_register_mark_region(struct Image *image, rct

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list