1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 20137Blender Foundation.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup depsgraph
22  */
23 
24 #pragma once
25 
26 #include <stddef.h>
27 
28 #include "DNA_ID.h"
29 
30 struct ID;
31 
32 /* Uncomment this to have verbose log about original and CoW pointers
33  * logged, with detailed information when they are allocated, expanded
34  * and remapped.
35  */
36 // #define DEG_DEBUG_COW_POINTERS
37 
38 #ifdef DEG_DEBUG_COW_POINTERS
39 #  define DEG_COW_PRINT(format, ...) printf(format, __VA_ARGS__);
40 #else
41 #  define DEG_COW_PRINT(format, ...)
42 #endif
43 
44 struct Depsgraph;
45 
46 namespace blender {
47 namespace deg {
48 
49 struct Depsgraph;
50 class DepsgraphNodeBuilder;
51 struct IDNode;
52 
53 /* Get fully expanded (ready for use) copy-on-write data-block for the given
54  * original data-block.
55  */
56 ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph,
57                                        const IDNode *id_node,
58                                        DepsgraphNodeBuilder *node_builder = nullptr,
59                                        bool create_placeholders = false);
60 ID *deg_expand_copy_on_write_datablock(const struct Depsgraph *depsgraph,
61                                        struct ID *id_orig,
62                                        DepsgraphNodeBuilder *node_builder = nullptr,
63                                        bool create_placeholders = false);
64 
65 /* Makes sure given CoW data-block is brought back to state of the original
66  * data-block.
67  */
68 ID *deg_update_copy_on_write_datablock(const struct Depsgraph *depsgraph, const IDNode *id_node);
69 ID *deg_update_copy_on_write_datablock(const struct Depsgraph *depsgraph, struct ID *id_orig);
70 
71 /* Helper function which frees memory used by copy-on-written databnlock. */
72 void deg_free_copy_on_write_datablock(struct ID *id_cow);
73 
74 /* Callback function for depsgraph operation node which ensures copy-on-write
75  * datablock is ready for use by further evaluation routines.
76  */
77 void deg_evaluate_copy_on_write(struct ::Depsgraph *depsgraph, const struct IDNode *id_node);
78 
79 /* Check that given ID is properly expanded and does not have any shallow
80  * copies inside. */
81 bool deg_validate_copy_on_write_datablock(ID *id_cow);
82 
83 /* Tag given ID block as being copy-on-wtritten. */
84 void deg_tag_copy_on_write_id(struct ID *id_cow, const struct ID *id_orig);
85 
86 /* Check whether ID datablock is expanded.
87  *
88  * TODO(sergey): Make it an inline function or a macro.
89  */
90 bool deg_copy_on_write_is_expanded(const struct ID *id_cow);
91 
92 /* Check whether copy-on-write datablock is needed for given ID.
93  *
94  * There are some exceptions on data-blocks which are covered by dependency graph
95  * but which we don't want to start duplicating.
96  *
97  * This includes images.
98  */
99 bool deg_copy_on_write_is_needed(const ID *id_orig);
100 bool deg_copy_on_write_is_needed(const ID_Type id_type);
101 
102 }  // namespace deg
103 }  // namespace blender
104