From 938a303ef8b63e51d78cd7f9bcb77a70c7bf7aa3 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 2 Oct 2003 21:16:37 +0000 Subject: [PATCH] frame rate throttling svn path=/trunk/boinc/; revision=2392 --- api/graphics_api.C | 65 +++++++++++++++++++++++++++++++++++++++++--- api/graphics_api.h | 8 ++---- api/windows_opengl.C | 46 ++++++++++++++++--------------- 3 files changed, 88 insertions(+), 31 deletions(-) diff --git a/api/graphics_api.C b/api/graphics_api.C index 8a2d0e5dab..5858ec946e 100755 --- a/api/graphics_api.C +++ b/api/graphics_api.C @@ -28,6 +28,9 @@ extern DWORD WINAPI win_graphics_event_loop( LPVOID duff ); HANDLE graphics_threadh=NULL; #endif +#ifdef __APPLE_CC__ +#include "mac_app_opengl.h" +#endif #include #include @@ -37,13 +40,12 @@ HANDLE graphics_threadh=NULL; #endif #include "parse.h" +#include "util.h" #include "app_ipc.h" -#include "graphics_api.h" #include "error_numbers.h" +#include "boinc_api.h" +#include "graphics_api.h" -#ifdef __APPLE_CC__ -#include "mac_app_opengl.h" -#endif #ifdef _WIN32 HANDLE hQuitEvent; @@ -158,6 +160,61 @@ int boinc_finish_opengl() { return 0; } +void throttled_app_render(int x, int y, double t) { + static double total_render_time = 0; + static double time_until_render = 0; + static double last_now = 0; + static double elapsed_time = 0; + double now, t0, t1, diff, frac, m; + bool ok_to_render; + + // the following should be passed in via prefs + double max_fps = 1; + double max_gfx_cpu_frac = 0.2; + + ok_to_render = true; + now = dtime(); + diff = now - last_now; + last_now = now; + if (diff > 1) diff = 0; // handle initial case + + // enforce frames/sec restriction + // + if (max_fps) { + time_until_render -= diff; + if (time_until_render < 0) { + time_until_render += 1./max_fps; + } else { + ok_to_render = false; + } + } + + // enforce max CPU time restriction + // + if (max_gfx_cpu_frac) { + elapsed_time += diff; + if (elapsed_time) { + frac = total_render_time/elapsed_time; + if (frac > max_gfx_cpu_frac) { + ok_to_render = false; + } + } + } + + // render if allowed + // + if (ok_to_render) { + if (max_gfx_cpu_frac) { + boinc_cpu_time(t0, m); + } + app_render(x, y, t); + if (max_gfx_cpu_frac) { + boinc_cpu_time(t1, m); + total_render_time += t1 - t0; + } + } +} + #ifdef HAVE_GL_LIB // Custom GL "Print" Routine GLvoid glPrint(GLuint font, const char *fmt, ...) { diff --git a/api/graphics_api.h b/api/graphics_api.h index 256d1b4627..c690a76b27 100755 --- a/api/graphics_api.h +++ b/api/graphics_api.h @@ -8,9 +8,11 @@ #ifndef HAVE_OPENGL_GL_H #define HAVE_OPENGL_GL_H #endif +#include #endif #ifdef _WIN32 +#include #ifndef HAVE_GL_LIB #define HAVE_GL_LIB 1 #endif @@ -68,15 +70,10 @@ #include "x_opengl.h" #endif -#ifdef __APPLE_CC__ -#include -#endif - // The API (functions called by the app) extern int boinc_init_opengl(); extern int boinc_finish_opengl(); extern GLvoid glPrint(GLuint font, const char *fmt, ...); -extern GLenum ReSizeGLScene(GLsizei width, GLsizei height); // Functions that must be supplied by the app // @@ -88,6 +85,7 @@ extern void app_resize(int width, int height); // extern GLenum InitGL(GLvoid); extern GLenum ReSizeGLScene(GLsizei width, GLsizei height); +extern void throttled_app_render(int, int, double); #ifdef _WIN32 extern HANDLE hQuitEvent; diff --git a/api/windows_opengl.C b/api/windows_opengl.C index d08c0b7c5c..613c161b83 100755 --- a/api/windows_opengl.C +++ b/api/windows_opengl.C @@ -1,5 +1,9 @@ -// Event loop and support functions for BOINC applications w/ graphics. -// Is any of this related to or dependent on OpenGL?? +// Event loop and support functions for Windows versions +// of BOINC applications w/ graphics. +// Platform-independent code should NOT be here. +// +// TODO: Is any of this related to or dependent on OpenGL?? +// Why not make it independent of OpenGL? // /* This Code Was Created By Jeff Molofee 2000 @@ -137,9 +141,8 @@ void SetMode(int mode) { hWnd = CreateWindowEx(dwExStyle, "BOINC_OpenGL", aid.app_name, dwStyle|WS_CLIPSIBLINGS|WS_CLIPCHILDREN, WindowRect.left, WindowRect.top, WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top, - NULL, NULL, hInstance, NULL); - - + NULL, NULL, hInstance, NULL + ); SetForegroundWindow(hWnd); @@ -241,27 +244,26 @@ LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window } if (current_graphics_mode == MODE_HIDE_GRAPHICS) return 0; - if(dtime()-starttime>1./fps) - { - GetClientRect(hWnd, &rt); - width = rt.right-rt.left; - height = rt.bottom-rt.top; + // TODO: remove width, height from API + // + GetClientRect(hWnd, &rt); + width = rt.right-rt.left; + height = rt.bottom-rt.top; #ifdef DRAW_WITH_DLL - float* data; - int data_size=100; - data=(float*)malloc(sizeof(float)*data_size); - for(int i=0;i