From b482b8543eb10102c6c09756e08977a3b69ff633 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 12 Feb 2010 00:44:26 +0000 Subject: Bugfix #21051: Restored 'Playback FPS' This commit restores the 'Playback FPS' option which showed an indicator of the frame rate of animation playback in the 3D-View. The info for this is now stored in a temp struct in scene data, with the status info being updated by the "animation step" operator instead of relying on globals as the old code did. This seems a lot more stable than in 2.49, but the accuracy is still questionable. --- source/blender/blenkernel/intern/scene.c | 3 ++ source/blender/blenloader/intern/readfile.c | 1 + source/blender/editors/include/ED_screen.h | 2 + source/blender/editors/include/ED_screen_types.h | 17 +++++++ source/blender/editors/screen/screen_edit.c | 26 ++++++++++ source/blender/editors/screen/screen_ops.c | 9 +++- source/blender/editors/space_view3d/space_view3d.c | 2 + source/blender/editors/space_view3d/view3d_draw.c | 59 +++++++++++++++++++++- source/blender/makesdna/DNA_scene_types.h | 2 + 9 files changed, 117 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 4624fbe40dc..68dded077b5 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -159,6 +159,7 @@ Scene *copy_scene(Main *bmain, Scene *sce, int type) scen->obedit= NULL; scen->toolsettings= MEM_dupallocN(sce->toolsettings); scen->stats= NULL; + scen->fps_info= NULL; ts= scen->toolsettings; if(ts) { @@ -318,6 +319,8 @@ void free_scene(Scene *sce) if(sce->stats) MEM_freeN(sce->stats); + if(sce->fps_info) + MEM_freeN(sce->fps_info); sound_destroy_scene(sce); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 175851266ed..ecddb6280b3 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4216,6 +4216,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->dagisvalid = 0; sce->obedit= NULL; sce->stats= 0; + sce->fps_info= NULL; sound_create_scene(sce); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 89f032efc21..c88985a7861 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -107,7 +107,9 @@ void ED_screen_new_window(struct bContext *C, struct rcti *position, int type); /* anim */ void ED_update_for_newframe(const struct bContext *C, int mute); +void ED_refresh_viewport_fps(struct bContext *C); +/* screen keymaps */ void ED_operatortypes_screen(void); void ED_keymap_screen(struct wmKeyConfig *keyconf); diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 0deda5a2a84..3ce3ac7a5f2 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -29,6 +29,8 @@ #ifndef ED_SCREEN_TYPES_H__ #define ED_SCREEN_TYPES_H__ +/* ----------------------------------------------------- */ + /* for animplayer */ typedef struct ScreenAnimData { ARegion *ar; /* do not read from this, only for comparing if region exists */ @@ -49,6 +51,21 @@ enum { ANIMPLAY_FLAG_NO_SYNC = (1<<3), }; +/* ----------------------------------------------------- */ + +#define REDRAW_FRAME_AVERAGE 8 + +/* for playback framerate info + * stored during runtime as scene->fps_info + */ +typedef struct ScreenFrameRateInfo { + double redrawtime; + double lredrawtime; + float redrawtimes_fps[REDRAW_FRAME_AVERAGE]; + short redrawtime_index; +} ScreenFrameRateInfo; + +/* ----------------------------------------------------- */ /* for editing areas/regions */ typedef struct AZone { diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 048ade764d5..5c987f8d6d0 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1614,6 +1614,32 @@ void ED_screen_full_restore(bContext *C, ScrArea *sa) } } +/* update frame rate info for viewport drawing */ +void ED_refresh_viewport_fps(bContext *C) +{ + wmTimer *animtimer= CTX_wm_screen(C)->animtimer; + Scene *scene= CTX_data_scene(C); + + /* is anim playback running? */ + if (animtimer && (U.uiflag & USER_SHOW_FPS)) { + ScreenFrameRateInfo *fpsi= scene->fps_info; + + /* if there isn't any info, init it first */ + if (fpsi == NULL) + fpsi= scene->fps_info= MEM_callocN(sizeof(ScreenFrameRateInfo), "refresh_viewport_fps fps_info"); + + /* update the values */ + fpsi->redrawtime= fpsi->lredrawtime; + fpsi->lredrawtime= animtimer->ltime; + } + else { + /* playback stopped or shouldn't be running */ + if (scene->fps_info) + MEM_freeN(scene->fps_info); + scene->fps_info= NULL; + } +} + /* redraws: uses defines from stime->redraws * enable: 1 - forward on, -1 - backwards on, 0 - off */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 7f63fc11e64..13709935141 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2481,9 +2481,8 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) if(sad->flag & ANIMPLAY_FLAG_JUMPED) sound_seek_scene(C); - + /* since we follow drawflags, we can't send notifier but tag regions ourselves */ - ED_update_for_newframe(C, 1); for(sa= screen->areabase.first; sa; sa= sa->next) { @@ -2497,6 +2496,12 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) } } + /* update frame rate info too + * NOTE: this may not be accurate enough, since we might need this after modifiers/etc. + * have been calculated instead of just before updates have been done? + */ + ED_refresh_viewport_fps(C); + /* recalculate the timestep for the timer now that we've finished calculating this, * since the frames-per-second value may have been changed */ diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 97ae94cae26..594eff2c0a0 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -612,6 +612,8 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) case NC_SCREEN: if(wmn->data == ND_GPENCIL) ED_region_tag_redraw(ar); + else if(wmn->data==ND_ANIMPLAY) + ED_region_tag_redraw(ar); break; } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 3c5b8c0abc7..855da0eefcf 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -74,6 +74,7 @@ #include "BIF_glutil.h" #include "WM_api.h" +#include "WM_types.h" #include "BLF_api.h" #include "ED_armature.h" @@ -82,6 +83,7 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_space_api.h" +#include "ED_screen_types.h" #include "ED_util.h" #include "ED_transform.h" #include "ED_types.h" @@ -1989,6 +1991,57 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, glPopMatrix(); } +/* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(), + * which currently gets called during SCREEN_OT_animation_step. + */ +static void draw_viewport_fps(Scene *scene, ARegion *ar) +{ + ScreenFrameRateInfo *fpsi= scene->fps_info; + float fps; + char printable[16]; + int i, tot; + + if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime) + return; + + printable[0] = '\0'; + +#if 0 + /* this is too simple, better do an average */ + fps = (float)(1.0/(fpsi->lredrawtime-fpsi->redrawtime)) +#else + fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0/(fpsi->lredrawtime-fpsi->redrawtime)); + + for (i=0, tot=0, fps=0.0f ; i < REDRAW_FRAME_AVERAGE ; i++) { + if (fpsi->redrawtimes_fps[i]) { + fps += fpsi->redrawtimes_fps[i]; + tot++; + } + } + if (tot) { + fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE; + + //fpsi->redrawtime_index++; + //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE) + // fpsi->redrawtime = 0; + + fps = fps / tot; + } +#endif + + /* is this more then half a frame behind? */ + if (fps+0.5 < FPS) { + UI_ThemeColor(TH_REDALERT); + sprintf(printable, "fps: %.2f", (float)fps); + } + else { + UI_ThemeColor(TH_TEXT_HI); + sprintf(printable, "fps: %i", (int)(fps+0.5)); + } + + BLF_draw_default(22, ar->winy-17, 0.0f, printable); +} + void view3d_main_area_draw(const bContext *C, ARegion *ar) { Scene *scene= CTX_data_scene(C); @@ -2176,8 +2229,10 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) else draw_view_icon(rv3d); - /* XXX removed viewport fps */ - if(U.uiflag & USER_SHOW_VIEWPORTNAME) { + if((U.uiflag & USER_SHOW_FPS) && (CTX_wm_screen(C)->animtimer)) { + draw_viewport_fps(scene, ar); + } + else if(U.uiflag & USER_SHOW_VIEWPORTNAME) { draw_viewport_name(ar, v3d); } if (grid_unit) { /* draw below the viewport name */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 204af647b3a..0138234850e 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -761,6 +761,8 @@ typedef struct Scene { void *sound_scene; void *sound_scene_handle; + void *fps_info; /* (runtime) info/cache used for presenting playback framerate info to the user */ + /* none of the dependancy graph vars is mean to be saved */ struct DagForest *theDag; short dagisvalid, dagflags; -- cgit v1.2.3