diff options
Diffstat (limited to 'source/blender/draw/engines/eevee_next/eevee_sync.hh')
-rw-r--r-- | source/blender/draw/engines/eevee_next/eevee_sync.hh | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.hh b/source/blender/draw/engines/eevee_next/eevee_sync.hh new file mode 100644 index 00000000000..74b08d0f10a --- /dev/null +++ b/source/blender/draw/engines/eevee_next/eevee_sync.hh @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2021 Blender Foundation. + */ + +/** \file + * \ingroup eevee + * + * Structures to identify unique data blocks. The keys are unique so we are able to + * match ids across frame updates. + */ + +#pragma once + +#include "BKE_duplilist.h" +#include "BLI_ghash.h" +#include "BLI_map.hh" +#include "DNA_object_types.h" +#include "DRW_render.h" +#include "GPU_material.h" + +#include "eevee_shader_shared.hh" + +namespace blender::eevee { + +class Instance; + +/* -------------------------------------------------------------------- */ +/** \name ObjectKey + * + * Unique key to identify each object in the hashmap. + * \{ */ + +struct ObjectKey { + /** Hash value of the key. */ + uint64_t hash_value; + /** Original Object or source object for duplis. */ + Object *ob; + /** Original Parent object for duplis. */ + Object *parent; + /** Dupli objects recursive unique identifier */ + int id[MAX_DUPLI_RECUR]; + /** If object uses particle system hair. */ + bool use_particle_hair; +#ifdef DEBUG + char name[64]; +#endif + ObjectKey() : ob(nullptr), parent(nullptr){}; + + ObjectKey(Object *ob_, Object *parent_, int id_[MAX_DUPLI_RECUR], bool use_particle_hair_) + : ob(ob_), parent(parent_), use_particle_hair(use_particle_hair_) + { + if (id_) { + memcpy(id, id_, sizeof(id)); + } + else { + memset(id, 0, sizeof(id)); + } + /* Compute hash on creation so we avoid the cost of it for every sync. */ + hash_value = BLI_ghashutil_ptrhash(ob); + hash_value = BLI_ghashutil_combine_hash(hash_value, BLI_ghashutil_ptrhash(parent)); + for (int i = 0; i < MAX_DUPLI_RECUR; i++) { + if (id[i] != 0) { + hash_value = BLI_ghashutil_combine_hash(hash_value, BLI_ghashutil_inthash(id[i])); + } + else { + break; + } + } +#ifdef DEBUG + STRNCPY(name, ob->id.name); +#endif + } + + ObjectKey(Object *ob, DupliObject *dupli, Object *parent) + : ObjectKey(ob, parent, dupli ? dupli->persistent_id : nullptr, false){}; + + ObjectKey(Object *ob) + : ObjectKey(ob, DRW_object_get_dupli(ob), DRW_object_get_dupli_parent(ob)){}; + + uint64_t hash(void) const + { + return hash_value; + } + + bool operator<(const ObjectKey &k) const + { + if (ob != k.ob) { + return (ob < k.ob); + } + if (parent != k.parent) { + return (parent < k.parent); + } + if (use_particle_hair != k.use_particle_hair) { + return (use_particle_hair < k.use_particle_hair); + } + return memcmp(id, k.id, sizeof(id)) < 0; + } + + bool operator==(const ObjectKey &k) const + { + if (ob != k.ob) { + return false; + } + if (parent != k.parent) { + return false; + } + if (use_particle_hair != k.use_particle_hair) { + return false; + } + return memcmp(id, k.id, sizeof(id)) == 0; + } +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sync Module + * + * \{ */ + +struct ObjectHandle : public DrawData { + ObjectKey object_key; + + void reset_recalc_flag(void) + { + if (recalc != 0) { + recalc = 0; + } + } +}; + +struct WorldHandle : public DrawData { + void reset_recalc_flag(void) + { + if (recalc != 0) { + recalc = 0; + } + } +}; + +class SyncModule { + private: + Instance &inst_; + + public: + SyncModule(Instance &inst) : inst_(inst){}; + ~SyncModule(){}; + + ObjectHandle &sync_object(Object *ob); + WorldHandle &sync_world(::World *world); + + void sync_mesh(Object *ob, ObjectHandle &ob_handle); + void sync_gpencil(Object *ob, ObjectHandle &ob_handle); + void sync_curves(Object *ob, ObjectHandle &ob_handle, ModifierData *modifier_data); +}; + +/** \} */ + +} // namespace blender::eevee |