forked from bartvdbraak/blender
Clip editor prefetch changes
Made it an operator instead of automatic prefetching. Filling the whole memory with frames is not always desired behavior. Now prefetching is available via P-key, or from Clip panel in toolbox or from Clip menu. Also enabled prefetching for non-proxied movies.
This commit is contained in:
parent
ef1af9f9c4
commit
845aea6864
@ -886,6 +886,7 @@ class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
|
||||
|
||||
layout.operator("clip.set_viewport_background")
|
||||
layout.operator("clip.setup_tracking_scene")
|
||||
layout.operator("clip.prefetch")
|
||||
|
||||
|
||||
class CLIP_MT_view(Menu):
|
||||
@ -945,6 +946,7 @@ class CLIP_MT_clip(Menu):
|
||||
layout.operator("clip.open")
|
||||
|
||||
if clip:
|
||||
layout.operator("clip.prefetch")
|
||||
layout.operator("clip.reload")
|
||||
layout.menu("CLIP_MT_proxy")
|
||||
|
||||
|
@ -1168,7 +1168,6 @@ void BKE_movieclip_reload(MovieClip *clip)
|
||||
free_buffers(clip);
|
||||
|
||||
clip->tracking.stabilization.ok = FALSE;
|
||||
clip->prefetch_ok = FALSE;
|
||||
|
||||
/* update clip source */
|
||||
detect_clip_source(clip);
|
||||
|
@ -6588,8 +6588,6 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
|
||||
clip->tracking.dopesheet.channels.first = clip->tracking.dopesheet.channels.last = NULL;
|
||||
clip->tracking.dopesheet.coverage_segments.first = clip->tracking.dopesheet.coverage_segments.last = NULL;
|
||||
|
||||
clip->prefetch_ok = FALSE;
|
||||
|
||||
link_list(fd, &tracking->objects);
|
||||
|
||||
for (object = tracking->objects.first; object; object = object->next) {
|
||||
|
@ -1456,8 +1456,6 @@ void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
|
||||
if (ibuf) {
|
||||
draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
|
||||
IMB_freeImBuf(ibuf);
|
||||
|
||||
clip_start_prefetch_job(C);
|
||||
}
|
||||
else {
|
||||
ED_region_grid_draw(ar, zoomx, zoomy);
|
||||
|
@ -605,26 +605,9 @@ typedef struct PrefetchThread {
|
||||
} PrefetchThread;
|
||||
|
||||
/* check whether pre-fetching is allowed */
|
||||
static bool check_prefetch_allowed(void)
|
||||
static bool check_prefetch_break(void)
|
||||
{
|
||||
wmWindowManager *wm;
|
||||
|
||||
/* if there's any job started, better to leave all CPU and
|
||||
* HDD bandwidth to it
|
||||
*
|
||||
* also, display transform could be needed during playback,
|
||||
* so better to avoid prefetching in this case and reserve
|
||||
* all the power for display transform
|
||||
*/
|
||||
for (wm = G.main->wm.first; wm; wm = wm->id.next) {
|
||||
if (WM_jobs_has_running_except(wm, WM_JOB_TYPE_CLIP_PREFETCH))
|
||||
return false;
|
||||
|
||||
if (ED_screen_animation_playing(wm))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return G.is_break;
|
||||
}
|
||||
|
||||
/* read file for specified frame number to the memory */
|
||||
@ -706,7 +689,7 @@ static unsigned char *prefetch_thread_next_frame(PrefetchQueue *queue, MovieClip
|
||||
unsigned char *mem = NULL;
|
||||
|
||||
BLI_spin_lock(&queue->spin);
|
||||
if (!*queue->stop && check_prefetch_allowed() &&
|
||||
if (!*queue->stop && !check_prefetch_break() &&
|
||||
IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame))
|
||||
{
|
||||
int current_frame;
|
||||
@ -848,7 +831,7 @@ static bool prefetch_movie_frame(MovieClip *clip, int frame, short render_size,
|
||||
MovieClipUser user = {0};
|
||||
ImBuf *ibuf;
|
||||
|
||||
if (!check_prefetch_allowed() || *stop)
|
||||
if (check_prefetch_break() || *stop)
|
||||
return false;
|
||||
|
||||
user.framenr = frame;
|
||||
@ -968,26 +951,6 @@ static bool prefetch_check_early_out(const bContext *C)
|
||||
int first_uncached_frame, end_frame;
|
||||
int clip_len;
|
||||
|
||||
if (clip->prefetch_ok)
|
||||
return true;
|
||||
|
||||
if (clip->source == MCLIP_SRC_MOVIE) {
|
||||
/* for movies we only prefetch undistorted proxy,
|
||||
* in other cases prefetching could lead to issues
|
||||
* due to timecodes issues.
|
||||
*/
|
||||
|
||||
if (clip->flag & MCLIP_USE_PROXY) {
|
||||
MovieClipUser *user = &sc->user;
|
||||
|
||||
if ((user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) == 0)
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
clip_len = BKE_movieclip_get_duration(clip);
|
||||
|
||||
/* check whether all the frames from prefetch range are cached */
|
||||
@ -1016,7 +979,6 @@ void clip_start_prefetch_job(const bContext *C)
|
||||
wmJob *wm_job;
|
||||
PrefetchJob *pj;
|
||||
SpaceClip *sc = CTX_wm_space_clip(C);
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
|
||||
if (prefetch_check_early_out(C))
|
||||
return;
|
||||
@ -1024,17 +986,6 @@ void clip_start_prefetch_job(const bContext *C)
|
||||
wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_area(C), "Prefetching",
|
||||
WM_JOB_PROGRESS, WM_JOB_TYPE_CLIP_PREFETCH);
|
||||
|
||||
if (WM_jobs_is_running(wm_job)) {
|
||||
/* if job is already running, it'll call clip editor redraw when
|
||||
* it's finished, so cache line is nicely updated
|
||||
* this will also trigger call of this function, which will ensure
|
||||
* all needed frames are prefetched
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
clip->prefetch_ok = true;
|
||||
|
||||
/* create new job */
|
||||
pj = MEM_callocN(sizeof(PrefetchJob), "prefetch job");
|
||||
pj->clip = ED_space_clip_get_clip(sc);
|
||||
@ -1045,9 +996,11 @@ void clip_start_prefetch_job(const bContext *C)
|
||||
pj->render_flag = sc->user.render_flag;
|
||||
|
||||
WM_jobs_customdata_set(wm_job, pj, prefetch_freejob);
|
||||
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP, 0);
|
||||
WM_jobs_timer(wm_job, 0.2, NC_MOVIECLIP | ND_DISPLAY, 0);
|
||||
WM_jobs_callbacks(wm_job, prefetch_startjob, NULL, NULL, NULL);
|
||||
|
||||
G.is_break = FALSE;
|
||||
|
||||
/* and finally start the job */
|
||||
WM_jobs_start(CTX_wm_manager(C), wm_job);
|
||||
}
|
||||
|
@ -108,6 +108,8 @@ void CLIP_OT_mode_set(struct wmOperatorType *ot);
|
||||
|
||||
void CLIP_OT_view_ndof(struct wmOperatorType *ot);
|
||||
|
||||
void CLIP_OT_prefetch(struct wmOperatorType *ot);
|
||||
|
||||
/* clip_toolbar.c */
|
||||
struct ARegion *ED_clip_has_properties_region(struct ScrArea *sa);
|
||||
void CLIP_OT_tools(struct wmOperatorType *ot);
|
||||
|
@ -1378,6 +1378,47 @@ void CLIP_OT_view_ndof(wmOperatorType *ot)
|
||||
ot->invoke = clip_view_ndof_invoke;
|
||||
}
|
||||
|
||||
/********************** Prefetch operator *********************/
|
||||
|
||||
static int clip_prefetch_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
||||
{
|
||||
/* no running blender, remove handler and pass through */
|
||||
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_CLIP_PREFETCH))
|
||||
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
||||
|
||||
/* running render */
|
||||
switch (event->type) {
|
||||
case ESCKEY:
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
static int clip_prefetch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
|
||||
{
|
||||
clip_start_prefetch_job(C);
|
||||
|
||||
/* add modal handler for ESC */
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
void CLIP_OT_prefetch(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Prefetch Frames";
|
||||
ot->idname = "CLIP_OT_prefetch";
|
||||
ot->description = "Prefetch frames from disk for faster playback/tracking";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = ED_space_clip_view_clip_poll;
|
||||
ot->invoke = clip_prefetch_invoke;
|
||||
ot->modal = clip_prefetch_modal;
|
||||
}
|
||||
|
||||
/********************** macroses *********************/
|
||||
|
||||
void ED_operatormacros_clip(void)
|
||||
|
@ -236,16 +236,6 @@ static void clip_stabilization_tag_refresh(ScrArea *sa)
|
||||
}
|
||||
}
|
||||
|
||||
static void clip_prefetch_tag_refresh(ScrArea *sa)
|
||||
{
|
||||
SpaceClip *sc = (SpaceClip *) sa->spacedata.first;
|
||||
MovieClip *clip = ED_space_clip_get_clip(sc);
|
||||
|
||||
if (clip) {
|
||||
clip->prefetch_ok = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* ******************** default callbacks for clip space ***************** */
|
||||
|
||||
static SpaceLink *clip_new(const bContext *C)
|
||||
@ -358,7 +348,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
switch (wmn->data) {
|
||||
case ND_FRAME:
|
||||
clip_scopes_tag_refresh(sa);
|
||||
clip_prefetch_tag_refresh(sa);
|
||||
/* no break! */
|
||||
|
||||
case ND_FRAME_RANGE:
|
||||
@ -367,19 +356,11 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
}
|
||||
break;
|
||||
case NC_MOVIECLIP:
|
||||
if (wmn->data == 0 && wmn->action == 0) {
|
||||
/* a nit funky, happens from prefetch job to update
|
||||
* cache line and job progress
|
||||
*/
|
||||
ED_area_tag_redraw(sa);
|
||||
}
|
||||
|
||||
switch (wmn->data) {
|
||||
case ND_DISPLAY:
|
||||
case ND_SELECT:
|
||||
clip_scopes_tag_refresh(sa);
|
||||
ED_area_tag_redraw(sa);
|
||||
clip_prefetch_tag_refresh(sa);
|
||||
break;
|
||||
}
|
||||
switch (wmn->action) {
|
||||
@ -423,7 +404,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
case NC_SCREEN:
|
||||
switch (wmn->data) {
|
||||
case ND_ANIMPLAY:
|
||||
clip_prefetch_tag_refresh(sa);
|
||||
ED_area_tag_redraw(sa);
|
||||
break;
|
||||
}
|
||||
@ -432,7 +412,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
if (wmn->data == ND_SPACE_CLIP) {
|
||||
clip_scopes_tag_refresh(sa);
|
||||
clip_stabilization_tag_refresh(sa);
|
||||
clip_prefetch_tag_refresh(sa);
|
||||
ED_area_tag_redraw(sa);
|
||||
}
|
||||
break;
|
||||
@ -442,10 +421,6 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
|
||||
ED_area_tag_redraw(sa);
|
||||
}
|
||||
break;
|
||||
case NC_WM:
|
||||
if (wmn->data == ND_FILEREAD)
|
||||
clip_prefetch_tag_refresh(sa);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,6 +440,7 @@ static void clip_operatortypes(void)
|
||||
WM_operatortype_append(CLIP_OT_rebuild_proxy);
|
||||
WM_operatortype_append(CLIP_OT_mode_set);
|
||||
WM_operatortype_append(CLIP_OT_view_ndof);
|
||||
WM_operatortype_append(CLIP_OT_prefetch);
|
||||
|
||||
/* ** clip_toolbar.c ** */
|
||||
WM_operatortype_append(CLIP_OT_tools);
|
||||
@ -598,6 +574,9 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
|
||||
kmi = WM_keymap_add_item(keymap, "CLIP_OT_set_solver_keyframe", EKEY, KM_PRESS, 0, 0);
|
||||
RNA_enum_set(kmi->ptr, "keyframe", 1);
|
||||
|
||||
/* io/playback */
|
||||
WM_keymap_add_item(keymap, "CLIP_OT_prefetch", PKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* ******** Hotkeys avalaible for main region only ******** */
|
||||
|
||||
keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
|
||||
|
@ -98,11 +98,6 @@ typedef struct MovieClip {
|
||||
|
||||
/* color management */
|
||||
ColorManagedColorspaceSettings colorspace_settings;
|
||||
|
||||
/* runtime prefetching stuff */
|
||||
char prefetch_ok;
|
||||
|
||||
char pad[7];
|
||||
} MovieClip;
|
||||
|
||||
typedef struct MovieClipScopes {
|
||||
|
Loading…
Reference in New Issue
Block a user