Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFalk David <falkdavid@gmx.de>2022-02-10 13:34:12 +0300
committerFalk David <falkdavid@gmx.de>2022-02-10 13:35:56 +0300
commite2befa425a84c9e4ec715442e85624a5d3669a4f (patch)
tree0965c6eb7d30eceeab8300288197f4e77b10a097 /source/blender/depsgraph/intern
parent84f30ac3a2e8b3017ef7dda34643e573a1f476b7 (diff)
GPencil: Update-on-write using update cache
This implements the update cache described in T95401. The cache is currently only used for drawing strokes and sculpting (using the push brush). **Note: Making use of the cache throughout grease pencil will have to be done incrementally in other patches. ** The update cache stores what elements have changed in the original data-block since the last time the eval object was updated. Additionally, the update cache can store multiple updates to the data and minimizes the number of elements that need to be copied. Elements can be tagged using `BKE_gpencil_tag_full_update` and `BKE_gpencil_tag_light_update`. A full update means that the element itself will be copied but also all of the content inside. E.g. when a layer is tagged for a full update, the layer, all the frames inside the layer and all the strokes inside the frames will be copied. A light update means that only the properties of the element are copied without any of the content. E.g. if a layer is tagged with a light update, it will copy the layer name, opacity, transform, etc. When the update cache is in use (e.g. elements have been tagged) then the depsgraph will not trigger a copy-on-write, but an update-on-write. This means that the update cache will be used to determine what elements have changed and then only those elements will be copied over to the eval object. If the update cache is empty or the data block was tagged with a full update, we always fall back to a copy-on-write. Currently, the update cache is only used by the active depsgraph. This is because we need to free the update cache after an update-on-write so it's reset and we need to make sure it is not freed or read by other depsgraphs. Co-authored-by: @yann-lty This patch was contributed by The SPA Studios. Reviewed By: sergey, antoniov, #dependency_graph, pepeland, mendio Maniphest Tasks: T95401 Differential Revision: https://developer.blender.org/D13984
Diffstat (limited to 'source/blender/depsgraph/intern')
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc11
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc7
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc59
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h45
5 files changed, 120 insertions, 4 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index b64f94568f6..48166567354 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -43,6 +43,7 @@
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_gpencil.h"
+#include "BKE_gpencil_update_cache.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
@@ -737,9 +738,6 @@ void update_id_after_copy(const Depsgraph *depsgraph,
}
BKE_pose_pchan_index_rebuild(object_cow->pose);
}
- if (object_cow->type == OB_GPENCIL) {
- BKE_gpencil_update_orig_pointers(object_orig, object_cow);
- }
update_particles_after_copy(depsgraph, object_orig, object_cow);
break;
}
@@ -892,6 +890,13 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode
update_edit_mode_pointers(depsgraph, id_orig, id_cow);
return id_cow;
}
+ /* In case we don't need to do a copy-on-write, we can use the update cache of the grease
+ * pencil data to do an update-on-write.*/
+ if (id_type == ID_GD && BKE_gpencil_can_avoid_full_copy_on_write(
+ (const ::Depsgraph *)depsgraph, (bGPdata *)id_orig)) {
+ BKE_gpencil_update_on_write((bGPdata *)id_orig, (bGPdata *)id_cow);
+ return id_cow;
+ }
}
RuntimeBackup backup(depsgraph);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
index 8bf64af7d5d..85ac8b509c2 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.cc
@@ -40,7 +40,8 @@ RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
object_backup(depsgraph),
drawdata_ptr(nullptr),
movieclip_backup(depsgraph),
- volume_backup(depsgraph)
+ volume_backup(depsgraph),
+ gpencil_backup(depsgraph)
{
drawdata_backup.first = drawdata_backup.last = nullptr;
}
@@ -75,6 +76,8 @@ void RuntimeBackup::init_from_id(ID *id)
case ID_VO:
volume_backup.init_from_volume(reinterpret_cast<Volume *>(id));
break;
+ case ID_GD:
+ gpencil_backup.init_from_gpencil(reinterpret_cast<bGPdata *>(id));
default:
break;
}
@@ -115,6 +118,8 @@ void RuntimeBackup::restore_to_id(ID *id)
case ID_VO:
volume_backup.restore_to_volume(reinterpret_cast<Volume *>(id));
break;
+ case ID_GD:
+ gpencil_backup.restore_to_gpencil(reinterpret_cast<bGPdata *>(id));
default:
break;
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
index 0629dbe62b4..c4f6bd954c0 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup.h
@@ -31,6 +31,7 @@
#include "intern/eval/deg_eval_runtime_backup_scene.h"
#include "intern/eval/deg_eval_runtime_backup_sound.h"
#include "intern/eval/deg_eval_runtime_backup_volume.h"
+#include "intern/eval/deg_eval_runtime_backup_gpencil.h"
namespace blender {
namespace deg {
@@ -71,6 +72,7 @@ class RuntimeBackup {
DrawDataList *drawdata_ptr;
MovieClipBackup movieclip_backup;
VolumeBackup volume_backup;
+ GPencilBackup gpencil_backup;
};
} // namespace deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc
new file mode 100644
index 00000000000..63d1eb9f711
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc
@@ -0,0 +1,59 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2022 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#include "intern/eval/deg_eval_runtime_backup_gpencil.h"
+#include "intern/depsgraph.h"
+
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_update_cache.h"
+
+#include "DNA_gpencil_types.h"
+
+namespace blender::deg {
+
+GPencilBackup::GPencilBackup(const Depsgraph *depsgraph) : depsgraph(depsgraph)
+{
+}
+
+void GPencilBackup::init_from_gpencil(bGPdata *UNUSED(gpd))
+{
+}
+
+void GPencilBackup::restore_to_gpencil(bGPdata *gpd)
+{
+ bGPdata *gpd_orig = reinterpret_cast<bGPdata *>(gpd->id.orig_id);
+
+ /* We check for the active depsgraph here to avoid freeing the cache on the original object
+ * multiple times. This free is only needed for the case where we tagged a full update in the
+ * update cache and did not do an update-on-write. */
+ if (depsgraph->is_active) {
+ BKE_gpencil_free_update_cache(gpd_orig);
+ }
+ /* Doing a copy-on-write copies the update cache pointer. Make sure to reset it
+ * to NULL as we should never use the update cache from eval data. */
+ gpd->runtime.update_cache = NULL;
+ /* Make sure to update the original runtime pointers in the eval data. */
+ BKE_gpencil_data_update_orig_pointers(gpd_orig, gpd);
+}
+
+} // namespace blender::deg
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h
new file mode 100644
index 00000000000..baf0f6a6945
--- /dev/null
+++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.h
@@ -0,0 +1,45 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2022 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+struct bGPdata;
+
+namespace blender {
+namespace deg {
+
+struct Depsgraph;
+
+/* Backup of volume datablocks runtime data. */
+class GPencilBackup {
+ public:
+ GPencilBackup(const Depsgraph *depsgraph);
+
+ void init_from_gpencil(bGPdata *gpd);
+ void restore_to_gpencil(bGPdata *gpd);
+
+ const Depsgraph* depsgraph;
+};
+
+} // namespace deg
+} // namespace blender