windows graphics

svn path=/trunk/boinc/; revision=529
This commit is contained in:
Eric Heien 2002-10-25 18:23:59 +00:00
parent ef99f6174d
commit d0073a01ed
2 changed files with 77 additions and 17 deletions

View File

@ -30,6 +30,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <afxwin.h> #include <afxwin.h>
#include <winuser.h> #include <winuser.h>
#include <mmsystem.h> // for timing
#endif #endif
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
@ -55,12 +56,18 @@
static APP_INIT_DATA aid; static APP_INIT_DATA aid;
GRAPHICS_INFO gi; GRAPHICS_INFO gi;
static double timer_period = 0.1; static double timer_period = 1.0/50.0; // 50 Hz timer
static double time_until_checkpoint; static double time_until_checkpoint;
static double time_until_redraw;
static double time_until_fraction_done_update; static double time_until_fraction_done_update;
static double fraction_done; static double fraction_done;
static bool ready_to_checkpoint = false; static bool ready_to_checkpoint = false;
static bool ready_to_redraw = false;
static bool this_process_active; static bool this_process_active;
int ok_to_draw = 0;
#ifdef _WIN32
HANDLE hGlobalDrawEvent;
#endif
// read the INIT_DATA and FD_INIT files // read the INIT_DATA and FD_INIT files
// //
@ -120,6 +127,7 @@ int boinc_init() {
#endif #endif
time_until_checkpoint = aid.checkpoint_period; time_until_checkpoint = aid.checkpoint_period;
time_until_fraction_done_update = aid.fraction_done_update_period; time_until_fraction_done_update = aid.fraction_done_update_period;
time_until_redraw = gi.refresh_period;
this_process_active = true; this_process_active = true;
set_timer(timer_period); set_timer(timer_period);
@ -161,6 +169,17 @@ int boinc_resolve_filename(char *virtual_name, char *physical_name, int len) {
bool boinc_time_to_checkpoint() { bool boinc_time_to_checkpoint() {
// Tell the graphics thread it's OK to draw now
if (ready_to_redraw) {
ok_to_draw = 1;
// And wait for the graphics thread to notify us that it's done drawing
ResetEvent(hGlobalDrawEvent);
WaitForSingleObject( hGlobalDrawEvent, INFINITE );
// Reset the refresh counter
time_until_redraw = gi.refresh_period;
ready_to_redraw = false;
}
return ready_to_checkpoint; return ready_to_checkpoint;
} }
@ -248,7 +267,7 @@ double boinc_cpu_time() {
} }
#ifdef _WIN32 #ifdef _WIN32
void CALLBACK on_timer(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) { void CALLBACK on_timer(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) {
#else #else
void on_timer(int a) { void on_timer(int a) {
#endif #endif
@ -260,6 +279,13 @@ void on_timer(int a) {
} }
} }
if (!ready_to_redraw) {
time_until_redraw -= timer_period;
if (time_until_redraw <= 0) {
ready_to_redraw = true;
}
}
if (this_process_active) { if (this_process_active) {
time_until_fraction_done_update -= timer_period; time_until_fraction_done_update -= timer_period;
if (time_until_fraction_done_update < 0) { if (time_until_fraction_done_update < 0) {
@ -275,7 +301,23 @@ void on_timer(int a) {
int set_timer(double period) { int set_timer(double period) {
int retval=0; int retval=0;
#ifdef _WIN32 #ifdef _WIN32
retval = SetTimer(NULL, 0, (int)(period*1000), on_timer); // Use Windows multimedia timer, since it is more accurate
// than SetTimer and doesn't require an associated event loop
retval = timeSetEvent(
(int)(period*1000), // uDelay
(int)(period*1000), // uResolution
on_timer, // lpTimeProc
NULL, // dwUser
TIME_PERIODIC // fuEvent
);
// Create the event object used to signal between the
// worker and event threads
hGlobalDrawEvent = CreateEvent(
NULL, // no security attributes
TRUE, // manual reset event
TRUE, // initial state is signaled
NULL); // object not named
#endif #endif
#if HAVE_SIGNAL_H #if HAVE_SIGNAL_H

View File

@ -1,3 +1,22 @@
// The contents of this file are subject to the Mozilla Public License
// Version 1.0 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://www.mozilla.org/MPL/
//
// Software distributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is the Berkeley Open Infrastructure for Network Computing.
//
// The Initial Developer of the Original Code is the SETI@home project.
// Portions created by the SETI@home project are Copyright (C) 2002
// University of California at Berkeley. All Rights Reserved.
//
// Contributor(s):
//
/* /*
* This Code Was Created By Jeff Molofee 2000 * This Code Was Created By Jeff Molofee 2000
* A HUGE Thanks To Fredric Echols For Cleaning Up * A HUGE Thanks To Fredric Echols For Cleaning Up
@ -12,7 +31,6 @@
#include <gl\glu.h> // Header File For The GLu32 Library #include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library #include <gl\glaux.h> // Header File For The Glaux Library
#include <stdio.h> #include <stdio.h>
#include <time.h>
#include "graphics_api.h" #include "graphics_api.h"
@ -22,6 +40,7 @@ HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application HINSTANCE hInstance; // Holds The Instance Of The Application
int mouse_thresh = 3; int mouse_thresh = 3;
int initCursorPosx, initCursorPosy; int initCursorPosx, initCursorPosy;
extern int ok_to_draw;
GLuint base; // Base Display List For The Font Set GLuint base; // Base Display List For The Font Set
GLfloat cnt1; // 1st Counter Used To Move Text & For Coloring GLfloat cnt1; // 1st Counter Used To Move Text & For Coloring
@ -30,8 +49,9 @@ GLfloat cnt2; // 2nd Counter Used To Move Text & For Coloring
bool keys[256]; bool keys[256];
bool active=TRUE; // Window Active Flag Set To TRUE By Default bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default
BOOL done=FALSE; // Bool Variable To Exit Loop BOOL done=FALSE; // Bool Variable To Exit Loop
int counter; int counter;
extern HANDLE hGlobalDrawEvent;
int DrawGLScene(GLvoid); int DrawGLScene(GLvoid);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
@ -444,16 +464,12 @@ LRESULT CALLBACK WndProc( HWND hWnd, // Handle For This Window
DWORD WINAPI win_graphics_event_loop( LPVOID gi ) { DWORD WINAPI win_graphics_event_loop( LPVOID gi ) {
MSG msg; // Windows Message Structure MSG msg; // Windows Message Structure
clock_t next_draw_time;
next_draw_time = clock();
fullscreen=FALSE; // Windowed Mode fullscreen=FALSE; // Windowed Mode
// Create Our OpenGL Window // Create Our OpenGL Window
if (!CreateGLWindow("BOINC Application Window",((GRAPHICS_INFO*)gi)->xsize, if (!CreateGLWindow("BOINC Application Window",((GRAPHICS_INFO*)gi)->xsize,
((GRAPHICS_INFO*)gi)->ysize,1,fullscreen)) ((GRAPHICS_INFO*)gi)->ysize,1,fullscreen)) {
{
return 0; // Quit If Window Was Not Created return 0; // Quit If Window Was Not Created
} }
@ -473,13 +489,15 @@ DWORD WINAPI win_graphics_event_loop( LPVOID gi ) {
{ {
if (active) // Program Active? if (active) // Program Active?
{ {
if (keys[VK_ESCAPE]) { // Was ESC Pressed? if (ok_to_draw) { // Not Time To Quit, Update Screen
done=TRUE; // ESC Signalled A Quit // Draw The Scene
} DrawGLScene();
else if (clock()>next_draw_time) { // Not Time To Quit, Update Screen // Swap Buffers (Double Buffering). This seems to take lots of CPU time
DrawGLScene(); // Draw The Scene SwapBuffers(hDC);
SwapBuffers(hDC); // Swap Buffers (Double Buffering). This is taking lots of CPU time // TODO: Do we need a mutex for ok_to_draw?
next_draw_time = clock()+(1000/60); ok_to_draw = 0;
// Signal the worker thread that we're done drawing
SetEvent(hGlobalDrawEvent);
} }
} }