mirror of https://github.com/BOINC/boinc.git
Merge branch 'master' of ssh://boinc.berkeley.edu/boinc-v2
This commit is contained in:
commit
2af3f993fb
|
@ -92,6 +92,10 @@ protected:
|
||||||
void updateSSMessageText(char *msg);
|
void updateSSMessageText(char *msg);
|
||||||
void strip_cr(char *buf);
|
void strip_cr(char *buf);
|
||||||
char m_gfx_Switcher_Path[PATH_MAX];
|
char m_gfx_Switcher_Path[PATH_MAX];
|
||||||
|
void SetDiscreteGPU(bool setDiscrete);
|
||||||
|
void CheckDualGPUStatus();
|
||||||
|
bool Host_is_running_on_batteries();
|
||||||
|
|
||||||
bool m_bErrorMode; // Whether to draw moving logo and possibly display an error
|
bool m_bErrorMode; // Whether to draw moving logo and possibly display an error
|
||||||
unsigned int m_hrError; // Error code to display
|
unsigned int m_hrError; // Error code to display
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,11 @@ int signof(float x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Path to our copy of switcher utility application in this screensaver bundle
|
||||||
|
if (gPathToBundleResources == NULL) {
|
||||||
|
gPathToBundleResources = [ myBundle resourcePath ];
|
||||||
|
}
|
||||||
|
|
||||||
[ super startAnimation ];
|
[ super startAnimation ];
|
||||||
|
|
||||||
if ( [ self isPreview ] ) {
|
if ( [ self isPreview ] ) {
|
||||||
|
@ -228,6 +233,8 @@ int signof(float x) {
|
||||||
}
|
}
|
||||||
gBOINC_Logo = NULL;
|
gBOINC_Logo = NULL;
|
||||||
|
|
||||||
|
// gPathToBundleResources has been released by autorelease
|
||||||
|
gPathToBundleResources = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are multiple displays, this may get called
|
// If there are multiple displays, this may get called
|
||||||
|
|
|
@ -20,7 +20,18 @@
|
||||||
// BOINC_Saver_Module
|
// BOINC_Saver_Module
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <IOKit/IOKitLib.h>
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include <IOKit/ps/IOPowerSources.h>
|
||||||
|
#include <IOKit/ps/IOPSKeys.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -49,7 +60,7 @@
|
||||||
#define NOTEXTLOGOFREQUENCY 4 /* Times per second to call animateOneFrame if no moving logo with text */
|
#define NOTEXTLOGOFREQUENCY 4 /* Times per second to call animateOneFrame if no moving logo with text */
|
||||||
#define GFX_STARTING_MSG_DURATION 45 /* seconds to show ScreenSaverAppStartingMsg */
|
#define GFX_STARTING_MSG_DURATION 45 /* seconds to show ScreenSaverAppStartingMsg */
|
||||||
#define RPC_RETRY_INTERVAL 10 /* # of seconds between retries connecting to core client */
|
#define RPC_RETRY_INTERVAL 10 /* # of seconds between retries connecting to core client */
|
||||||
|
#define BATTERY_CHECK_INTERVAL 3 /* # of seconds between checks of whether running on batteries */
|
||||||
|
|
||||||
enum SaverState {
|
enum SaverState {
|
||||||
SaverState_Idle,
|
SaverState_Idle,
|
||||||
|
@ -73,8 +84,13 @@ extern CFStringRef gPathToBundleResources;
|
||||||
static SaverState saverState = SaverState_Idle;
|
static SaverState saverState = SaverState_Idle;
|
||||||
// int gQuitCounter = 0;
|
// int gQuitCounter = 0;
|
||||||
|
|
||||||
|
static bool IsDualGPUMacbook = false;
|
||||||
|
static io_connect_t GPUSelectConnect = IO_OBJECT_NULL;
|
||||||
|
static bool RunningOnBattery = true;
|
||||||
|
static time_t ScreenSaverStartTime = 0;
|
||||||
|
static bool ScreenIsBlanked = false;
|
||||||
|
|
||||||
const char * CantLaunchCCMsg = "Unable to launch BOINC application.";
|
const char * CantLaunchCCMsg = "Unable to launch BOINC application.";
|
||||||
const char * LaunchingCCMsg = "Launching BOINC application.";
|
const char * LaunchingCCMsg = "Launching BOINC application.";
|
||||||
const char * ConnectingCCMsg = "Connecting to BOINC application.";
|
const char * ConnectingCCMsg = "Connecting to BOINC application.";
|
||||||
const char * ConnectedCCMsg = "Communicating with BOINC application.";
|
const char * ConnectedCCMsg = "Communicating with BOINC application.";
|
||||||
|
@ -84,6 +100,7 @@ const char * ScreenSaverAppStartingMsg = "Starting screensaver graphics.\nPleas
|
||||||
const char * CantLaunchDefaultGFXAppMsg = "Can't launch default screensaver module. Please reinstall BOINC";
|
const char * CantLaunchDefaultGFXAppMsg = "Can't launch default screensaver module. Please reinstall BOINC";
|
||||||
const char * DefaultGFXAppCantRPCMsg = "Default screensaver module couldn't connect to BOINC application";
|
const char * DefaultGFXAppCantRPCMsg = "Default screensaver module couldn't connect to BOINC application";
|
||||||
const char * DefaultGFXAppCrashedMsg = "Default screensaver module had an unrecoverable error";
|
const char * DefaultGFXAppCrashedMsg = "Default screensaver module had an unrecoverable error";
|
||||||
|
const char * RunningOnBatteryMsg = "Displaying minimum screensaver to save battery power";
|
||||||
|
|
||||||
//const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode.";
|
//const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode.";
|
||||||
|
|
||||||
|
@ -281,6 +298,22 @@ int CScreensaver::Create() {
|
||||||
saverState = SaverState_ControlPanelTestMode;
|
saverState = SaverState_ControlPanelTestMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the estimated blank time by adding the starting
|
||||||
|
// time and and the user-specified time which is in minutes
|
||||||
|
// On dual-GPU Macbok Pros, the CScreensaver class will be
|
||||||
|
// constructed and destructed each time we switch beteen
|
||||||
|
// battery and AC power, so we need to get the starting time
|
||||||
|
// only once.
|
||||||
|
if (!ScreenSaverStartTime) {
|
||||||
|
ScreenSaverStartTime = time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dwBlankScreen = gGoToBlank;
|
||||||
|
if (gGoToBlank && (gBlankingTime > 0))
|
||||||
|
m_dwBlankTime = ScreenSaverStartTime + (gBlankingTime * 60);
|
||||||
|
else
|
||||||
|
m_dwBlankTime = 0;
|
||||||
|
|
||||||
// If there are multiple displays, initBOINCSaver may get called
|
// If there are multiple displays, initBOINCSaver may get called
|
||||||
// multiple times (once for each display), so we need to guard
|
// multiple times (once for each display), so we need to guard
|
||||||
// against launching multiple instances of the core client
|
// against launching multiple instances of the core client
|
||||||
|
@ -302,6 +335,15 @@ int CScreensaver::Create() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!IsDualGPUMacbook) {
|
||||||
|
SetDiscreteGPU(false);
|
||||||
|
if (IsDualGPUMacbook && (GPUSelectConnect != IO_OBJECT_NULL)) {
|
||||||
|
IOServiceClose(GPUSelectConnect);
|
||||||
|
GPUSelectConnect = IO_OBJECT_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TEXTLOGOFREQUENCY;
|
return TEXTLOGOFREQUENCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,19 +441,32 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) {
|
||||||
pid_t myPid;
|
pid_t myPid;
|
||||||
OSStatus err;
|
OSStatus err;
|
||||||
|
|
||||||
|
if (ScreenIsBlanked) {
|
||||||
|
setSSMessageText(0); // No text message
|
||||||
|
return NOTEXTLOGOFREQUENCY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckDualGPUStatus();
|
||||||
|
|
||||||
switch (saverState) {
|
switch (saverState) {
|
||||||
case SaverState_RelaunchCoreClient:
|
case SaverState_RelaunchCoreClient:
|
||||||
err = initBOINCApp();
|
err = initBOINCApp();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SaverState_LaunchingCoreClient:
|
case SaverState_LaunchingCoreClient:
|
||||||
if (m_wasAlreadyRunning)
|
if (IsDualGPUMacbook && RunningOnBattery) {
|
||||||
|
setSSMessageText(RunningOnBatteryMsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_wasAlreadyRunning) {
|
||||||
setSSMessageText(ConnectingCCMsg);
|
setSSMessageText(ConnectingCCMsg);
|
||||||
else
|
} else {
|
||||||
setSSMessageText(LaunchingCCMsg);
|
setSSMessageText(LaunchingCCMsg);
|
||||||
|
}
|
||||||
|
|
||||||
myPid = FindProcessPID(NULL, m_CoreClientPID);
|
myPid = FindProcessPID(NULL, m_CoreClientPID);
|
||||||
if (myPid) {
|
if (myPid) {
|
||||||
saverState = SaverState_CoreClientRunning;
|
saverState = SaverState_CoreClientRunning;
|
||||||
if (!rpc->init(NULL)) { // Initialize communications with Core Client
|
if (!rpc->init(NULL)) { // Initialize communications with Core Client
|
||||||
m_bConnected = true;
|
m_bConnected = true;
|
||||||
|
@ -431,20 +486,31 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SaverState_CoreClientRunning:
|
case SaverState_CoreClientRunning:
|
||||||
// RPC called in DataManagementProc()
|
if (IsDualGPUMacbook && RunningOnBattery) {
|
||||||
setSSMessageText(ConnectingCCMsg);
|
setSSMessageText(RunningOnBatteryMsg);
|
||||||
if (! m_bResetCoreState) {
|
break;
|
||||||
saverState = SaverState_ConnectedToCoreClient;
|
}
|
||||||
}
|
|
||||||
break;
|
// RPC called in DataManagementProc()
|
||||||
|
setSSMessageText(ConnectingCCMsg);
|
||||||
|
if (! m_bResetCoreState) {
|
||||||
|
saverState = SaverState_ConnectedToCoreClient;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SaverState_ConnectedToCoreClient:
|
case SaverState_ConnectedToCoreClient:
|
||||||
|
if (IsDualGPUMacbook && RunningOnBattery) {
|
||||||
|
setSSMessageText(RunningOnBatteryMsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (m_hrError) {
|
switch (m_hrError) {
|
||||||
case 0:
|
case 0:
|
||||||
setSSMessageText(ConnectedCCMsg);
|
setSSMessageText(ConnectedCCMsg);
|
||||||
break; // No status response yet from DataManagementProc
|
break; // No status response yet from DataManagementProc
|
||||||
case SCRAPPERR_SCREENSAVERBLANKED:
|
case SCRAPPERR_SCREENSAVERBLANKED:
|
||||||
setSSMessageText(0); // No text message
|
setSSMessageText(0); // No text message
|
||||||
|
ScreenIsBlanked = true;
|
||||||
break;
|
break;
|
||||||
#if 0 // Not currently used
|
#if 0 // Not currently used
|
||||||
case SCRAPPERR_QUITSCREENSAVERREQUESTED:
|
case SCRAPPERR_QUITSCREENSAVERREQUESTED:
|
||||||
|
@ -520,6 +586,12 @@ int CScreensaver::getSSMessage(char **theMessage, int* coveredFreq) {
|
||||||
break; // Should never get here; fixes compiler warning
|
break; // Should never get here; fixes compiler warning
|
||||||
} // end switch (saverState)
|
} // end switch (saverState)
|
||||||
|
|
||||||
|
if (IsDualGPUMacbook && RunningOnBattery) {
|
||||||
|
if ((m_dwBlankScreen) && (time(0) > m_dwBlankTime) && (m_dwBlankTime > 0)) {
|
||||||
|
setSSMessageText(0); // No text message
|
||||||
|
ScreenIsBlanked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_MessageText[0]) {
|
if (m_MessageText[0]) {
|
||||||
newFrequency = TEXTLOGOFREQUENCY;
|
newFrequency = TEXTLOGOFREQUENCY;
|
||||||
|
@ -621,13 +693,11 @@ void CScreensaver::HandleRPCError() {
|
||||||
bool CScreensaver::CreateDataManagementThread() {
|
bool CScreensaver::CreateDataManagementThread() {
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
// Calculate the estimated blank time by adding the starting
|
// On dual-GPU Macbook Pros, our OpenGL scrensaver
|
||||||
// time and and the user-specified time which is in minutes
|
// applications trigger a switch to the power-hungry
|
||||||
m_dwBlankScreen = gGoToBlank;
|
// discrete GPU. To extend battery life, don't run
|
||||||
if (gGoToBlank && (gBlankingTime > 0))
|
// them when on battery power.
|
||||||
m_dwBlankTime = time(0) + (gBlankingTime * 60);
|
if (IsDualGPUMacbook && RunningOnBattery) return true;
|
||||||
else
|
|
||||||
m_dwBlankTime = 0;
|
|
||||||
|
|
||||||
if (m_hDataManagementThread == NULL) {
|
if (m_hDataManagementThread == NULL) {
|
||||||
retval = pthread_create(&m_hDataManagementThread, NULL, DataManagementProcStub, 0);
|
retval = pthread_create(&m_hDataManagementThread, NULL, DataManagementProcStub, 0);
|
||||||
|
@ -822,6 +892,82 @@ OSErr CScreensaver::KillScreenSaver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CScreensaver::Host_is_running_on_batteries() {
|
||||||
|
CFDictionaryRef pSource = NULL;
|
||||||
|
CFStringRef psState;
|
||||||
|
int i;
|
||||||
|
bool retval = false;
|
||||||
|
|
||||||
|
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
|
||||||
|
CFArrayRef list = IOPSCopyPowerSourcesList(blob);
|
||||||
|
|
||||||
|
for (i=0; i<CFArrayGetCount(list); i++) {
|
||||||
|
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(list, i));
|
||||||
|
if(!pSource) break;
|
||||||
|
psState = (CFStringRef)CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));
|
||||||
|
if(!CFStringCompare(psState,CFSTR(kIOPSBatteryPowerValue),0))
|
||||||
|
retval = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(blob);
|
||||||
|
CFRelease(list);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CScreensaver::SetDiscreteGPU(bool setDiscrete) {
|
||||||
|
kern_return_t kernResult = 0;
|
||||||
|
io_service_t service = IO_OBJECT_NULL;
|
||||||
|
|
||||||
|
if (GPUSelectConnect == IO_OBJECT_NULL) {
|
||||||
|
service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleGraphicsControl"));
|
||||||
|
if (service != IO_OBJECT_NULL) {
|
||||||
|
kernResult = IOServiceOpen(service, mach_task_self(), setDiscrete ? 1 : 0, &GPUSelectConnect);
|
||||||
|
if (kernResult == KERN_SUCCESS) {
|
||||||
|
IsDualGPUMacbook = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// On Dual-GPU Macbook Pros only:
|
||||||
|
// switch to intrinsic GPU if running on battery
|
||||||
|
// switch to discrete GPU if running on AC power
|
||||||
|
//
|
||||||
|
// Apple's Screensaver Engine will detect the GPU change and
|
||||||
|
// call stopAnimation, then initWithFrame and startAnimation.
|
||||||
|
void CScreensaver::CheckDualGPUStatus() {
|
||||||
|
static double lastBatteryCheckTime = 0;
|
||||||
|
double currentTime;
|
||||||
|
bool nowOnBattery;
|
||||||
|
|
||||||
|
if (!IsDualGPUMacbook) return;
|
||||||
|
|
||||||
|
currentTime = dtime();
|
||||||
|
if (currentTime < lastBatteryCheckTime + BATTERY_CHECK_INTERVAL) return;
|
||||||
|
lastBatteryCheckTime = currentTime;
|
||||||
|
|
||||||
|
nowOnBattery = Host_is_running_on_batteries();
|
||||||
|
if (nowOnBattery == RunningOnBattery) return;
|
||||||
|
|
||||||
|
RunningOnBattery = nowOnBattery;
|
||||||
|
if (nowOnBattery) {
|
||||||
|
if (GPUSelectConnect != IO_OBJECT_NULL) {
|
||||||
|
IOServiceClose(GPUSelectConnect);
|
||||||
|
GPUSelectConnect = IO_OBJECT_NULL;
|
||||||
|
}
|
||||||
|
// If an OpenGL screensaver app is running, ew must shut it down
|
||||||
|
// to release its claim on the discrete GPU to save battery power.
|
||||||
|
DestroyDataManagementThread();
|
||||||
|
} else {
|
||||||
|
SetDiscreteGPU(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void print_to_log_file(const char *format, ...) {
|
void print_to_log_file(const char *format, ...) {
|
||||||
#if CREATE_LOG
|
#if CREATE_LOG
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
Loading…
Reference in New Issue