mac opengl

svn path=/trunk/boinc/; revision=493
This commit is contained in:
Eric Heien 2002-10-14 20:42:01 +00:00
parent b05d095c23
commit 447f4202ae
8 changed files with 3220 additions and 44 deletions

409
api/mac_app_opengl.c Normal file
View File

@ -0,0 +1,409 @@
// 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):
//
#include "graphics_api.h"
#include "mac_app_opengl.h"
#include "mac_carbon_gl.h"
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#include <OpenGL/gl.h>
#else
#include <gl.h>
#include <Devices.h>
#include <Dialogs.h>
#include <DriverServices.h>
#include <Events.h>
#include <Gestalt.h>
#include <LowMem.h>
#include <PictUtils.h>
#include <TextEdit.h>
#include <ToolUtils.h>
#include <QDOffscreen.h>
#include <Windows.h>
#endif
#include <math.h>
#include <stdio.h>
#include <string.h>
// project includes ---------------------------------------------------------
#include "mac_main.h"
void drawGL(WindowPtr pWindow);
static void DisposeGLWindow (WindowPtr pWindow); // Dispose a single window and it's GL context
// statics/globals (internal only) ------------------------------------------
static const EventTypeSpec appEventList[] =
{
{kEventClassCommand, kEventCommandProcess},
{kEventClassMouse, kEventMouseDown},
{kEventClassMouse, kEventMouseUp},
{kEventClassMouse, kEventMouseMoved},
{kEventClassMouse, kEventMouseDragged},
{kEventClassMouse, kEventMouseWheelMoved}
};
WindowRef appGLWindow;
EventLoopTimerRef boincTimer;
EventLoopTimerUPP boincTimerUPP;
EventHandlerUPP appCommandProcessor;
WindowPtr boincAboutWindow;
AGLContext boincAGLContext;
GLuint monacoFontList;
char boincStrContext [256];
structGLWindowInfo glInfo;
long gFrameWindow=0;
float gRotation=0;
AbsoluteTime gTimeWindow;
bool user_requested_exit = false;
// --------------------------------------------------------------------------
int InitGLWindow(int xsize, int ysize, int depth)
{
OSStatus err;
Rect winRect;
TimerUPP boincYieldUPP;
EventLoopTimerRef boincYieldTimer;
short i,fNum;
long response;
MenuHandle menu;
InitCursor();
// add quit if not under Mac OS X
err = Gestalt (gestaltMenuMgrAttr, &response);
if ((err == noErr) && !(response & gestaltMenuMgrAquaLayoutMask)) {
menu = NewMenu (128, "\pFile"); // new menu
InsertMenu (menu, 0); // add menu to end
AppendMenu (menu, "\pQuit/Q"); // add quit
}
SetRect( &winRect, 100, 100, 100+xsize, 100+ysize );
err = CreateNewWindow ( kDocumentWindowClass, kWindowStandardDocumentAttributes, &winRect, &appGLWindow );
if (err != noErr) return -1;
// Application-level event handler installer
appCommandProcessor = NewEventHandlerUPP(MainAppEventHandler);
err = InstallApplicationEventHandler(appCommandProcessor, GetEventTypeCount(appEventList),
appEventList, 0, NULL);
// Install application graphics timer
boincTimerUPP = NewEventLoopTimerUPP(GraphicsLoopProcessor);
err = InstallEventLoopTimer(GetMainEventLoop(), 0,
kEventDurationMillisecond*10, // Every 1/60th of a second
boincTimerUPP, NULL, &boincTimer);
// Install preemption
boincYieldUPP = NewEventLoopTimerUPP(YieldProcessor);
err = InstallEventLoopTimer(GetMainEventLoop(), 0,
kEventDurationMillisecond*10, // Every 10 ms
boincYieldUPP, NULL, &boincYieldTimer);
// TODO: add an event handler for the window
ChangeWindowAttributes( appGLWindow, kWindowStandardHandlerAttribute, 0 );
SetWTitle (appGLWindow, "\pWindow");
ShowWindow(appGLWindow);
SetPortWindowPort (appGLWindow);
glInfo.fAcceleratedMust = false; // must renderer be accelerated?
glInfo.VRAM = 0 * 1048576; // minimum VRAM (if not zero this is always a required minimum)
glInfo.textureRAM = 0 * 1048576; // minimum texture RAM (if not zero this is always a required minimum)
if (!CheckMacOSX ()) // this is false on Mac OS 9 since Mac OS 9 does not support dragging conttexts with shared txtures between to different vendor's renderers.
glInfo.fDraggable = false; // should a pixel format that supports all monitors be chosen?
else
glInfo.fDraggable = true; // should a pixel format that supports all monitors be chosen?
glInfo.fmt = 0; // output pixel format
i = 0;
glInfo.aglAttributes [i++] = AGL_RGBA;
glInfo.aglAttributes [i++] = AGL_DOUBLEBUFFER;
glInfo.aglAttributes [i++] = AGL_ACCELERATED;
glInfo.aglAttributes [i++] = AGL_NO_RECOVERY;
glInfo.aglAttributes [i++] = AGL_DEPTH_SIZE;
glInfo.aglAttributes [i++] = 16;
glInfo.aglAttributes [i++] = AGL_NONE;
BuildGLFromWindow (appGLWindow, &boincAGLContext, &glInfo, NULL );
if (!boincAGLContext)
{
DestroyGLFromWindow (&boincAGLContext, &glInfo);
sprintf (boincStrContext, "No context");
}
else
{
Rect rectPort;
GetWindowPortBounds (appGLWindow, &rectPort);
aglSetCurrentContext (boincAGLContext);
aglReportError ();
aglUpdateContext (boincAGLContext);
aglReportError ();
// Set Texture mapping parameters
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glClearColor(0.15f, 0.15f, 0.15f, 1.0f); // Clear color buffer to dark grey
glClear (GL_COLOR_BUFFER_BIT);
glReportError ();
aglSwapBuffers (boincAGLContext);
aglReportError ();
aglDisable (boincAGLContext, AGL_BUFFER_RECT);
aglReportError ();
glViewport (0, 0, rectPort.right - rectPort.left, rectPort.bottom - rectPort.top);
glReportError ();
sprintf (boincStrContext, "%d x %d", rectPort.right - rectPort.left, rectPort.bottom - rectPort.top);
GetFNum("\pMonaco", &fNum); // build font
monacoFontList = BuildFontGL (boincAGLContext, fNum, normal, 9);
aglUpdateContext (boincAGLContext);
aglReportError ();
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////
// GraphicsLoopProcessor //
//////////////////////////////////////////////////////////////////////////////////
pascal void GraphicsLoopProcessor(EventLoopTimerRef inTimer, void* timeData) {
DoUpdate (boincAGLContext);
}
//////////////////////////////////////////////////////////////////////////////////
// YieldProcessor //
//////////////////////////////////////////////////////////////////////////////////
pascal void YieldProcessor(EventLoopTimerRef inTimer, void* timeData) {
YieldToAnyThread();
}
/*
if ((pWindowInfo) && (boincAGLContext))
{
GetWindowPortBounds (whichWindow, &rectTemp);
aglSetCurrentContext (boincAGLContext); // ensure the context we are working with is current
aglUpdateContext (boincAGLContext);
glViewport (0, 0, rectTemp.right - rectTemp.left, rectTemp.bottom - rectTemp.top);
sprintf (pWindowInfo->strContext, "%d x %d", rectTemp.right - rectTemp.left, rectTemp.bottom - rectTemp.top);
}
*/
//////////////////////////////////////////////////////////////////////////////////
// MainAppEventHandler //
//////////////////////////////////////////////////////////////////////////////////
pascal OSStatus MainAppEventHandler(EventHandlerCallRef appHandler, EventRef theEvent, void* appData)
{
#pragma unused (appHandler, appData)
HICommand aCommand;
OSStatus result;
Point mDelta;
switch(GetEventClass(theEvent))
{
case kEventClassMouse: // 'mous'
GetEventParameter(theEvent, // the event itself
kEventParamMouseDelta, // symbolic parameter name
typeQDPoint, // expected type
NULL, // actual type (NULL is valid)
sizeof(mDelta), // buffer size
NULL, // actual buffer size (Can be NULL)
&mDelta); // variable to hold data
switch(GetEventKind(theEvent))
{
case kEventMouseDown:
break;
case kEventMouseUp:
break;
case kEventMouseMoved:
break;
case kEventMouseDragged:
break;
case kEventMouseWheelMoved:
break;
default:
result = eventNotHandledErr;
break;
}
break;
case kEventClassCommand:
result = GetEventParameter(theEvent, kEventParamDirectObject,
typeHICommand, NULL, sizeof(HICommand),
NULL, &aCommand);
switch (aCommand.commandID)
{
case kHICommandQuit:
QuitApplicationEventLoop();
result = noErr;
break;
case kHICommandOK: // 'ok '
case kHICommandCancel: // 'not!'
case kHICommandUndo: // 'undo'
case kHICommandRedo: // 'redo'
case kHICommandCut: // 'cut '
case kHICommandCopy: // 'copy'
case kHICommandPaste: // 'past'
case kHICommandClear: // 'clea'
case kHICommandSelectAll: // 'sall'
case kHICommandHide: // 'hide'
case kHICommandZoomWindow: // 'zoom'
case kHICommandMinimizeWindow: // 'mini'
case kHICommandArrangeInFront: // 'frnt'
break;
case kHICommandAbout: // 'abou'
// Open About window
//CreateAboutWindow();
result = noErr;
break;
default:
result = eventNotHandledErr;
break;
}
break;
default:
result = eventNotHandledErr;
break;
}
return result;
}
// --------------------------------------------------------------------------
pascal void mac_graphics_event_loop ( GRAPHICS_INFO *gi ) {
InitGLWindow(gi->xsize, gi->ysize, 16);
RunApplicationEventLoop();
}
// --------------------------------------------------------------------------
void mac_cleanup (void)
{
// TODO: Dispose all the timers here
RemoveEventLoopTimer(boincTimer);
DisposeEventLoopTimerUPP(boincTimerUPP);
DisposeEventHandlerUPP(appCommandProcessor);
//DisposeGLWindow (appGLWindow);
}
// --------------------------------------------------------------------------
static void DisposeGLWindow (WindowPtr pWindow) // Dispose a single window and it's GL context
{
if (pWindow)
{
DeleteFontGL (monacoFontList);
// must clean up failure to do so will result in an Unmapped Memory Exception
DestroyGLFromWindow (&boincAGLContext, &glInfo);
DisposeWindow (pWindow);
}
}
#pragma mark -
//-----------------------------------------------------------------------------------------------------------------------
// OpenGL Drawing
void drawGL(WindowPtr pWindow)
{
static int first = 1;
static char myStr[256];
if( first ) {
gFrameWindow = 0;
gTimeWindow.hi = 0;
gTimeWindow.lo = 0;
gRotation = 0.0;
first = 0;
}
float f = 0.0;
glClearColor(0.25f, 0.25f, 0.25f, 1.0f); // Clear color buffer to dark grey
glClear(GL_COLOR_BUFFER_BIT);
gRotation += 0.5;
f = gRotation;
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glRotated (f, 0.0, 0.0, 1.0);
glEnable (GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw textured polygon
glColor3d(1.0, 0.0, 0.0);
glVertex3d(0.7, 0.7, 0.0);
glColor3d(0.0, 1.0, 0.0);
glVertex3d(-0.7, 0.7, 0.0);
glColor3d(0.0, 0.0, 1.0);
glVertex3d(-0.7, -0.7, 0.0);
glColor3d(0.7, 0.7, 0.7);
glVertex3d(0.7, -0.7, 0.0);
glEnd();
glDisable (GL_TEXTURE_2D);
// draw info
Rect rectPort;
GLint matrixMode;
GetWindowPortBounds (pWindow, &rectPort);
glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
glMatrixMode (GL_PROJECTION);
glPushMatrix();
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glLoadIdentity ();
glScalef (2.0 / (rectPort.right - rectPort.left), -2.0 / (rectPort.bottom - rectPort.top), 1.0);
glTranslatef (-(rectPort.right - rectPort.left) / 2.0, -(rectPort.bottom - rectPort.top) / 2.0, 0.0);
glColor3f (1.0, 1.0, 1.0);
glRasterPos3d (10, 12, 0);
MultiWinDrawFrameRate (monacoFontList, myStr, &gFrameWindow, &gTimeWindow);
glRasterPos3d (10, 24, 0);
DrawCStringGL (boincStrContext, monacoFontList);
glRasterPos3d (10, (rectPort.bottom - rectPort.top) - 15, 0);
DrawCStringGL ((char*) glGetString (GL_VENDOR), monacoFontList);
glRasterPos3d (10, (rectPort.bottom - rectPort.top) - 3, 0);
DrawCStringGL ((char*) glGetString (GL_RENDERER), monacoFontList);
glPopMatrix(); // GL_MODELVIEW
glMatrixMode (GL_PROJECTION);
glPopMatrix();
glMatrixMode (matrixMode);
}

33
api/mac_app_opengl.h Normal file
View File

@ -0,0 +1,33 @@
// 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):
//
#include <Carbon/Carbon.h>
#ifdef __cplusplus
extern "C" {
#endif
pascal void mac_graphics_event_loop ( GRAPHICS_INFO *gi );
pascal void GraphicsLoopProcessor(EventLoopTimerRef inTimer, void* timeData);
pascal void YieldProcessor(EventLoopTimerRef inTimer, void* timeData);
extern int InitGLWindow(int xsize, int ysize, int depth);
#ifdef __cplusplus
}
#endif

888
api/mac_carbon_dsp.c Executable file
View File

@ -0,0 +1,888 @@
// 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):
//
/*
Contains: Functions to enable building and destroying a DSp fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<3> 3/26/01 ggs Add DSp version check and other items for full screen on X
<2> 3/26/01 ggs Add new DSp functinality for Mac OS X
<1> 1/19/01 ggs Initial re-add
<7> 3/21/00 ggs Added windowed mode and clean up various implementation details
<6> 2/22/00 ggs fix fades
<5> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context checks are in
<4> 1/24/00 ggs add new disclaimer, protection from NULL dispose, better
software renderer handling
<3> 12/18/99 ggs Fixed err use before init
<2> 12/18/99 ggs Fix headers
<1> 11/28/99 ggs Initial add. Split of just DSp handling functions. Added total
device RAM checks, better step downs using actual supported
resolutions. Need to add user verify for contexts that require
it, integration of this in context step down, and a freq bit
field.
<1> 11/11/99 ggs Initial Add
Disclaimer: You may incorporate this sample code into your applications without
restriction, though the sample code has been provided "AS IS" and the
responsibility for its operation is 100% yours. However, what you are
not permitted to do is to redistribute the source as "DSC Sample Code"
after having made changes. If you're going to re-distribute the source,
we require that you make it clear in the source that the code was
descended from Apple Sample Code, but that you've made changes.
Adapted to BOINC by Eric Heien
*/
// Usage notes:
// kUseFades enables gamma fades for activates and deactivates
#define kUseFades
//kUseRAMCheck enables estimated video card RAM checks
#define kUseRAMCheck
// system includes ----------------------------------------------------------
#ifdef __APPLE_CC__
#include <Carbon/Carbon.h>
#else
#include <events.h>
#include <sound.h>
#include <fp.h>
#endif
#include <string.h>
// project includes ---------------------------------------------------------
#include "mac_carbon_dsp.h"
// globals (internal/private) -----------------------------------------------
enum
{
kMaxNumRes = 64, // max number of resolution slots
kMaxRefreshFreq = 75
};
Boolean gDSpStarted = false; // will never be true unless DSp is installed and start succeeds
Boolean gNeedFade = false;
// prototypes (internal/private) --------------------------------------------
DSpContextReference * ReserveUnusedDevices (GDHandle hGD);
OSStatus FreeUnusedDevices (GDHandle hGD, DSpContextReference ** ppContextRefUnused);
void BuildResolutionList (GDHandle hGD, Point * pResList, SInt32 * pFreqList);
OSStatus DoDeviceRAMCheck (pstructGLInfo pcontextInfo, Point * pResList, SInt32 * pFreqList, GLint depthSizeSupport);
Boolean DoContextStepDown (pstructGLInfo pcontextInfo, DSpContextAttributes * pContextAttributes, Point * pResList, SInt32 * pFreqList);
// functions (internal/private) ---------------------------------------------
// ReserveUnusedDevices
// reserves contexts on unused devices to vprevent their selection by DSp, returns list of these devices
DSpContextReference * ReserveUnusedDevices (GDHandle hGD)
{
DSpContextAttributes theContextAttributes;
DSpContextReference * pContextRefUnused = NULL;
GDHandle hDevice = DMGetFirstScreenDevice (true); // check number of screens
DisplayIDType displayID = 0;
short numDevices = 0, indexDevice = 0;
do
{
numDevices++;
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
numDevices--; // only count unused screens
if (numDevices)
{
pContextRefUnused = (DSpContextReference *) NewPtr ((long) sizeof (DSpContextReference) * numDevices);
hDevice = DMGetFirstScreenDevice (true); // check number of screens
do
{
if (hDevice != hGD) // if this device is not the one the user chose
{
if (noErr == DSpReportError (DMGetDisplayIDByGDevice (hDevice, &displayID, false)))
if (noErr == DSpReportError (DSpGetFirstContext (displayID, &pContextRefUnused [indexDevice]))) // get a context and
if (noErr == DSpReportError (DSpContext_GetAttributes (pContextRefUnused [indexDevice], &theContextAttributes))) // find attributes
DSpReportError (DSpContext_Reserve (pContextRefUnused [indexDevice], &theContextAttributes)); // reserve it
indexDevice++;
}
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
}
return pContextRefUnused;
}
// --------------------------------------------------------------------------
// FreeUnusedDevices
// frees screen that were previously reserved to prevent selection
OSStatus FreeUnusedDevices (GDHandle hGD, DSpContextReference ** ppContextRefUnused)
{
OSStatus err = noErr;
GDHandle hDevice = DMGetFirstScreenDevice (true); // check number of screens
short indexDevice = 0;
do
{
if (hDevice != hGD) // if this device is not the one the user chose
{
err = DSpContext_Release (*ppContextRefUnused [indexDevice]); // release it
DSpReportError (err);
indexDevice++;
}
hDevice = DMGetNextScreenDevice (hDevice, true);
}
while (hDevice);
if (*ppContextRefUnused)
DisposePtr ((Ptr) *ppContextRefUnused);
*ppContextRefUnused = NULL;
return err;
}
// --------------------------------------------------------------------------
// BuildResolutionList
// builds a list of supported resolutions and frequencies for GDevice
void BuildResolutionList (GDHandle hGD, Point * pResList, SInt32 * pFreqList)
{
DSpContextAttributes theContextAttributes;
DSpContextReference currContext;
OSStatus err;
DisplayIDType displayID = 0;
short i;
for (i = 0; i < kMaxNumRes; i++) // clear resolution list
{
pResList [i].h = 0x7FFF;
pResList [i].v = 0x7FFF;
pFreqList [i] = 0; // some context require certain frequencies find highest for each (not higher than 85
}
err = DMGetDisplayIDByGDevice (hGD, &displayID, true);
if (noErr != err)
ReportErrorNum ("DMGetDisplayIDByGDevice error", err);
else
{
if (noErr == DSpReportError (DSpGetFirstContext (displayID, &currContext)))
do
{
// insertion sort into resolution list
if (noErr == DSpReportError (DSpContext_GetAttributes (currContext, &theContextAttributes)))
{
Point pntTemp;
Boolean fDone = false;
short i = 0;
while ((i < kMaxNumRes) && (!fDone))
{
if ((theContextAttributes.displayWidth == pResList [i].h) && (theContextAttributes.displayHeight == pResList [i].v)) //skip
{
if ((pFreqList [i] == 0) || ((theContextAttributes.frequency <= (kMaxRefreshFreq << 16)) && (theContextAttributes.frequency > pFreqList [i])))
pFreqList [i] = theContextAttributes.frequency;
break;
}
if (theContextAttributes.displayWidth * theContextAttributes.displayHeight < pResList [i].h * pResList [i].v) //insert
{
pntTemp = pResList [i];
pResList [i].h = (short) theContextAttributes.displayWidth;
pResList [i].v = (short) theContextAttributes.displayHeight;
pFreqList [i] = theContextAttributes.frequency;
fDone = true;
}
i++;
}
// i points to next element to switch; finish array swaps (if
while ((i < kMaxNumRes) && (fDone))
{
Point pntSwitch = pResList [i];
pResList [i++] = pntTemp;
pntTemp = pntSwitch;
}
}
err = DSpGetNextContext (currContext, &currContext);
if (noErr != err)
{
if (kDSpContextNotFoundErr != err)
DSpReportError (err);
currContext = 0; // ensure we drop out
}
}
while (currContext);
else
ReportErrorNum ("DSpGetFirstContext error", err);
}
// zeroize unused elements
for (i = 0; i < kMaxNumRes; i++)
{
if ((pResList [i].h == 0x7FFF) || (pResList [i].v == 0x7FFF))
{
pResList [i].h = 0;
pResList [i].v = 0;
}
}
}
// --------------------------------------------------------------------------
// DoDeviceRAMCheck
// checks requested allocation against device RAM
// Note: may modify pcontextInfo
// this should be equal or less strigent than OpenGL actual allocation to avoid failing on valid drawables
OSStatus DoDeviceRAMCheck (pstructGLInfo pcontextInfo, Point * pResList, SInt32 * pFreqList, GLint depthSizeSupport)
{
float frontBufferFactor = 1.0f, backBufferFactor = 0.0f; // amount of screen(front) or request(back) sized buffers required, in bytes
Point pntFrontBuffer; // size of front buffer that wil be allocated
short i, indexFrontBuffer;
OSStatus err = noErr;
// must take into account the entire front buffer, so figure out what screen resolution we are really going to use
// find front buffer for request
i = 0;
while (((pResList [i].h < pcontextInfo->width) || (pResList [i].v < pcontextInfo->height)) &&
((pResList [i].h != 0) || (pResList [i].v != 0)) &&
(i < kMaxNumRes))
i++;
// save front buffer sizes
pntFrontBuffer.h = pResList [i].h;
pntFrontBuffer.v = pResList [i].v;
// if we have a valid frequnecy for the context set it (to ensure a good selection
pcontextInfo->freq = pFreqList [i] >> 16;
indexFrontBuffer = i;
// front buffers required
if (16 == pcontextInfo->pixelDepth)
frontBufferFactor *= 2.0;
else if (32 == pcontextInfo->pixelDepth)
frontBufferFactor *= 4.0;
// back buffers required
backBufferFactor = 0.0f;
i = 0;
while (64 > i)
if (AGL_DOUBLEBUFFER == pcontextInfo->aglAttributes[i++])
{
if (16 == pcontextInfo->pixelDepth)
backBufferFactor = 2.0f;
else if (32 == pcontextInfo->pixelDepth)
backBufferFactor = 4.0f;
break;
}
i = 0;
while (64 > i)
if (AGL_DEPTH_SIZE == pcontextInfo->aglAttributes[i++])
{
long requestDepth = pcontextInfo->aglAttributes[i];
GLint bit = 0x00000001;
short currDepth = 0, prevDepth = 0;
// if (depthSizeSupport)
// {
do
{
if (bit & depthSizeSupport) // if the card supports the depth
{
prevDepth = currDepth;
switch (bit)
{
case AGL_1_BIT:
currDepth = 1;
break;
case AGL_2_BIT:
currDepth = 2;
break;
case AGL_3_BIT:
currDepth = 3;
break;
case AGL_4_BIT:
currDepth = 4;
break;
case AGL_5_BIT:
currDepth = 5;
break;
case AGL_6_BIT:
currDepth = 6;
break;
case AGL_8_BIT:
currDepth = 8;
break;
case AGL_10_BIT:
currDepth = 10;
break;
case AGL_12_BIT:
currDepth = 12;
break;
case AGL_16_BIT:
currDepth = 16;
break;
case AGL_24_BIT:
currDepth = 24;
break;
case AGL_32_BIT:
currDepth = 32;
break;
case AGL_48_BIT:
currDepth = 48;
break;
case AGL_64_BIT:
currDepth = 64;
break;
case AGL_96_BIT:
currDepth = 96;
break;
case AGL_128_BIT:
currDepth = 128;
break;
}
}
bit *= 2;
} while (!((requestDepth > prevDepth) && (requestDepth <= currDepth)) && (bit < AGL_128_BIT + 1));
// }
// else // no card depth support info
// currDepth = requestDepth; // we don't have card info thus assume we can support exact depth requested (may fail later but will always be equal or less stringent)
if ((AGL_128_BIT >= bit) && (0 != currDepth))
backBufferFactor += (float) currDepth / 8.0;
break;
}
// What we now have:
// pcontextInfo->width, height: request width and height
// pResList: sorted list of resolutions supported on this display
// pntFrontBuffer : size of front buffer that will currently be allocated
// indexFrontBuffer: position in array of current front buffer request
// frontBufferFactor: number of screen resolution size buffers that will be needed
// backBufferFactor: number of request size buffers that will be needed
// if we see zero VRAM here we must be looking at the software renderer thus this check is moot.
if (pcontextInfo->VRAM == 0)
{
// no changes required
return noErr;
}
// find a context size that can support our texture requirements in the current total VRAM
if ((pcontextInfo->VRAM - pcontextInfo->textureRAM) < (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor +
pcontextInfo->width * pcontextInfo->height * backBufferFactor))
{
if (pcontextInfo->fDepthMust && pcontextInfo->fSizeMust)
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures (depth buffer and pixel size must be as requested)");
return err;
}
else if (pcontextInfo->fSizeMust) // if we can adjust the size, try adjusting the
{
// try 16 bit if must size is true
if ((pcontextInfo->pixelDepth > 16) &&
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor / 2.0 +
pcontextInfo->width * pcontextInfo->height * (backBufferFactor - 2.0)))
pcontextInfo->pixelDepth = 16;
else
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures");
return err;
}
}
else // can adjust size and might be able to adjust depth
{ // make drawable fit
Boolean fFound = false;
// see if we can just adjust the pixel depth
if ((pcontextInfo->pixelDepth > 16) && // if we are requesting 32 bit
(!pcontextInfo->fDepthMust) && // if we can adjust the pixel depth
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pntFrontBuffer.h * pntFrontBuffer.v * frontBufferFactor / 2.0 +
pcontextInfo->width * pcontextInfo->height * (backBufferFactor - 2.0)))
{
fFound = true;
pcontextInfo->pixelDepth = 16;
}
else // pixel depth alone wont do it
{
i = (short) (indexFrontBuffer - 1);
while (i >= 0)
{
//
if ((pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pResList [i].h * pResList [i].v * frontBufferFactor +
pResList [i].h * pResList [i].v * backBufferFactor))
{
fFound = true;
pcontextInfo->width = pResList [i].h;
pcontextInfo->height = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
break;
}
else if ((pcontextInfo->pixelDepth > 16) && // if we are requesting 32 bit
(!pcontextInfo->fDepthMust) && // if we can adjust the pixel depth
(pcontextInfo->VRAM - pcontextInfo->textureRAM) > (pResList [i].h * pResList [i].v * frontBufferFactor / 2.0 +
pResList [i].h * pResList [i].v * (backBufferFactor - 2.0)))
{
fFound = true;
pcontextInfo->width = pResList [i].h;
pcontextInfo->height = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
pcontextInfo->pixelDepth = 16;
break;
}
i--;
}
// we tried the smallest screen size and still need to use less VRAM, adjust backbuffer to what is available
if ((!fFound) && (((pcontextInfo->VRAM - pcontextInfo->textureRAM) - pResList [0].h * pResList [0].v * frontBufferFactor) > 0))
{
float factor;
fFound = true;
factor = (float) sqrt((float) (pcontextInfo->width * pcontextInfo->height * backBufferFactor) /
(float) ((pcontextInfo->VRAM - pcontextInfo->textureRAM) - pResList [0].h * pResList [0].v * frontBufferFactor));
pcontextInfo->width /= factor;
pcontextInfo->height /= factor;
pcontextInfo->freq = pFreqList [0] >> 16;
}
}
if (!fFound)
{
// cannot accomdate request
ReportError ("Not enough total VRAM for drawable and textures");
return err;
}
}
}
return noErr;
}
// --------------------------------------------------------------------------
// DoContextStepDown
// steps down through frequencies, depths and sizes to try to find a valid context
// bounded by flags for SizeMust and DepthMust
// Note: may modify pcontextInfo
Boolean DoContextStepDown (pstructGLInfo pcontextInfo, DSpContextAttributes * pContextAttributes, Point * pResList, SInt32 * pFreqList)
{
// find current resolution
short i = 0;
while (((pResList [i].h <= pContextAttributes->displayWidth) || (pResList [i].v <= pContextAttributes->displayHeight)) &&
((pResList [i].h != 0) || (pResList [i].v != 0)) &&
(i < kMaxNumRes))
i++;
i--; // i points to index of current resolution
if (pcontextInfo->fSizeMust) // adjust depth only
{
if (pcontextInfo->pixelDepth > 16) // also try pixel depth step down
{
pContextAttributes->displayBestDepth = 16;
pContextAttributes->backBufferBestDepth = 16;
}
else
return false; // no more options to try
}
else if (pcontextInfo->fDepthMust) // adjust size only
{
if (i > 0)
{
i--; // i was pointing at current resolution, now it is pointing at new resolution to try
// set new resolution
pContextAttributes->displayWidth = pResList [i].h;
pContextAttributes->displayHeight = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
}
else
return false;
}
else // adjust size and depth
{
if (pContextAttributes->displayBestDepth > 16)
{
pContextAttributes->displayBestDepth = 16;
pContextAttributes->backBufferBestDepth = 16;
}
else if (i > 0)
{
i--; // i was pointing at current resolution, now it is pointing at new resolution to try
// reset pixel depth
pContextAttributes->displayBestDepth = pcontextInfo->pixelDepth;
pContextAttributes->backBufferBestDepth = pcontextInfo->pixelDepth;
// set new resolution
pContextAttributes->displayWidth = pResList [i].h;
pContextAttributes->displayHeight = pResList [i].v;
pcontextInfo->freq = pFreqList [i] >> 16;
}
else
return false;
}
return true;
}
#pragma mark -
// functions (public) -------------------------------------------------------
// GetDSpVersion
// Gets the current version of DSp
NumVersion GetDSpVersion (void)
{
NumVersion versionDSp = { 0, 0, 0, 0 };
OSStatus err = noErr;
if (!gDSpStarted)
err = StartDSp ();
if (noErr == err)
versionDSp = DSpGetVersion ();
return versionDSp;
}
// --------------------------------------------------------------------------
// StartDSp
// handles starting up DrawSprocket
OSStatus StartDSp (void)
{
OSStatus err = noErr;
if (!gDSpStarted)
{
// check for DSp
if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) DSpStartup)
{
ReportError ("DSp not installed");
return kDSpNotInitializedErr;
}
else
{
err = DSpReportError (DSpStartup()); // start DSp
if (noErr != err)
return err;
else
gDSpStarted = true;
}
}
return err;
}
// --------------------------------------------------------------------------
// ShutdownDSpContext
// shuts down DrawSprocket
void ShutdownDSp (void)
{
if (gDSpStarted)
{
DSpShutdown ();
gDSpStarted = false;
}
}
#pragma mark -
// --------------------------------------------------------------------------
// GetDSpDrawable
// Just returns the front buffer
// Inputs: *pdspContext
// pcontextInfo: request and requirements for cotext and drawable
// Outputs: returns CGrafPtr thaat is front buffer of context
// if error: will return NULL
CGrafPtr GetDSpDrawable (DSpContextReference dspContext)
{
CGrafPtr pCGraf = NULL;
if (noErr == DSpReportError (DSpContext_GetFrontBuffer (dspContext, &pCGraf)))
return pCGraf;
else
return NULL;
}
// --------------------------------------------------------------------------
// BuildDSpContext
// contextInfo and tries to allocate the corresponding DSp context
// Inputs: hGD: GDHandle to device to look at
// pcontextInfo: request and requirements for cotext and drawable
// Outputs: *pdspContext as allocated
// pcontextInfo: allocated parameters
// if fail to allocate: pdspContext will be NULL
// if error: will return error pdspContext will be NULL
OSStatus BuildDSpContext (DSpContextReference* pdspContext, GDHandle hGD, GLint depthSizeSupport, pstructGLInfo pcontextInfo)
{
DSpContextAttributes theContextAttributes, foundAttributes;
DSpContextReference * pContextRefUnused;
SInt32 aFreqList [kMaxNumRes];
Point aResList [kMaxNumRes]; // list for resolution information
OSStatus err = noErr;
*pdspContext = 0;
// check for DSp
if (noErr != StartDSp ())
{
ReportError ("DSp startup failed");
return noErr; // already reported
}
// reserve contexts on other screens to prevent their selection
pContextRefUnused = ReserveUnusedDevices (hGD);
// build resolution list
BuildResolutionList (hGD, aResList, aFreqList);
// handle default pixel depths
if (pcontextInfo->pixelDepth == 0) // default
{
pcontextInfo->pixelDepth = (**(**hGD).gdPMap).pixelSize;
if (pcontextInfo->pixelDepth < 16)
pcontextInfo->pixelDepth = 16;
}
#ifdef kUseRAMCheck
if (noErr != DoDeviceRAMCheck (pcontextInfo, aResList, aFreqList, depthSizeSupport))
return err;
#endif // kUseRAMCheck
// Note: DSp < 1.7.3 REQUIRES the back buffer attributes even if only one buffer is required
BlockZero (&theContextAttributes, sizeof (DSpContextAttributes));
// memset(&theContextAttributes, 0, sizeof (DSpContextAttributes));
theContextAttributes.displayWidth = pcontextInfo->width;
theContextAttributes.displayHeight = pcontextInfo->height;
theContextAttributes.displayBestDepth = pcontextInfo->pixelDepth;
theContextAttributes.backBufferBestDepth = pcontextInfo->pixelDepth;
do
{
theContextAttributes.frequency = pcontextInfo->freq * 0x10000;
theContextAttributes.colorNeeds = kDSpColorNeeds_Require;
theContextAttributes.displayDepthMask = kDSpDepthMask_All;
theContextAttributes.backBufferDepthMask = kDSpDepthMask_All;
theContextAttributes.pageCount = 1; // only the front buffer is needed
err = DSpFindBestContext(&theContextAttributes, pdspContext);
if (noErr != err) // if we had any errors, reset for next try
if (!DoContextStepDown (pcontextInfo, &theContextAttributes, aResList, aFreqList))
break; // have run out of options
} while (err == kDSpContextNotFoundErr);
// check find best context errors
if (kDSpContextNotFoundErr == err)
{
*pdspContext = 0;
return noErr;
}
else if (noErr != err)
{
DSpReportError (err);
*pdspContext = 0;
return err;
}
err = DSpReportError (DSpContext_GetAttributes (*pdspContext, &foundAttributes));
if (noErr != err)
{
*pdspContext = 0;
return err;
}
// reset width and height to full screen and handle our own centering
// HWA will not correctly center less than full screen size contexts
theContextAttributes.displayWidth = foundAttributes.displayWidth;
theContextAttributes.displayHeight = foundAttributes.displayHeight;
theContextAttributes.pageCount = 1; // only the front buffer is needed
theContextAttributes.contextOptions = 0 | kDSpContextOption_DontSyncVBL; // no page flipping and no VBL sync needed
err = DSpReportError (DSpContext_Reserve(*pdspContext, &theContextAttributes )); // reserve our context
if (noErr != err)
{
*pdspContext = 0;
return err;
}
if (gNeedFade == true)
{
DSpReportError (DSpContext_CustomFadeGammaOut (NULL, NULL, fadeTicks));
gNeedFade = false;
}
err = DSpReportError (DSpContext_SetState (*pdspContext, kDSpContextState_Active)); // activate our context
if (noErr != err)
{
DSpContext_Release (*pdspContext);
DSpReportError (DSpContext_CustomFadeGammaIn (NULL, NULL, fadeTicks));
*pdspContext = 0;
return err;
}
FreeUnusedDevices (hGD, &pContextRefUnused);
if (!pcontextInfo->fSizeMust) // if we got whatever was available
{
// reset inputs to what was allocated (constrain aspect ratio)
// unless we ask for smaller, then leave the same
if ((pcontextInfo->width > foundAttributes.displayWidth) || (pcontextInfo->height > foundAttributes.displayHeight))
{
float hFactor = (float) pcontextInfo->width / (float) foundAttributes.displayWidth;
float vFactor = (float) pcontextInfo->height / (float) foundAttributes.displayHeight;
if (hFactor > vFactor)
{
pcontextInfo->width = (short) foundAttributes.displayWidth;
pcontextInfo->height /= hFactor;
}
else
{
pcontextInfo->height = (short) foundAttributes.displayHeight;
pcontextInfo->width /= vFactor;
}
}
}
// else still use inputs to allocate drawable
pcontextInfo->freq = foundAttributes.frequency / 0x10000;
pcontextInfo->pixelDepth = foundAttributes.displayBestDepth;
return noErr;
}
//-----------------------------------------------------------------------------------------------------------------------
// Deactivates and dumps context
void DestroyDSpContext (DSpContextReference* pdspContext)
{
if (gDSpStarted)
{
if (*pdspContext)
{
DSpReportError (DSpContext_SetState(*pdspContext, kDSpContextState_Inactive));
DSpReportError (DSpContext_CustomFadeGammaIn (NULL, NULL, fadeTicks));
DSpReportError (DSpContext_Release (*pdspContext));
*pdspContext = NULL;
}
}
}
#pragma mark -
//-----------------------------------------------------------------------------------------------------------------------
OSStatus DSpContext_CustomFadeGammaIn (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks)
{
OSStatus err = noErr;
#ifndef kUseFades
#pragma unused (inContext, fadeColor, fadeTicks)
#else
RGBColor inZeroIntensityColor;
UInt32 currTick;
UInt16 step = (UInt16) (800 / fadeTicks);
long x, percent = 0;
if (gDSpStarted)
{
if (fadeTicks == 0)
fadeTicks = 1;
if (fadeColor == NULL)
{
inZeroIntensityColor.red = 0x0000;
inZeroIntensityColor.green = 0x0000;
inZeroIntensityColor.blue = 0x0000;
}
else
inZeroIntensityColor = *fadeColor;
currTick = TickCount ();
for (x = 1; x <= fadeTicks; x++)
{
percent = step * x / 8;
err = DSpContext_FadeGamma(inContext, percent, &inZeroIntensityColor);
if (err != noErr)
break;
while (currTick >= TickCount ()) {}
// SystemTask ();
currTick = TickCount ();
}
if (err == noErr)
err = DSpContext_FadeGamma(inContext, 100, &inZeroIntensityColor);
}
#endif // kUseFades
return err;
}
//-----------------------------------------------------------------------------------------------------------------------
OSStatus DSpContext_CustomFadeGammaOut (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks )
{
OSStatus err = noErr;
#ifndef kUseFades
#pragma unused (inContext, fadeColor, fadeTicks)
#else
RGBColor inZeroIntensityColor;
UInt32 currTick;
UInt16 step = (UInt16) (800 / fadeTicks);
long x, percent = 0;
if (gDSpStarted)
{
if (fadeTicks == 0)
fadeTicks = 1; // ensure we do not have zero fade time
if (fadeColor == NULL)
{
inZeroIntensityColor.red = 0x0000;
inZeroIntensityColor.green = 0x0000;
inZeroIntensityColor.blue = 0x0000;
}
else
inZeroIntensityColor = *fadeColor;
currTick = TickCount ();
for (x = fadeTicks - 1; x >= 0; x--)
{
percent = step * x / 8;
err = DSpContext_FadeGamma(inContext, percent, &inZeroIntensityColor);
if (err != noErr)
break;
while (currTick >= TickCount ()) {}
// SystemTask ();
currTick = TickCount ();
}
}
#endif // kUseFades
return err;
}

128
api/mac_carbon_dsp.h Executable file
View File

@ -0,0 +1,128 @@
// 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):
//
/*
Contains: Functions to enable building and destorying a DSp fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<2> 3/26/01 ggs Add DSp version check and other items for full screen on X
<1> 1/19/01 ggs Initial re-add
<4> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context checks are in
<3> 1/24/00 ggs Add C++ support
<2> 12/18/99 ggs Fix headers
<1> 11/28/99 ggs Initial add. Split of just DSp handling functions. Added total
device RAM checks, better step downs using actual supported
resolutions. Need to add user verify for contexts that require
it, integration of this in context step down, and a freq bit
field.
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Adapted to BOINC by Eric Heien
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef SetupDSp_h
#define SetupDSp_h
// includes ---------------------------------------------------------
#ifdef __APPLE_CC__
#include <DrawSprocket/DrawSprocket.h>
#else
#include <DrawSprocket.h>
#endif
#include "mac_carbon_gl.h"
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
enum { fadeTicks = 10 };
// public function declarations -------------------------------------
NumVersion GetDSpVersion (void);
OSStatus StartDSp (void);
void ShutdownDSp (void);
CGrafPtr GetDSpDrawable (DSpContextReference dspContext);
OSStatus BuildDSpContext (DSpContextReference* pdspContext, GDHandle hGD, GLint depthSizeSupport, pstructGLInfo pcontextInfo);
void DestroyDSpContext (DSpContextReference* pdspContext);
OSStatus DSpContext_CustomFadeGammaOut (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks);
OSStatus DSpContext_CustomFadeGammaIn (DSpContextReference inContext, const RGBColor *fadeColor, long fadeTicks);
extern Boolean gDSpStarted;
extern Boolean gNeedFade;
#ifdef __cplusplus
}
#endif
#endif // SetupDSp_h

1379
api/mac_carbon_gl.c Executable file

File diff suppressed because it is too large Load Diff

243
api/mac_carbon_gl.h Executable file
View File

@ -0,0 +1,243 @@
// 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):
//
/*
Contains: Functions to enable build and destory a GL fullscreen context
Written by: Geoff Stahl (ggs)
Copyright: Copyright © 1999 Apple Computer, Inc., All Rights Reserved
Change History (most recent first):
<2> 3/26/01 ggs Add DSp version check and other items for full screen on X
<1> 1/19/01 ggs Initial re-add
<7> 3/21/00 ggs Added windowed mode and clean up various implementation details
<6> 1/26/00 ggs Add fade code back in, ensure NULL pointer/context/drawable
checks are in, add Preflight
<5> 1/24/00 ggs Added get device num and get gdhandle from point routines, add
support for compiling from C++
<4> 12/18/99 ggs Fix headers
<3> 11/28/99 ggs Split out DSp and error handling. Added texture memory
considerations, assume VRAM is required if other than zero
<3> 11/12/99 ggs add pixel format and freq return
<2> 11/12/99 ggs 1.0 Interface complete
<1> 11/11/99 ggs Initial Add
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Adapted to BOINC by Eric Heien
*/
// Usage notes:
// include control --------------------------------------------------
#ifndef SetupGL_h
#define SetupGL_h
// includes ---------------------------------------------------------
#ifdef __APPLE_CC__
#include <DrawSprocket/DrawSprocket.h>
#include <AGL/agl.h>
#else
#include <DrawSprocket.h>
#include <agl.h>
#include <gl.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// structures (public) -----------------------------------------------
// structure for creating a fullscreen context
struct structGLInfo // storage for setup info
{
SInt16 width; // input: width of drawable (screen width in full screen mode), return: actual width allocated
SInt16 height; // input: height of drawable (screen height in full screen mode), return: actual height allocated
Boolean fSizeMust; // input: dspContext must be requested display size (ignored in window mode)
// if fSizeMust display size will not be stepped down to try to find a match,
// if display is stepped down aspect ratio will be maintained for returned size
UInt32 pixelDepth; // input: requested pixel depth
Boolean fDepthMust; // input: pixel depth must be set (if false then current depth will be used if able)
Boolean fFullscreen; // input: use DSp to get fullscreen? (or find full screen renderer)
// if fFullscreen, will search for full screen renderers first then use DSp for others
// unless a device is specified, in which case we will try there first
Boolean fAcceleratedMust; // input: must renderer be accelerated?
GLint aglAttributes[64]; // input: pixel format attributes always required (reset to what was actually allocated)
SInt32 VRAM; // input: minimum VRAM; output: actual (if successful otherwise input)
SInt32 textureRAM; // input: amount of texture RAM required on card; output: same (used in allcoation to ensure enough texture
AGLPixelFormat fmt; // input: none; output pixel format...
SInt32 freq; // input: frequency request for display; output: actual
};
typedef struct structGLInfo structGLInfo;
typedef struct structGLInfo * pstructGLInfo;
// structure for creating a context from a window
struct structGLWindowInfo // storage for setup info
{
Boolean fAcceleratedMust; // input: must renderer be accelerated?
GLint aglAttributes[64]; // input: pixel format attributes always required (reset to what was actually allocated)
SInt32 VRAM; // input: minimum VRAM; output: actual (if successful otherwise input)
SInt32 textureRAM; // input: amount of texture RAM required on card; output: same (used in allcoation to ensure enough texture
AGLPixelFormat fmt; // input: none; output pixel format...
Boolean fDraggable; // input: is window going to be dragable,
// if so renderer check (accel, VRAM, textureRAM) will look at all renderers vice just the current one
// if window is not dragable renderer check will either check the single device or short
// circuit to software if window spans multiple devices
// software renderer is consider to have unlimited VRAM, unlimited textureRAM and to not be accelerated
};
typedef struct structGLWindowInfo structGLWindowInfo;
typedef struct structGLWindowInfo * pstructGLWindowInfo;
// public function declarations -------------------------------------
// Runtime check to see if we are running on Mac OS X
// Inputs: None
// Returns: 0 if < Mac OS X or version number of Mac OS X (10.0 for GM)
UInt32 CheckMacOSX (void);
// Checks for presense of OpenGL and DSp (if required)
// Inputs: checkFullscreen: true if one wants to run fullscreen (which requires DrwSprocket currently)
// Ouputs: true if OpenGL is installed (and DrawSprocket if checkFullscreen is true
Boolean PreflightGL (Boolean checkFullscreen);
// Takes device # and geometry request and tries to build best context and drawable
// If requested device does not work, will start at first device and walk down devices
// looking for first one that satisfies requirments
// Devices are numbered in order that DMGetFirstScreenDevice/DMGetNextScreenDevice returns,
// fullscreen devices are numbered after this, but they will be searched first if fFullscreen == true,
// they will not be searched in the non-fullscreen case
// Inputs: *pnumDevice: -1: main device, 0: any device, other #: attempt that device first, then any device
// *pcontextInfo: request and requirements for cotext and drawable
// Outputs: *paglDraw, *paglContext and *pdspContext as allocated
// *pnumDevice to device number in list that was used
// *pcontextInfo: allocated parameters
// If fail to build context: paglDraw, paglContext and pdspContext will be NULL
// If fatal error: will return error and paglDraw, paglContext and pdspContext will be NULL
// Note: Errors can be generated internally when a specific device fails, this is normal and these
// will not be returned is a subsequent device succeeds
OSStatus BuildGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext,
short* pnumDevice, pstructGLInfo pcontextInfo, AGLContext aglShareContext);
// Destroys drawable and context
// Ouputs: *paglDraw, *paglContext and *pdspContext should be 0 on exit
OSStatus DestroyGL (AGLDrawable* paglDraw, AGLContext* paglContext, DSpContextReference* pdspContext, pstructGLInfo pcontextInfo);
// same as above except that it takes a window as input and attempts to build requested conext on that
OSStatus BuildGLFromWindow (WindowPtr pWindow, AGLContext* paglContext, pstructGLWindowInfo pcontextInfo, AGLContext aglShareContext);
// same as above but destorys a context that was associated with an existing window, window is left intacted
OSStatus DestroyGLFromWindow (AGLContext* paglContext, pstructGLWindowInfo pcontextInfo);
// Special suspend function to ensure the the GL window is hidden
OSStatus SuspendFullScreenGL (AGLDrawable aglDraw, AGLContext aglContext);
// Special resume function to ensure the the GL window is shown
OSStatus ResumeFullScreenGL (AGLDrawable aglDraw, AGLContext aglContext);
// Pauses gl to allow toolbox drawing
OSStatus PauseGL (AGLContext aglContext);
// resumes gl to allow gl drawing
OSStatus ResumeGL (AGLContext aglContext);
short FindGDHandleFromRect (Rect * pRect, GDHandle * phgdOnThisDevice);
short FindGDHandleFromWindow (WindowPtr pWindow, GDHandle * phgdOnThisDevice);
// returns the number of the device that the rect is mostly is on (i.e., where it is numerically in the search order)
short FindDeviceNumFromRect (Rect * rect);
void MultiWinDrawFrameRate (GLuint fontList, char * cString, long * frames, AbsoluteTime * time);
void DrawCStringGL (char * cstrOut, GLuint fontList);
GLuint BuildFontGL (AGLContext ctx, GLint fontID, Style face, GLint size);
void DeleteFontGL (GLuint fontList);
// Error reporter, can be set to report however the application desires
void ReportError (char * strError);
// Error with numeric code reporter, can be set to report however the application desires
void ReportErrorNum (char * strError, long numError);
// Handle reporting of DSp errors, error code is passed through
OSStatus DSpReportError (OSStatus error);
// Handle reporting of agl errors, error code is passed through
OSStatus aglReportError (void);
// Handle reporting of OpenGL errors, error code is passed through
OSStatus glReportError (void);
void DoUpdate (AGLContext aglContext);
#ifdef __cplusplus
}
#endif
#endif // SetupGL_h

View File

@ -2128,3 +2128,15 @@ Eric October 13, 2002
file_names.C
scheduler_op.C
Eric October 14, 2002
- Added initial support for Mac OpenGL graphics, still needs to
be polished and tested (particularly multithreaded aspect)
api/
mac_app_opengl.c,h
mac_carbon_dsp.c,h
mac_carbon_gl.c,h
mac_build/
boinc.pbproj/
project.pbxproj

View File

@ -201,7 +201,7 @@
INSTALL_PATH = "$(HOME)/Applications";
LIBRARY_SEARCH_PATHS = "";
OPTIMIZATION_CFLAGS = "-O0";
OTHER_CFLAGS = "-DHOSTTYPE=\\\\\\\"MacOSX\\\\\\\" -DHOST=\\\\\\\"MacOSX\\\\\\\" -DVERSION=1 -Dmac -DHAVE_SYS_SOCKET_H -DHAVE_SYS_RESOURCE_H -DHAVE_NETDB_H -DHAVE_UNISTD_H -DHAVE_SYS_WAIT_H -DHAVE_NETINET_IN_H -DHAVE_SIGNAL_H -DHAVE_ARPA_INET_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H -DHAVE_DIRENT_H -DHAVE_FCNTL_H -DHAVE_SYS_STAT_H";
OTHER_CFLAGS = "-DHOSTTYPE=\\\\\\\"MacOSX\\\\\\\" -DHOST=\\\\\\\"MacOSX\\\\\\\" -DVERSION=1 -Dmac -DHAVE_SYS_SOCKET_H -DHAVE_SYS_RESOURCE_H -DHAVE_NETDB_H -DHAVE_UNISTD_H -DHAVE_SYS_WAIT_H -DHAVE_NETINET_IN_H -DHAVE_SIGNAL_H -DHAVE_ARPA_INET_H -DHAVE_SYS_TIME_H -DHAVE_SYS_TYPES_H -DHAVE_DIRENT_H -DHAVE_FCNTL_H -DHAVE_SYS_STAT_H -DHAVE_SYS_SYSCTL_H -DHAVE_SYS_MOUNT_H -DHAVE_SYS_VMMETER_H";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = BOINC;
@ -322,7 +322,6 @@
F54B900A02AC0A0D01FB7237,
F54B900B02AC0A0D01FB7237,
F54B900C02AC0A0D01FB7237,
F54B900D02AC0A0D01FB7237,
F54B900E02AC0A0D01FB7237,
F54B900F02AC0A0D01FB7237,
F54B901002AC0A0D01FB7237,
@ -1147,7 +1146,6 @@
F54B8FD502AC0A0C01FB7237,
F54B8FD602AC0A0C01FB7237,
F54B8FD702AC0A0C01FB7237,
F54B8FD802AC0A0C01FB7237,
F54B8FD902AC0A0C01FB7237,
F54B8FDA02AC0A0C01FB7237,
F54B8FDB02AC0A0C01FB7237,
@ -1291,12 +1289,6 @@
path = ../client/log_flags.h;
refType = 2;
};
F54B8FD802AC0A0C01FB7237 = {
isa = PBXFileReference;
name = main.C;
path = ../client/main.C;
refType = 2;
};
F54B8FD902AC0A0C01FB7237 = {
isa = PBXFileReference;
name = message.h;
@ -1543,12 +1535,6 @@
settings = {
};
};
F54B900D02AC0A0D01FB7237 = {
fileRef = F54B8FD802AC0A0C01FB7237;
isa = PBXBuildFile;
settings = {
};
};
F54B900E02AC0A0D01FB7237 = {
fileRef = F54B8FDA02AC0A0C01FB7237;
isa = PBXBuildFile;
@ -1778,6 +1764,12 @@
};
F54FF8B6029F2FFC012012A7 = {
children = (
F579BDAB0357F389012012A7,
F579BDAC0357F389012012A7,
F5895D8F0359FDD6012012A7,
F5895D920359FDD6012012A7,
F5895D900359FDD6012012A7,
F5895D910359FDD6012012A7,
F59DD6F7032FF0AF01A80164,
F59DD6F6032FF0AF01A80164,
F5E946F303269BE2012012A7,
@ -1804,7 +1796,7 @@
);
buildSettings = {
LIBRARY_SEARCH_PATHS = /usr/lib/gcc/darwin/3.1;
OTHER_CFLAGS = "-Dunix -Dmac -DHAVE_DIRENT_H -DBOINC_APP_GRAPHICS";
OTHER_CFLAGS = "-Dunix -Dmac -DHAVE_DIRENT_H -DHAVE_SYS_RESOURCE_H -DHAVE_UNISTD_H -DHAVE_SIGNAL_H -DHAVE_SYS_TIME_H -DBOINC_APP_GRAPHICS";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = upper_case;
@ -1854,10 +1846,13 @@
buildActionMask = 2147483647;
files = (
F5BFEB8F02D1137F012012A7,
F5E946F803269BEF012012A7,
F5E946FA03269BF0012012A7,
F5E946FD03269BF3012012A7,
F59DD6FA032FF0AF01A80164,
F579BDAD0357F389012012A7,
F5895D930359FDD6012012A7,
F5895D940359FDD6012012A7,
F5895D9A035A2BEC012012A7,
F5895D9C035A2BEE012012A7,
);
isa = PBXHeadersBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -1875,10 +1870,13 @@
F54FF8C2029F304E012012A7,
F5BFEB9002D1137F012012A7,
F5E946F503269BE2012012A7,
F5E946F703269BEE012012A7,
F5E946F903269BF0012012A7,
F5E946FB03269BF2012012A7,
F59DD6FB032FF0AF01A80164,
F579BDAE0357F389012012A7,
F5895D950359FDD6012012A7,
F5895D960359FDD6012012A7,
F5895D99035A2BEC012012A7,
F5895D9B035A2BEE012012A7,
);
isa = PBXSourcesBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -1895,6 +1893,8 @@
F59DD6FE0330029E01A80164,
F5C932E2033257FD01A80164,
F5C932E30332580901A80164,
F5895D6503591C6A012012A7,
F5895D6603591C70012012A7,
);
isa = PBXFrameworksBuildPhase;
runOnlyForDeploymentPostprocessing = 0;
@ -1930,6 +1930,114 @@
settings = {
};
};
F579BDAB0357F389012012A7 = {
isa = PBXFileReference;
name = mac_app_opengl.h;
path = ../api/mac_app_opengl.h;
refType = 2;
};
F579BDAC0357F389012012A7 = {
isa = PBXFileReference;
name = mac_app_opengl.c;
path = ../api/mac_app_opengl.c;
refType = 2;
};
F579BDAD0357F389012012A7 = {
fileRef = F579BDAB0357F389012012A7;
isa = PBXBuildFile;
settings = {
};
};
F579BDAE0357F389012012A7 = {
fileRef = F579BDAC0357F389012012A7;
isa = PBXBuildFile;
settings = {
};
};
F5895D6503591C6A012012A7 = {
fileRef = F5C5402002BFA6C601BEDAB8;
isa = PBXBuildFile;
settings = {
};
};
F5895D6603591C70012012A7 = {
fileRef = F5C5401F02BFA6C601BEDAB8;
isa = PBXBuildFile;
settings = {
};
};
F5895D8F0359FDD6012012A7 = {
isa = PBXFileReference;
name = mac_carbon_dsp.h;
path = ../api/mac_carbon_dsp.h;
refType = 2;
};
F5895D900359FDD6012012A7 = {
isa = PBXFileReference;
name = mac_carbon_gl.h;
path = ../api/mac_carbon_gl.h;
refType = 2;
};
F5895D910359FDD6012012A7 = {
isa = PBXFileReference;
name = mac_carbon_gl.c;
path = ../api/mac_carbon_gl.c;
refType = 2;
};
F5895D920359FDD6012012A7 = {
isa = PBXFileReference;
name = mac_carbon_dsp.c;
path = ../api/mac_carbon_dsp.c;
refType = 2;
};
F5895D930359FDD6012012A7 = {
fileRef = F5895D8F0359FDD6012012A7;
isa = PBXBuildFile;
settings = {
};
};
F5895D940359FDD6012012A7 = {
fileRef = F5895D900359FDD6012012A7;
isa = PBXBuildFile;
settings = {
};
};
F5895D950359FDD6012012A7 = {
fileRef = F5895D910359FDD6012012A7;
isa = PBXBuildFile;
settings = {
};
};
F5895D960359FDD6012012A7 = {
fileRef = F5895D920359FDD6012012A7;
isa = PBXBuildFile;
settings = {
};
};
F5895D99035A2BEC012012A7 = {
fileRef = F5EAD479031AF001018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5895D9A035A2BEC012012A7 = {
fileRef = F5EAD478031AF001018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5895D9B035A2BEE012012A7 = {
fileRef = F5EAD475031AEFF8018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5895D9C035A2BEE012012A7 = {
fileRef = F5EAD474031AEFF8018E201A;
isa = PBXBuildFile;
settings = {
};
};
F59DD6F6032FF0AF01A80164 = {
isa = PBXFileReference;
path = graphics_api.h;
@ -2124,18 +2232,6 @@
settings = {
};
};
F5E946F703269BEE012012A7 = {
fileRef = F5EAD479031AF001018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5E946F803269BEF012012A7 = {
fileRef = F5EAD478031AF001018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5E946F903269BF0012012A7 = {
fileRef = F5755AD302FE063A012012A7;
isa = PBXBuildFile;
@ -2148,18 +2244,6 @@
settings = {
};
};
F5E946FB03269BF2012012A7 = {
fileRef = F5EAD475031AEFF8018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5E946FD03269BF3012012A7 = {
fileRef = F5EAD474031AEFF8018E201A;
isa = PBXBuildFile;
settings = {
};
};
F5EAD474031AEFF8018E201A = {
isa = PBXFileReference;
name = filesys.h;