diff options
author | Falk David <falkdavid@gmx.de> | 2022-02-10 13:34:12 +0300 |
---|---|---|
committer | Falk David <falkdavid@gmx.de> | 2022-02-10 13:35:56 +0300 |
commit | e2befa425a84c9e4ec715442e85624a5d3669a4f (patch) | |
tree | 0965c6eb7d30eceeab8300288197f4e77b10a097 /source/blender/depsgraph | |
parent | 84f30ac3a2e8b3017ef7dda34643e573a1f476b7 (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')
6 files changed, 122 insertions, 4 deletions
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 41253117096..91c7fac68de 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC intern/eval/deg_eval_flush.cc intern/eval/deg_eval_runtime_backup.cc intern/eval/deg_eval_runtime_backup_animation.cc + intern/eval/deg_eval_runtime_backup_gpencil.cc intern/eval/deg_eval_runtime_backup_modifier.cc intern/eval/deg_eval_runtime_backup_movieclip.cc intern/eval/deg_eval_runtime_backup_object.cc @@ -131,6 +132,7 @@ set(SRC intern/eval/deg_eval_flush.h intern/eval/deg_eval_runtime_backup.h intern/eval/deg_eval_runtime_backup_animation.h + intern/eval/deg_eval_runtime_backup_gpencil.h intern/eval/deg_eval_runtime_backup_modifier.h intern/eval/deg_eval_runtime_backup_movieclip.h intern/eval/deg_eval_runtime_backup_object.h 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 |