renderspu_agl.c revision d171c6e83ee2cdae7d630182ee101efbf0f8c0e8
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include <iprt/semaphore.h>
#include <stdio.h>
#include "cr_environment.h"
#include "cr_error.h"
#include "cr_string.h"
#include "cr_mem.h"
#include "renderspu.h"
#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 &&
{
if (result)
{
/* Update the clipping region */
}
/* Make sure that the position is updated relative to the Qt main
* view */
}
}
}
/* Window event handler */
{
/* If we aren't initialized or even deinitialized already (as on VM
* shutdown) do nothing. */
if (!render_spu.fInit)
return eventNotHandledErr;
/* Fetch the sender of the event */
switch (class)
{
case kEventClassVBox:
{
switch (kind)
{
case kEventVBoxUpdateContext:
{
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */
if (context &&
{
if (result)
{
/* Reapply the last active context */
if (tmpContext)
{
if (result)
{
}
}
}
}
eventResult = noErr;
#endif
break;
}
case kEventVBoxBoundsChanged:
{
#ifndef __LP64__ /** @todo port to 64-bit darwin! Need to check if this event is generated or not (it probably isn't). */
HIPoint p;
HISize s;
GLint l[4] = { 0,
0,
/* Update the root window clip region */
/* Temporary save the current active context */
/* Reapply the last active context */
if (tmpContext)
{
/* Doesn't work with DirectX; Anyway doesn't */
/* if (result)*/
/* {*/
/* result = render_spu.ws.aglUpdateContext(tmpContext);*/
/* CHECK_AGL_RC (result, "Render SPU (windowEvtHndlr): UpdateContext Failed");*/
/* }*/
}
eventResult = noErr;
#endif
break;
}
};
break;
}
break;
};
return eventResult;
}
{
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->BltInfo.Base.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;
}
{
/* stub only */
}
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_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;
}
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");
DEBUG_MSG_POETZSCH (("Size %d visible %d\n", window->BltInfo.Base.id, IsWindowVisible (window->window)));
/* 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;
}
/* 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 renderspu_SystemVBoxPresentComposition( WindowInfo *window, struct VBOXVR_SCR_COMPOSITOR * pCompositor, struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
{
}
void
{
/* DEBUG_MSG_POETZSCH (("makecurrent %d: \n", window->BltInfo.Base.id));*/
//crDebug( "renderspu_SystemMakeCurrent( %x, %i, %x )", window, nativeWindow, context );
nativeWindow = 0;
{
{
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");
}
}
/* Reapply the visible regions */
}
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->BltInfo.Base.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");
}
}
{
/* Remember any additional clipping stuff e.g. seamless regions */
if (window->hVisibleRegion)
{
window->hVisibleRegion = 0;
}
if (cRects>0)
{
int i;
/* Create some temporary regions */
SetEmptyRgn (rgn);
for (i=0; i<cRects; ++i)
{
//DEBUG_MSG_POETZSCH (("visible rect %d %d %d %d\n", pRects[4*i] , pRects[4*i+1],
// pRects[4*i+2], pRects[4*i+3]));
}
DisposeRgn (tmpRgn);
}
}
{
/* Remember the visible region of the root window if there is one */
{
}
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;
{
/* The render_spu.hRootVisibleRegion has coordinates from the root
* window. We intersect it with the rect of the OpenGL window we
* currently process. */
/* Because the clipping is done in the coordinate space of the OpenGL
* window we have to remove the x/y position from the newly created
* region. */
}
else
{
/* If there is not root clipping region is available, create a base
* region with the size of the target window. This covers all
}
/* Now intersect the window clipping region with a additional region e.g.
* for the seamless mode. */
if (window->hVisibleRegion)
{
/* 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 */
/* The parent has to be in its own group */
{
}
/* 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 */
window->hVisibleRegion = 0;
if(showIt)
crDebug("Render SPU (renderspu_SystemVBoxCreateWindow): actual window (x, y, width, height): %d, %d, %d, %d",
return GL_TRUE;
}
int renderspu_SystemInit()
{
return VINF_SUCCESS;
}
int renderspu_SystemTerm()
{
return VINF_SUCCESS;
}
{
}