renderspu_agl.c revision 91d3c13d786ab55099e36be254f46bd98254b482
/* 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',
kEventVBoxBoundsChanged = 'bchg'
};
#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)) \
{ \
}
/* In some case (like compiz which doesn't provide us with clipping regions) we
* have to make sure that *all* open OpenGL windows are clipped to the main
* application window. This is done here when called from the event handler
* which monitor bounding changes of the main window. */
{
/* The window with id zero is the base window, which isn't displayed at
* all. So ignore it. */
if (key > 0)
{
/* Fetch the actually window info & the user data */
/* We need to assign the context with this window */
if (context &&
{
/* Update the clipping region */
/* Make sure that the position is updated relative to the Qt main
* view */
}
}
}
/* Window event handler */
{
switch (class)
{
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;
}
case kEventVBoxBoundsChanged:
{
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to cehck if this event is generated or not (it probably isn't). */
HIPoint p;
HISize s;
GLint l[4] = { 0,
0,
#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 */
}
{
/* DEBUG_MSG_POETZSCH (("WindowAttachContext %d\n", wi->id));*/
/* 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");
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");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowSize): SendEventToEventTarget Failed");
/* 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");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemWindowPosition): PostEventToQueue Failed");
/* 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");
CHECK_CARBON_RC_RETURN_VOID (status, "Render SPU (renderspu_SystemShowWindow): PostEventToQueue Failed");
}
}
void
{
/* DEBUG_MSG_POETZSCH (("makecurrent %d: \n", window->id));*/
//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);
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 */
{
{kEventClassVBox, kEventVBoxBoundsChanged} /* Clip/Pos the OpenGL windows when the main window is changed in pos/size */
};
}
}
/* Add the new window to the master group */
/* 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;
}