renderspu_agl.c revision aeb7d3465f6e399a9719a21364e9a483302102df
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include <stdio.h>
#include "cr_environment.h"
#include "cr_error.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "renderspu.h"
/* Some necessary global defines */
uint64_t gDockUpdateTS = 0;
enum
{
/* Event classes */
kEventClassVBox = 'vbox',
/* Event kinds */
kEventVBoxShowWindow = 'swin',
kEventVBoxHideWindow = 'hwin',
kEventVBoxMoveWindow = 'mwin',
kEventVBoxResizeWindow = 'rwin',
kEventVBoxDisposeWindow = 'dwin',
kEventVBoxUpdateDock = 'udck',
kEventVBoxUpdateContext = 'uctx'
};
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
# define renderspuSetWindowContext(w, c) \
# define renderspuGetWindowContext(w) \
#else
# define renderspuSetWindowContext(w, c) \
( SetWRefCon( (w), (unsigned long) (c) ) )
# define renderspuGetWindowContext(w) \
#endif
/* Debug macros */
#ifdef DEBUG_poetzsch
#define DEBUG_MSG_POETZSCH(text) \
#else
#define DEBUG_MSG_POETZSCH(text) \
do {} while (0)
#endif
{ \
return ret; \
}
if(!(result)) \
{ \
}
/* Window event handler */
{
/*
Rect rectPort = { 0, 0, 0, 0 };
if( window )
GetWindowPortBounds( window, &rectPort );
*/
switch (class)
{
case kEventClassWindow:
{
switch (kind)
{
#ifndef __LP64__ /* not available for 64-bit processes? */
case kEventWindowDrawContent:
{
break;
}
#endif
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to cehck if this event is generated or not (it probably isn't). */
case kEventWindowShown:
{
//InvalWindowRect( window, &rectPort );
break;
}
#endif
{
if (context &&
{
//result = render_spu.ws.aglSetCurrentContext(context->context);
//result = render_spu.ws.aglUpdateContext(context->context);
//CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");
//render_spu.self.Flush();
}
//InvalWindowRect (window, &rectPort);
break;
}
};
break;
}
case kEventClassVBox:
{
switch (kind)
{
case kEventVBoxUpdateContext:
{
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to cehck if this event is generated or not (it probably isn't). */
if (context &&
{
//glFlush();
}
#endif
break;
}
};
break;
}
break;
};
return result;
}
{
return GL_TRUE;
}
{
/* ATTR_ADDV(AGL_RED_SIZE, 1);
ATTR_ADDV(AGL_GREEN_SIZE, 1);
ATTR_ADDV(AGL_BLUE_SIZE, 1); */
/* if( render_spu.fullscreen )*/
/* ATTR_ADD(AGL_FULLSCREEN);*/
if( visAttribs & CR_ALPHA_BIT )
if( visAttribs & CR_DOUBLE_BIT )
if( visAttribs & CR_STEREO_BIT )
if( visAttribs & CR_DEPTH_BIT )
if( visAttribs & CR_STENCIL_BIT )
if( visAttribs & CR_ACCUM_BIT ) {
if( visAttribs & CR_ALPHA_BIT )
}
if( visAttribs & CR_MULTISAMPLE_BIT ) {
}
if( visAttribs & CR_OVERLAY_BIT )
}
void
{
}
{
(void) sharedContext;
crError( "Render SPU (renderspu_SystemCreateContext): Unable to create pixel format" );
return GL_FALSE;
}
crError( "Render SPU (renderspu_SystemCreateContext): Could not create rendering context" );
return GL_FALSE;
}
return GL_TRUE;
}
void
{
if(!context)
return;
{
}
}
void
{
/* Real fullscreen isn't supported by VirtualBox */
}
{
/* Flush old context first */
/* If the window buffer name is uninitialized we have to create a new
* dummy context. */
{
/* Use the same visual bits as those in the context structure */
{
crError( "Render SPU (renderspuWindowAttachContext): Unable to create pixel format" );
return GL_FALSE;
}
/* Create the dummy context */
if( !wi->dummyContext )
{
crError( "Render SPU (renderspuWindowAttachContext): Could not create rendering context" );
return GL_FALSE;
}
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
#else
#endif
/* New global buffer name */
/* Set the new buffer name to the dummy context. This enable the
* sharing of the same hardware buffer afterwards. */
/* Assign the dummy context to the window */
}
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
#else
#endif
/* Only switch the context if the drawable has changed */
if (oldDrawable != newDrawable)
{
/* Reset the current context */
/* Set the buffer name of the dummy context to the current context
* also. After that both share the same hardware buffer. */
/* Set the new drawable */
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
result = -1;
#else
#endif
}
return result;
}
{
return GL_TRUE;
}
void
{
if(!window->nativeWindow)
{
OSStatus status = CreateEvent(NULL, kEventClassVBox, kEventVBoxDisposeWindow, 0, kEventAttributeNone, &evt);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemDestroyWindow): CreateEvent Failed");
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemDestroyWindow): SetEventParameter Failed");
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemDestroyWindow): PostEventToQueue Failed");
}
/* Delete the dummy context */
if(window->dummyContext)
{
}
/* Reset some values */
if (window->hVisibleRegion)
{
window->hVisibleRegion = 0;
}
}
void
{
/* Send a event to the main thread, cause some function of Carbon aren't
* thread safe */
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): CreateEvent Failed ");
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof(window->window), &window->window);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): SetEventParameter Failed");
HISize s = CGSizeMake (w, h);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): SetEventParameter Failed");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): SetEventParameter Failed");
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): SendEventToEventTarget Failed");
/* We are tracking the position of the overlay window ourself. If the user
switch to fullscreen/seamless there is no hint that the position has
changed. (In the guest point of view it hasn't changed when the pos is
at (0, 0). So to be on the save side we post an additional pos event if
this is the case. */
if (window->x == 0 &&
window->y == 0)
renderspu_SystemWindowPosition (window, 0, 0);
else
{
/* Update the context. If the above position call is done this isn't
necessary cause its already done there. */
if (context &&
{
//result = render_spu.ws.aglUpdateContext(context->context);
//CHECK_AGL_RC (result, "Render SPU (renderspu_SystemWindowSize): UpdateContext Failed");
//glFlush();
}
}
/* save the new size */
}
void
{
Rect r;
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemGetWindowGeometry): GetWindowBounds Failed");
*x = (int) r.left;
*y = (int) r.top;
}
void
{
HISize s;
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
status = -1;
#else
#endif
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemGetMaxWindowSize): GetWindowResizeLimits Failed");
*w = s.width;
*h = s.height;
}
void
{
/* Send a event to the main thread, cause some function of Carbon aren't
* thread safe */
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): CreateEvent Failed");
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof(window->window), &window->window);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): SetEventParameter Failed");
HIPoint p = CGPointMake (x, y);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): SetEventParameter Failed");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): SetEventParameter Failed");
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): PostEventToQueue Failed");
/* Update the context */
if (context &&
{
DEBUG_MSG_POETZSCH (("Position %d context %x visible %d\n", window->id, context->context, IsWindowVisible (window->window)));
//result = render_spu.ws.aglUpdateContext(context->context);
//CHECK_AGL_RC (result, "Render SPU (renderspu_SystemWindowPosition): UpdateContext Failed");
//glFlush();
}
/* save the new pos */
window->x = x;
window->y = y;
}
/* Either show or hide the render SPU's window. */
void
{
return;
if(showIt)
{
/* Force moving the win to the right position before we show it */
/* Send a event to the main thread, cause some function of Carbon
* aren't thread safe */
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): CreateEvent Failed");
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): SetEventParameter Failed");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowShow): SetEventParameter Failed");
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): PostEventToQueue Failed");
}
else
{
OSStatus status = CreateEvent(NULL, kEventClassVBox, kEventVBoxHideWindow, 0, kEventAttributeNone, &evt);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): CreateEvent Failed");
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): SetEventParameter Failed");
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): PostEventToQueue Failed");
}
/* Update the context */
if (context &&
{
DEBUG_MSG_POETZSCH (("Showed %d context %x visible %d\n", window->id, context->context, IsWindowVisible (window->window)));
glFlush();
}
}
void
{
//crDebug( "renderspu_SystemMakeCurrent( %x, %i, %x )", window, nativeWindow, context );
{
{
crDebug("Render SPU (renderspu_SystemMakeCurrent): MakeCurrent visual mismatch (0x%x != 0x%x); remaking window.",
/*
* XXX have to revisit this issue!!!
*
* But for now we destroy the current window
* and re-create it with the context's visual abilities
*/
window);
}
/* This is the normal case: rendering to the render SPU's own window */
context);
/* XXX this is a total hack to work around an NVIDIA driver bug */
{
GLfloat f[4];
{
crDebug("Render SPU (renderspu_SystemMakeCurrent): Resetting raster pos");
}
}
}
else
renderspuWindowAttachContext (0, 0, 0);
}
void
{
if(!context)
crError("Render SPU (renderspu_SystemSwapBuffers): SwapBuffers got a null context from the window");
// DEBUG_MSG_POETZSCH (("Swapped %d context %x visible: %d\n", window->id, context->context, IsWindowVisible (window->window)));
else
glFlush();
/* This method seems called very often. To prevent the dock using all free
* resources we update the dock only two times per second. */
{
/* Send a event to the main thread, cause some function of Carbon aren't
* thread safe */
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): CreateEvent Failed");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemSwapBuffers): PostEventToQueue Failed");
}
}
{
DEBUG_MSG_POETZSCH (("Visible region \n"));
if (window->hVisibleRegion)
{
window->hVisibleRegion = 0;
}
if (cRects>0)
{
int i;
/* Create some temporary regions */
SetEmptyRgn (rgn);
for (i=0; i<cRects; ++i)
{
}
DisposeRgn (tmpRgn);
}
}
{
{
}
if (cRects>0)
{
int i;
for (i=0; i<cRects; ++i)
{
}
DisposeRgn (tmpRgn);
}
}
/*Assumes that all regions are in the guest coordinates system*/
{
if (!c || !c->context) return;
SetEmptyRgn (rgn);
{
}
else /*@todo create tmp region rect with size of underlying framebuffer */
{
/* SetRectRgn(0,0,fb->width,fb->height); */
}
if (window->hVisibleRegion)
{
}
/* If we'd need to set clip region in host screen coordinates, than shift it*/
/* OffsetRgn(rgn, fb->hostleft, fb->hosttop); */
/* Set the clip region to the context */
/* Clear the region structure */
DisposeRgn (rgn);
}
{
WindowAttributes winAttr = kWindowNoShadowAttribute | kWindowCompositingAttribute | kWindowIgnoreClicksAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute;
{
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): CreateEvent Failed", false);
status = SetEventParameter(evt, kEventParamWindowRef, typeWindowRef, sizeof (window->window), &window->window);
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): SetEventParameter Failed", false);
//status = SendEventToEventTarget (evt, GetWindowEventTarget (HIViewGetWindow ((HIViewRef)render_spu_parent_window_id)));
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): PostEventToQueue Failed", false);
}
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): CreateNewWindow Failed", GL_FALSE);
/* We set a title for debugging purposes */
/* We need grouping so create a master group for this & all following
* windows & one group for the parent. */
if(!gMasterGroup || !gParentGroup)
{
status = CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &gMasterGroup);
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): CreateWindowGroup Failed", GL_FALSE);
status = CreateWindowGroup(kWindowGroupAttrMoveTogether | kWindowGroupAttrLayerTogether | kWindowGroupAttrSharedActivation | kWindowGroupAttrHideOnCollapse | kWindowGroupAttrFixedLevel, &gParentGroup);
CHECK_CARBON_RC_RETURN (status, "Render SPU (renderspu_SystemVBoxCreateWindow): CreateWindowGroup Failed", GL_FALSE);
/* Make the correct z-layering */
/* and set the gParentGroup as parent for gMasterGroup. */
#ifdef __LP64__ /** @todo port to 64-bit darwin. */
#else
#endif
}
/* The parent has to be in its own group */
{
/* We need to process events from our main window */
if(!gParentEventHandler)
{
/* Install the event handlers */
{
};
}
}
/* Add the new window to the master group */
/* Own handler needed? */
{
/* Even though there are still issues with the windows themselves,
install the event handlers */
/*
InstallWindowEventHandler(window->window, window->event_handler,
GetEventTypeCount(event_list), event_list,
window, NULL);
*/
}
/* This will be initialized on the first attempt to attach the global
* context to this new window */
if(showIt)
crDebug("Render SPU (renderspu_SystemVBoxCreateWindow): actual window (x, y, width, height): %d, %d, %d, %d",
return GL_TRUE;
}