Bugfix #21051: Restored 'Playback FPS'
authorJoshua Leung <aligorith@gmail.com>
Fri, 12 Feb 2010 00:44:26 +0000 (00:44 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 12 Feb 2010 00:44:26 +0000 (00:44 +0000)
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
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/ED_screen.h
source/blender/editors/include/ED_screen_types.h
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/makesdna/DNA_scene_types.h

index 4624fbe..68dded0 100644 (file)
@@ -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);
 }
index 1758512..ecddb62 100644 (file)
@@ -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);
 
index 89f032e..c88985a 100644 (file)
@@ -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);
 
index 0deda5a..3ce3ac7 100644 (file)
@@ -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 {
index 048ade7..5c987f8 100644 (file)
@@ -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
  */
index 7f63fc1..1370993 100644 (file)
@@ -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
                 */
index 97ae94c..594eff2 100644 (file)
@@ -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;
        }
 }
index 3c5b8c0..855da0e 100644 (file)
@@ -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 */
index 204af64..0138234 100644 (file)
@@ -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;