From a41b08d1a4cd79e6254ec93ba711c3bf11e7ab61 Mon Sep 17 00:00:00 2001 From: Vlad Date: Tue, 10 Aug 2010 15:28:05 +0300 Subject: [PATCH] added fps files --- xscreensaver/hacks/fps.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++ xscreensaver/hacks/fps.h | 28 ++++++ 2 files changed, 270 insertions(+) create mode 100644 xscreensaver/hacks/fps.c create mode 100644 xscreensaver/hacks/fps.h diff --git a/xscreensaver/hacks/fps.c b/xscreensaver/hacks/fps.c new file mode 100644 index 0000000..2aa0174 --- /dev/null +++ b/xscreensaver/hacks/fps.c @@ -0,0 +1,242 @@ +/* fps, Copyright (c) 2001-2008 Jamie Zawinski + * Draw a frames-per-second display (Xlib and OpenGL). + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include "screenhackI.h" +#include "fpsI.h" + +fps_state * +fps_init (Display *dpy, Window window) +{ + fps_state *st; + const char *font; + XFontStruct *f; + int first, last; + + if (! get_boolean_resource (dpy, "doFPS", "DoFPS")) + return 0; + + st = (fps_state *) calloc (1, sizeof(*st)); + + st->dpy = dpy; + st->window = window; + st->clear_p = get_boolean_resource (dpy, "fpsSolid", "FPSSolid"); + + font = get_string_resource (dpy, "fpsFont", "Font"); + + if (!font) font = "-*-courier-bold-r-normal-*-180-*"; + f = XLoadQueryFont (dpy, font); + if (!f) f = XLoadQueryFont (dpy, "fixed"); + + first = f->min_char_or_byte2; + last = f->max_char_or_byte2; + + { + XWindowAttributes xgwa; + XGCValues gcv; + XGetWindowAttributes (dpy, window, &xgwa); + gcv.font = f->fid; + gcv.foreground = + get_pixel_resource (st->dpy, xgwa.colormap, "foreground", "Foreground"); + st->draw_gc = XCreateGC (dpy, window, GCFont|GCForeground, &gcv); + gcv.foreground = + get_pixel_resource (st->dpy, xgwa.colormap, "background", "Background"); + st->erase_gc = XCreateGC (dpy, window, GCFont|GCForeground, &gcv); + } + + st->font = f; + st->x = 10; + st->y = 10; + if (get_boolean_resource (dpy, "fpsTop", "FPSTop")) + st->y = - (st->font->ascent + st->font->descent + 10); + + strcpy (st->string, "FPS: ... "); + + return st; +} + +void +fps_free (fps_state *st) +{ + if (st->draw_gc) XFreeGC (st->dpy, st->draw_gc); + if (st->erase_gc) XFreeGC (st->dpy, st->erase_gc); + if (st->font) XFreeFont (st->dpy, st->font); + free (st); +} + + +void +fps_slept (fps_state *st, unsigned long usecs) +{ + st->slept += usecs; +} + + +double +fps_compute (fps_state *st, unsigned long polys) +{ + if (! st) return 0; /* too early? */ + + /* Every N frames (where N is approximately one second's worth of frames) + check the wall clock. We do this because checking the wall clock is + a slow operation. + */ + if (st->frame_count++ >= st->last_ifps) + { +# ifdef GETTIMEOFDAY_TWO_ARGS + struct timezone tzp; + gettimeofday(&st->this_frame_end, &tzp); +# else + gettimeofday(&st->this_frame_end); +# endif + + if (st->prev_frame_end.tv_sec == 0) + st->prev_frame_end = st->this_frame_end; + } + + /* If we've probed the wall-clock time, regenerate the string. + */ + if (st->this_frame_end.tv_sec != st->prev_frame_end.tv_sec) + { + double uprev_frame_end = (st->prev_frame_end.tv_sec + + ((double) st->prev_frame_end.tv_usec + * 0.000001)); + double uthis_frame_end = (st->this_frame_end.tv_sec + + ((double) st->this_frame_end.tv_usec + * 0.000001)); + double fps = st->frame_count / (uthis_frame_end - uprev_frame_end); + double idle = (((double) st->slept * 0.000001) / + (uthis_frame_end - uprev_frame_end)); + double load = 100 * (1 - idle); + + if (load < 0) load = 0; /* well that's obviously nonsense... */ + + st->prev_frame_end = st->this_frame_end; + st->frame_count = 0; + st->slept = 0; + st->last_ifps = fps; + st->last_fps = fps; + + sprintf (st->string, (polys + ? "FPS: %.1f \nLoad: %.1f%% " + : "FPS: %.1f \nLoad: %.1f%% "), + fps, load); + + if (polys > 0) + { + const char *s = ""; +# if 0 + if (polys >= (1024 * 1024)) polys >>= 20, s = "M"; + else if (polys >= 2048) polys >>= 10, s = "K"; +# endif + + strcat (st->string, "\nPolys: "); + if (polys >= 1000000) + sprintf (st->string + strlen(st->string), "%lu,%03lu,%03lu%s ", + (polys / 1000000), ((polys / 1000) % 1000), + (polys % 1000), s); + else if (polys >= 1000) + sprintf (st->string + strlen(st->string), "%lu,%03lu%s ", + (polys / 1000), (polys % 1000), s); + else + sprintf (st->string + strlen(st->string), "%lu%s ", polys, s); + } + } + + return st->last_fps; +} + + + +/* Width (and optionally height) of the string in pixels. + */ +static int +string_width (XFontStruct *f, const char *c, int *height_ret) +{ + int x = 0; + int max_w = 0; + int h = f->ascent + f->descent; + while (*c) + { + int cc = *((unsigned char *) c); + if (*c == '\n') + { + if (x > max_w) max_w = x; + x = 0; + h += f->ascent + f->descent; + } + else + x += (f->per_char + ? f->per_char[cc-f->min_char_or_byte2].width + : f->min_bounds.rbearing); + c++; + } + if (x > max_w) max_w = x; + if (height_ret) *height_ret = h; + + return max_w; +} + + +/* This function is used only in Xlib mode. For GL mode, see glx/fps-glx.c. + */ +void +fps_draw (fps_state *st) +{ + XWindowAttributes xgwa; + const char *string = st->string; + const char *s; + int x = st->x; + int y = st->y; + int lines = 1; + int lh = st->font->ascent + st->font->descent; + + XGetWindowAttributes (st->dpy, st->window, &xgwa); + + for (s = string; *s; s++) + if (*s == '\n') lines++; + + if (y < 0) + y = -y + (lines-1) * lh; + else + y = xgwa.height - y; + + y -= lh * (lines-1) + st->font->descent; + + /* clear the background */ + if (st->clear_p) + { + int w, h; + w = string_width (st->font, string, &h); + XFillRectangle (st->dpy, st->window, st->erase_gc, + x - st->font->descent, + y - lh, + w + 2*st->font->descent, + h + 2*st->font->descent); + } + + /* draw the text */ + while (lines) + { + s = strchr (string, '\n'); + if (! s) s = string + strlen(string); + XDrawString (st->dpy, st->window, st->draw_gc, + x, y, string, s - string); + string = s; + string++; + lines--; + y += lh; + } +} diff --git a/xscreensaver/hacks/fps.h b/xscreensaver/hacks/fps.h new file mode 100644 index 0000000..6f9559c --- /dev/null +++ b/xscreensaver/hacks/fps.h @@ -0,0 +1,28 @@ +/* fps, Copyright (c) 2001-2008 Jamie Zawinski + * Draw a frames-per-second display (Xlib and OpenGL). + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. No representations are made about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + */ + +#ifndef __XSCREENSAVER_FPS_H__ +# define __XSCREENSAVER_FPS_H__ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +typedef struct fps_state fps_state; + +extern fps_state *fps_init (Display *, Window); +extern void fps_free (fps_state *); +extern void fps_slept (fps_state *, unsigned long usecs); +extern double fps_compute (fps_state *, unsigned long polys); +extern void fps_draw (fps_state *); + +#endif /* __XSCREENSAVER_FPS_H__ */ -- 1.7.9.5