Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/eevee/eevee_data.c
| Show All 36 Lines | |||||
| #include "eevee_lightcache.h" | #include "eevee_lightcache.h" | ||||
| #include "eevee_private.h" | #include "eevee_private.h" | ||||
| /* Motion Blur data. */ | /* Motion Blur data. */ | ||||
| static void eevee_motion_blur_mesh_data_free(void *val) | static void eevee_motion_blur_mesh_data_free(void *val) | ||||
| { | { | ||||
| EEVEE_GeometryMotionData *geom_mb = (EEVEE_GeometryMotionData *)val; | EEVEE_ObjectMotionData *mb_data = (EEVEE_ObjectMotionData *)val; | ||||
| EEVEE_HairMotionData *hair_mb = (EEVEE_HairMotionData *)val; | if (mb_data->hair_data != NULL) { | ||||
| switch (geom_mb->type) { | MEM_freeN(mb_data->hair_data); | ||||
| case EEVEE_MOTION_DATA_HAIR: | |||||
| for (int j = 0; j < hair_mb->psys_len; j++) { | |||||
| for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) { | |||||
| GPU_VERTBUF_DISCARD_SAFE(hair_mb->psys[j].hair_pos[i]); | |||||
| } | } | ||||
| for (int i = 0; i < ARRAY_SIZE(hair_mb->psys[0].hair_pos); i++) { | if (mb_data->geometry_data != NULL) { | ||||
| DRW_TEXTURE_FREE_SAFE(hair_mb->psys[j].hair_pos_tx[i]); | MEM_freeN(mb_data->geometry_data); | ||||
| } | |||||
| } | |||||
| break; | |||||
| case EEVEE_MOTION_DATA_MESH: | |||||
| for (int i = 0; i < ARRAY_SIZE(geom_mb->vbo); i++) { | |||||
| GPU_VERTBUF_DISCARD_SAFE(geom_mb->vbo[i]); | |||||
| } | |||||
| break; | |||||
| } | } | ||||
| MEM_freeN(val); | MEM_freeN(val); | ||||
| } | } | ||||
| static uint eevee_object_key_hash(const void *key) | static uint eevee_object_key_hash(const void *key) | ||||
| { | { | ||||
| EEVEE_ObjectKey *ob_key = (EEVEE_ObjectKey *)key; | EEVEE_ObjectKey *ob_key = (EEVEE_ObjectKey *)key; | ||||
| uint hash = BLI_ghashutil_ptrhash(ob_key->ob); | uint hash = BLI_ghashutil_ptrhash(ob_key->ob); | ||||
| Show All 22 Lines | if (key_a->parent != key_b->parent) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (memcmp(key_a->id, key_b->id, sizeof(key_a->id)) != 0) { | if (memcmp(key_a->id, key_b->id, sizeof(key_a->id)) != 0) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void EEVEE_motion_hair_step_free(EEVEE_HairMotionStepData *step_data) | |||||
| { | |||||
| GPU_vertbuf_discard(step_data->hair_pos); | |||||
| DRW_texture_free(step_data->hair_pos_tx); | |||||
| MEM_freeN(step_data); | |||||
| } | |||||
| void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb) | void EEVEE_motion_blur_data_init(EEVEE_MotionBlurData *mb) | ||||
| { | { | ||||
| if (mb->object == NULL) { | if (mb->object == NULL) { | ||||
| mb->object = BLI_ghash_new(eevee_object_key_hash, eevee_object_key_cmp, "EEVEE Object Motion"); | mb->object = BLI_ghash_new(eevee_object_key_hash, eevee_object_key_cmp, "EEVEE Object Motion"); | ||||
| } | } | ||||
| if (mb->geom == NULL) { | for (int i = 0; i < 2; i++) { | ||||
| mb->geom = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE Mesh Motion"); | if (mb->position_vbo_cache[i] == NULL) { | ||||
| mb->position_vbo_cache[i] = BLI_ghash_new( | |||||
| BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE duplicate vbo cache"); | |||||
| } | |||||
| if (mb->hair_motion_step_cache[i] == NULL) { | |||||
| mb->hair_motion_step_cache[i] = BLI_ghash_new( | |||||
| BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EEVEE hair motion step cache"); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb) | void EEVEE_motion_blur_data_free(EEVEE_MotionBlurData *mb) | ||||
| { | { | ||||
| if (mb->object) { | if (mb->object) { | ||||
| BLI_ghash_free(mb->object, MEM_freeN, MEM_freeN); | BLI_ghash_free(mb->object, MEM_freeN, eevee_motion_blur_mesh_data_free); | ||||
| mb->object = NULL; | mb->object = NULL; | ||||
| } | } | ||||
| if (mb->geom) { | for (int i = 0; i < 2; i++) { | ||||
| BLI_ghash_free(mb->geom, NULL, eevee_motion_blur_mesh_data_free); | if (mb->position_vbo_cache[i]) { | ||||
| mb->geom = NULL; | BLI_ghash_free(mb->position_vbo_cache[i], NULL, (GHashValFreeFP)GPU_vertbuf_discard); | ||||
| } | |||||
| if (mb->hair_motion_step_cache[i]) { | |||||
| BLI_ghash_free( | |||||
| mb->hair_motion_step_cache[i], NULL, (GHashValFreeFP)EEVEE_motion_hair_step_free); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, | EEVEE_ObjectMotionData *EEVEE_motion_blur_object_data_get(EEVEE_MotionBlurData *mb, Object *ob) | ||||
| Object *ob, | |||||
| bool hair) | |||||
| { | { | ||||
| if (mb->object == NULL) { | if (mb->object == NULL) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| EEVEE_ObjectKey key, *key_p; | EEVEE_ObjectKey key, *key_p; | ||||
| /* Small hack to avoid another comparison. */ | /* Assumes that all instances have the same object pointer. This is currently the case because | ||||
| key.ob = (Object *)((char *)ob + hair); | * instance objects are temporary objects on the stack. */ | ||||
| key.ob = ob; | |||||
| DupliObject *dup = DRW_object_get_dupli(ob); | DupliObject *dup = DRW_object_get_dupli(ob); | ||||
| if (dup) { | if (dup) { | ||||
| key.parent = DRW_object_get_dupli_parent(ob); | key.parent = DRW_object_get_dupli_parent(ob); | ||||
| memcpy(key.id, dup->persistent_id, sizeof(key.id)); | memcpy(key.id, dup->persistent_id, sizeof(key.id)); | ||||
| } | } | ||||
| else { | else { | ||||
| key.parent = key.ob; | key.parent = key.ob; | ||||
| memset(key.id, 0, sizeof(key.id)); | memset(key.id, 0, sizeof(key.id)); | ||||
| } | } | ||||
| EEVEE_ObjectMotionData *ob_step = BLI_ghash_lookup(mb->object, &key); | EEVEE_ObjectMotionData *ob_step = BLI_ghash_lookup(mb->object, &key); | ||||
| if (ob_step == NULL) { | if (ob_step == NULL) { | ||||
| key_p = MEM_mallocN(sizeof(*key_p), __func__); | key_p = MEM_mallocN(sizeof(*key_p), __func__); | ||||
| memcpy(key_p, &key, sizeof(*key_p)); | memcpy(key_p, &key, sizeof(*key_p)); | ||||
| ob_step = MEM_callocN(sizeof(EEVEE_ObjectMotionData), __func__); | ob_step = MEM_callocN(sizeof(EEVEE_ObjectMotionData), __func__); | ||||
| BLI_ghash_insert(mb->object, key_p, ob_step); | BLI_ghash_insert(mb->object, key_p, ob_step); | ||||
| } | } | ||||
| return ob_step; | return ob_step; | ||||
| } | } | ||||
| static void *motion_blur_deform_data_get(EEVEE_MotionBlurData *mb, Object *ob, bool hair) | EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_ObjectMotionData *mb_data) | ||||
| { | { | ||||
| if (mb->geom == NULL) { | if (mb_data->geometry_data == NULL) { | ||||
| return NULL; | EEVEE_GeometryMotionData *geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__); | ||||
| } | |||||
| DupliObject *dup = DRW_object_get_dupli(ob); | |||||
| void *key; | |||||
| if (dup) { | |||||
| key = dup->ob; | |||||
| } | |||||
| else { | |||||
| key = ob; | |||||
| } | |||||
| /* Only use data for object that have no modifiers. */ | |||||
| if (!BKE_object_is_modified(DRW_context_state_get()->scene, ob)) { | |||||
| key = ob->data; | |||||
| } | |||||
| key = (char *)key + (int)hair; | |||||
| EEVEE_GeometryMotionData *geom_step = BLI_ghash_lookup(mb->geom, key); | |||||
| if (geom_step == NULL) { | |||||
| if (hair) { | |||||
| EEVEE_HairMotionData *hair_step; | |||||
| /* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */ | |||||
| int psys_len = (ob->type != OB_HAIR) ? BLI_listbase_count(&ob->modifiers) : 1; | |||||
| hair_step = MEM_callocN(sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, | |||||
| __func__); | |||||
| hair_step->psys_len = psys_len; | |||||
| geom_step = (EEVEE_GeometryMotionData *)hair_step; | |||||
| geom_step->type = EEVEE_MOTION_DATA_HAIR; | |||||
| } | |||||
| else { | |||||
| geom_step = MEM_callocN(sizeof(EEVEE_GeometryMotionData), __func__); | |||||
| geom_step->type = EEVEE_MOTION_DATA_MESH; | geom_step->type = EEVEE_MOTION_DATA_MESH; | ||||
| mb_data->geometry_data = geom_step; | |||||
| } | } | ||||
| BLI_ghash_insert(mb->geom, key, geom_step); | return mb_data->geometry_data; | ||||
| } | |||||
| return geom_step; | |||||
| } | } | ||||
| EEVEE_GeometryMotionData *EEVEE_motion_blur_geometry_data_get(EEVEE_MotionBlurData *mb, Object *ob) | EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_ObjectMotionData *mb_data, Object *ob) | ||||
| { | { | ||||
| return motion_blur_deform_data_get(mb, ob, false); | if (mb_data->hair_data == NULL) { | ||||
| /* Ugly, we allocate for each modifiers and just fill based on modifier index in the list. */ | |||||
| int psys_len = (ob->type != OB_HAIR) ? BLI_listbase_count(&ob->modifiers) : 1; | |||||
| EEVEE_HairMotionData *hair_step = MEM_callocN( | |||||
| sizeof(EEVEE_HairMotionData) + sizeof(hair_step->psys[0]) * psys_len, __func__); | |||||
| hair_step->psys_len = psys_len; | |||||
| hair_step->type = EEVEE_MOTION_DATA_HAIR; | |||||
| mb_data->hair_data = hair_step; | |||||
| } | } | ||||
| return mb_data->hair_data; | |||||
| EEVEE_HairMotionData *EEVEE_motion_blur_hair_data_get(EEVEE_MotionBlurData *mb, Object *ob) | |||||
| { | |||||
| return motion_blur_deform_data_get(mb, ob, true); | |||||
| } | } | ||||
| /* View Layer data. */ | /* View Layer data. */ | ||||
| void EEVEE_view_layer_data_free(void *storage) | void EEVEE_view_layer_data_free(void *storage) | ||||
| { | { | ||||
| EEVEE_ViewLayerData *sldata = (EEVEE_ViewLayerData *)storage; | EEVEE_ViewLayerData *sldata = (EEVEE_ViewLayerData *)storage; | ||||
| ▲ Show 20 Lines • Show All 178 Lines • Show Last 20 Lines | |||||