diff options
Diffstat (limited to 'source/blender/blenkernel/intern/movieclip.c')
-rw-r--r-- | source/blender/blenkernel/intern/movieclip.c | 125 |
1 files changed, 112 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index fe7c2055aef..5b4dbc66cc2 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -129,6 +129,23 @@ static void movie_clip_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void movie_clip_foreach_cache(ID *id, + IDTypeForeachCacheFunctionCallback function_callback, + void *user_data) +{ + MovieClip *movie_clip = (MovieClip *)id; + IDCacheKey key = { + .id_session_uuid = id->session_uuid, + .offset_in_ID = offsetof(MovieClip, cache), + .cache_v = movie_clip->cache, + }; + function_callback(id, &key, (void **)&movie_clip->cache, 0, user_data); + + key.offset_in_ID = offsetof(MovieClip, tracking.camera.intrinsics); + key.cache_v = movie_clip->tracking.camera.intrinsics; + function_callback(id, &key, (void **)&movie_clip->tracking.camera.intrinsics, 0, user_data); +} + IDTypeInfo IDType_ID_MC = { .id_code = ID_MC, .id_filter = FILTER_ID_MC, @@ -144,6 +161,7 @@ IDTypeInfo IDType_ID_MC = { .free_data = movie_clip_free_data, .make_local = NULL, .foreach_id = movie_clip_foreach_id, + .foreach_cache = movie_clip_foreach_cache, }; /*********************** movieclip buffer loaders *************************/ @@ -220,19 +238,19 @@ static void get_sequence_fname(const MovieClip *clip, const int framenr, char *n char head[FILE_MAX], tail[FILE_MAX]; int offset; - BLI_strncpy(name, clip->name, sizeof(clip->name)); + BLI_strncpy(name, clip->filepath, sizeof(clip->filepath)); BLI_path_sequence_decode(name, head, tail, &numlen); /* Movie-clips always points to first image from sequence, auto-guess offset for now. * Could be something smarter in the future. */ - offset = sequence_guess_offset(clip->name, strlen(head), numlen); + offset = sequence_guess_offset(clip->filepath, strlen(head), numlen); if (numlen) { BLI_path_sequence_encode( name, head, tail, numlen, offset + framenr - clip->start_frame + clip->frame_offset); } else { - BLI_strncpy(name, clip->name, sizeof(clip->name)); + BLI_strncpy(name, clip->filepath, sizeof(clip->filepath)); } BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id)); @@ -246,7 +264,7 @@ static void get_proxy_fname( char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX]; int proxynr = framenr - clip->start_frame + 1 + clip->frame_offset; - BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); + BLI_split_dirfile(clip->filepath, clipdir, clipfile, FILE_MAX, FILE_MAX); if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) { BLI_strncpy(dir, clip->proxy.dir, sizeof(dir)); @@ -395,7 +413,7 @@ static void movieclip_open_anim_file(MovieClip *clip) char str[FILE_MAX]; if (!clip->anim) { - BLI_strncpy(str, clip->name, FILE_MAX); + BLI_strncpy(str, clip->filepath, FILE_MAX); BLI_path_abs(str, ID_BLEND_PATH_FROM_GLOBAL(&clip->id)); /* FIXME: make several stream accessible in image editor, too */ @@ -445,7 +463,7 @@ static void movieclip_calc_length(MovieClip *clip) unsigned short numlen; char name[FILE_MAX], head[FILE_MAX], tail[FILE_MAX]; - BLI_path_sequence_decode(clip->name, head, tail, &numlen); + BLI_path_sequence_decode(clip->filepath, head, tail, &numlen); if (numlen == 0) { /* there's no number group in file name, assume it's single framed sequence */ @@ -531,10 +549,10 @@ static int user_frame_to_cache_frame(MovieClip *clip, int framenr) unsigned short numlen; char head[FILE_MAX], tail[FILE_MAX]; - BLI_path_sequence_decode(clip->name, head, tail, &numlen); + BLI_path_sequence_decode(clip->filepath, head, tail, &numlen); /* see comment in get_sequence_fname */ - clip->cache->sequence_offset = sequence_guess_offset(clip->name, strlen(head), numlen); + clip->cache->sequence_offset = sequence_guess_offset(clip->filepath, strlen(head), numlen); } index += clip->cache->sequence_offset; @@ -674,7 +692,7 @@ static bool put_imbuf_cache( clip->cache->sequence_offset = -1; if (clip->source == MCLIP_SRC_SEQUENCE) { unsigned short numlen; - BLI_path_sequence_decode(clip->name, NULL, NULL, &numlen); + BLI_path_sequence_decode(clip->filepath, NULL, NULL, &numlen); clip->cache->is_still_sequence = (numlen == 0); } } @@ -758,7 +776,7 @@ static void detect_clip_source(Main *bmain, MovieClip *clip) ImBuf *ibuf; char name[FILE_MAX]; - BLI_strncpy(name, clip->name, sizeof(name)); + BLI_strncpy(name, clip->filepath, sizeof(name)); BLI_path_abs(name, BKE_main_blendfile_path(bmain)); ibuf = IMB_testiffname(name, IB_rect | IB_multilayer); @@ -795,7 +813,7 @@ MovieClip *BKE_movieclip_file_add(Main *bmain, const char *name) /* create a short library name */ clip = movieclip_alloc(bmain, BLI_path_basename(name)); - BLI_strncpy(clip->name, name, sizeof(clip->name)); + BLI_strncpy(clip->filepath, name, sizeof(clip->filepath)); detect_clip_source(bmain, clip); @@ -821,7 +839,7 @@ MovieClip *BKE_movieclip_file_add_exists_ex(Main *bmain, const char *filepath, b /* first search an identical filepath */ for (clip = bmain->movieclips.first; clip; clip = clip->id.next) { - BLI_strncpy(strtest, clip->name, sizeof(clip->name)); + BLI_strncpy(strtest, clip->filepath, sizeof(clip->filepath)); BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &clip->id)); if (BLI_path_cmp(strtest, str) == 0) { @@ -1739,7 +1757,7 @@ void BKE_movieclip_filename_for_frame(MovieClip *clip, MovieClipUser *user, char } } else { - BLI_strncpy(name, clip->name, FILE_MAX); + BLI_strncpy(name, clip->filepath, FILE_MAX); BLI_path_abs(name, ID_BLEND_PATH_FROM_GLOBAL(&clip->id)); } } @@ -1848,3 +1866,84 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip); movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id); } + +/* -------------------------------------------------------------------- */ +/** \name GPU textures + * \{ */ + +static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip, + MovieClipUser *cuser, + eGPUTextureTarget textarget) +{ + LISTBASE_FOREACH (MovieClip_RuntimeGPUTexture *, tex, &clip->runtime.gputextures) { + if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) { + if (tex == NULL) { + tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), + __func__); + + for (int i = 0; i < TEXTARGET_COUNT; i++) { + tex->gputexture[i] = NULL; + } + + memcpy(&tex->user, cuser, sizeof(MovieClipUser)); + BLI_addtail(&clip->runtime.gputextures, tex); + } + + return &tex->gputexture[textarget]; + } + } + return NULL; +} + +GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser) +{ + if (clip == NULL) { + return NULL; + } + + GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D); + if (*tex) { + return *tex; + } + + /* check if we have a valid image buffer */ + ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser); + if (ibuf == NULL) { + *tex = GPU_texture_create_error(2, false); + return *tex; + } + + /* This only means RGBA16F instead of RGBA32F. */ + const bool high_bitdepth = false; + const bool store_premultiplied = ibuf->rect_float ? false : true; + *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied); + + /* Do not generate mips for movieclips... too slow. */ + GPU_texture_mipmap_mode(*tex, false, true); + + IMB_freeImBuf(ibuf); + + return *tex; +} + +void BKE_movieclip_free_gputexture(struct MovieClip *clip) +{ + /* number of gpu textures to keep around as cache + * We don't want to keep too many GPU textures for + * movie clips around, as they can be large.*/ + const int MOVIECLIP_NUM_GPUTEXTURES = 1; + + while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) { + MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead( + &clip->runtime.gputextures); + for (int i = 0; i < TEXTARGET_COUNT; i++) { + /* free glsl image binding */ + if (tex->gputexture[i]) { + GPU_texture_free(tex->gputexture[i]); + tex->gputexture[i] = NULL; + } + } + MEM_freeN(tex); + } +} +/** \} */
\ No newline at end of file |