diff options
Diffstat (limited to 'src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c')
-rw-r--r-- | src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c new file mode 100644 index 00000000..583398a3 --- /dev/null +++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c @@ -0,0 +1,479 @@ +/* $Id: renderspu_cocoa.c $ */ +/** @file + * VirtualBox OpenGL Cocoa Window System implementation + */ + +/* + * Copyright (C) 2009-2019 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#include <OpenGL/OpenGL.h> + +#include "renderspu.h" +#include <iprt/process.h> +#include <iprt/string.h> +#include <iprt/path.h> + +#include <cr_string.h> +#include <cr_mem.h> + +GLboolean renderspu_SystemInitVisual(VisualInfo *pVisInfo) +{ + CRASSERT(pVisInfo); + +/* cocoaGLVisualCreate(&pCtxInfo->context);*/ + + return GL_TRUE; +} + +GLboolean renderspu_SystemCreateContext(VisualInfo *pVisInfo, ContextInfo *pCtxInfo, ContextInfo *pSharedCtxInfo) +{ + CRASSERT(pVisInfo); + CRASSERT(pCtxInfo); + + pCtxInfo->currentWindow = NULL; + + cocoaGLCtxCreate(&pCtxInfo->context, pVisInfo->visAttribs, pSharedCtxInfo ? pSharedCtxInfo->context : NULL); + + return GL_TRUE; +} + +void renderspu_SystemDestroyContext(ContextInfo *pCtxInfo) +{ + if(!pCtxInfo) + return; + + if(pCtxInfo->context) + { + cocoaGLCtxDestroy(pCtxInfo->context); + pCtxInfo->context = NULL; + } +} + +void renderspuFullscreen(WindowInfo *pWinInfo, GLboolean fFullscreen) +{ + /* Real fullscreen isn't supported by VirtualBox */ +} + +GLboolean renderspu_SystemVBoxCreateWindow(VisualInfo *pVisInfo, GLboolean fShowIt, WindowInfo *pWinInfo) +{ + CRASSERT(pVisInfo); + CRASSERT(pWinInfo); + + /* VirtualBox is the only frontend which support 3D right now. */ + char pszName[256]; + if (RTProcGetExecutablePath(pszName, sizeof(pszName))) + /* Check for VirtualBox and VirtualBoxVM */ + if (RTStrNICmp(RTPathFilename(pszName), "VirtualBox", 10) != 0) + return GL_FALSE; + + pWinInfo->visual = pVisInfo; + pWinInfo->window = NULL; + pWinInfo->nativeWindow = NULL; + pWinInfo->currentCtx = NULL; + + NativeNSViewRef pParentWin = (NativeNSViewRef)(uintptr_t)render_spu_parent_window_id; + + cocoaViewCreate(&pWinInfo->window, pWinInfo, pParentWin, pVisInfo->visAttribs); + + if (fShowIt) + renderspu_SystemShowWindow(pWinInfo, fShowIt); + + return GL_TRUE; +} + +void renderspu_SystemReparentWindow(WindowInfo *pWinInfo) +{ + NativeNSViewRef pParentWin = (NativeNSViewRef)(uintptr_t)render_spu_parent_window_id; + cocoaViewReparent(pWinInfo->window, pParentWin); +} + +void renderspu_SystemDestroyWindow(WindowInfo *pWinInfo) +{ + CRASSERT(pWinInfo); + + cocoaViewDestroy(pWinInfo->window); +} + +void renderspu_SystemWindowPosition(WindowInfo *pWinInfo, GLint x, GLint y) +{ + CRASSERT(pWinInfo); + NativeNSViewRef pParentWin = (NativeNSViewRef)(uintptr_t)render_spu_parent_window_id; + + /*pParentWin is unused in the call, otherwise it might hold incorrect value if for ex. last reparent call was for + a different screen*/ + cocoaViewSetPosition(pWinInfo->window, pParentWin, x, y); +} + +void renderspu_SystemWindowSize(WindowInfo *pWinInfo, GLint w, GLint h) +{ + CRASSERT(pWinInfo); + + cocoaViewSetSize(pWinInfo->window, w, h); +} + +void renderspu_SystemGetWindowGeometry(WindowInfo *pWinInfo, GLint *pX, GLint *pY, GLint *pW, GLint *pH) +{ + CRASSERT(pWinInfo); + + cocoaViewGetGeometry(pWinInfo->window, pX, pY, pW, pH); +} + +void renderspu_SystemGetMaxWindowSize(WindowInfo *pWinInfo, GLint *pW, GLint *pH) +{ + CRASSERT(pWinInfo); + + *pW = 10000; + *pH = 10000; +} + +void renderspu_SystemShowWindow(WindowInfo *pWinInfo, GLboolean fShowIt) +{ + CRASSERT(pWinInfo); + + cocoaViewShow(pWinInfo->window, fShowIt); +} + +void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry ) +{ + cocoaViewPresentComposition(window->window, pChangedEntry); +} + +void renderspu_SystemMakeCurrent(WindowInfo *pWinInfo, GLint nativeWindow, ContextInfo *pCtxInfo) +{ +/* if(pWinInfo->visual != pCtxInfo->visual)*/ +/* printf ("visual mismatch .....................\n");*/ + + nativeWindow = 0; + + if (pWinInfo && pCtxInfo) + cocoaViewMakeCurrentContext(pWinInfo->window, pCtxInfo->context); + else + cocoaViewMakeCurrentContext(NULL, NULL); +} + +void renderspu_SystemSwapBuffers(WindowInfo *pWinInfo, GLint flags) +{ + CRASSERT(pWinInfo); + + cocoaViewDisplay(pWinInfo->window); +} + +GLboolean renderspu_SystemWindowNeedEmptyPresent(WindowInfo *pWinInfo) +{ + return cocoaViewNeedsEmptyPresent(pWinInfo->window); +} + +void renderspu_SystemWindowVisibleRegion(WindowInfo *pWinInfo, GLint cRects, const GLint* paRects) +{ + CRASSERT(pWinInfo); + + cocoaViewSetVisibleRegion(pWinInfo->window, cRects, paRects); +} + +void renderspu_SystemWindowApplyVisibleRegion(WindowInfo *pWinInfo) +{ +} + +int renderspu_SystemInit() +{ + return VINF_SUCCESS; +} + +int renderspu_SystemTerm() +{ + CrGlslTerm(&render_spu.GlobalShaders); + return VINF_SUCCESS; +} + +static SPUNamedFunctionTable * renderspuFindEntry(SPUNamedFunctionTable *aFunctions, const char *pcszName) +{ + SPUNamedFunctionTable *pCur; + + for (pCur = aFunctions ; pCur->name != NULL ; pCur++) + { + if (!crStrcmp( pcszName, pCur->name ) ) + { + return pCur; + } + } + + AssertFailed(); + + return NULL; +} + +typedef struct CR_RENDER_CTX_INFO +{ + ContextInfo * pContext; + WindowInfo * pWindow; +} CR_RENDER_CTX_INFO; + +void renderspuCtxInfoInitCurrent(CR_RENDER_CTX_INFO *pInfo) +{ + GET_CONTEXT(pCurCtx); + pInfo->pContext = pCurCtx; + pInfo->pWindow = pCurCtx ? pCurCtx->currentWindow : NULL; +} + +void renderspuCtxInfoRestoreCurrent(CR_RENDER_CTX_INFO *pInfo) +{ + GET_CONTEXT(pCurCtx); + if (pCurCtx == pInfo->pContext && (!pCurCtx || pCurCtx->currentWindow == pInfo->pWindow)) + return; + renderspuPerformMakeCurrent(pInfo->pWindow, 0, pInfo->pContext); +} + +GLboolean renderspuCtxSetCurrentWithAnyWindow(ContextInfo * pContext, CR_RENDER_CTX_INFO *pInfo) +{ + WindowInfo * window; + renderspuCtxInfoInitCurrent(pInfo); + + if (pInfo->pContext == pContext) + return GL_TRUE; + + window = pContext->currentWindow; + if (!window) + { + window = renderspuGetDummyWindow(pContext->BltInfo.Base.visualBits); + if (!window) + { + WARN(("renderspuGetDummyWindow failed")); + return GL_FALSE; + } + } + + Assert(window); + + renderspuPerformMakeCurrent(window, 0, pContext); + return GL_TRUE; +} + +void renderspu_SystemDefaultSharedContextChanged(ContextInfo *fromContext, ContextInfo *toContext) +{ + CRASSERT(fromContext != toContext); + + if (!CrGlslIsInited(&render_spu.GlobalShaders)) + { + CrGlslInit(&render_spu.GlobalShaders, &render_spu.blitterDispatch); + } + + if (fromContext) + { + if (CrGlslNeedsCleanup(&render_spu.GlobalShaders)) + { + CR_RENDER_CTX_INFO Info; + if (renderspuCtxSetCurrentWithAnyWindow(fromContext, &Info)) + { + CrGlslCleanup(&render_spu.GlobalShaders); + renderspuCtxInfoRestoreCurrent(&Info); + } + else + WARN(("renderspuCtxSetCurrentWithAnyWindow failed!")); + } + } + else + { + CRASSERT(!CrGlslNeedsCleanup(&render_spu.GlobalShaders)); + } + + CRASSERT(!CrGlslNeedsCleanup(&render_spu.GlobalShaders)); + + if (toContext) + { + CR_RENDER_CTX_INFO Info; + if (renderspuCtxSetCurrentWithAnyWindow(toContext, &Info)) + { + int rc = CrGlslProgGenAllNoAlpha(&render_spu.GlobalShaders); + if (!RT_SUCCESS(rc)) + WARN(("CrGlslProgGenAllNoAlpha failed, rc %d", rc)); + + renderspuCtxInfoRestoreCurrent(&Info); + } + else + crWarning("renderspuCtxSetCurrentWithAnyWindow failed!"); + } +} + +AssertCompile(sizeof (GLhandleARB) == sizeof (void*)); + +static VBoxGLhandleARB crHndlSearchVBox(GLhandleARB hNative) +{ + CRASSERT(!(((uintptr_t)hNative) >> 32)); + return (VBoxGLhandleARB)((uintptr_t)hNative); +} + +static GLhandleARB crHndlSearchNative(VBoxGLhandleARB hVBox) +{ + return (GLhandleARB)((uintptr_t)hVBox); +} + +static VBoxGLhandleARB crHndlAcquireVBox(GLhandleARB hNative) +{ + CRASSERT(!(((uintptr_t)hNative) >> 32)); + return (VBoxGLhandleARB)((uintptr_t)hNative); +} + +static GLhandleARB crHndlReleaseVBox(VBoxGLhandleARB hVBox) +{ + return (GLhandleARB)((uintptr_t)hVBox); +} + +static void SPU_APIENTRY renderspu_SystemDeleteObjectARB(VBoxGLhandleARB obj) +{ + GLhandleARB hNative = crHndlReleaseVBox(obj); + if (!hNative) + { + crWarning("no native for %d", obj); + return; + } + + render_spu.pfnDeleteObject(hNative); +} + +static void SPU_APIENTRY renderspu_SystemGetAttachedObjectsARB( VBoxGLhandleARB containerObj, GLsizei maxCount, GLsizei * pCount, VBoxGLhandleARB * obj ) +{ + GLhandleARB *paAttachments; + GLhandleARB hNative = crHndlSearchNative(containerObj); + GLsizei count, i; + + if (pCount) + *pCount = 0; + + if (!hNative) + { + crWarning("no native for %d", obj); + return; + } + + paAttachments = crCalloc(maxCount * sizeof (*paAttachments)); + if (!paAttachments) + { + crWarning("crCalloc failed"); + return; + } + + render_spu.pfnGetAttachedObjects(hNative, maxCount, &count, paAttachments); + if (pCount) + *pCount = count; + if (count > maxCount) + { + crWarning("count too big"); + count = maxCount; + } + + for (i = 0; i < count; ++i) + { + obj[i] = crHndlSearchVBox(paAttachments[i]); + CRASSERT(obj[i]); + } + + crFree(paAttachments); +} + +static VBoxGLhandleARB SPU_APIENTRY renderspu_SystemGetHandleARB(GLenum pname) +{ + GLhandleARB hNative = render_spu.pfnGetHandle(pname); + VBoxGLhandleARB hVBox; + if (!hNative) + { + crWarning("pfnGetHandle failed"); + return 0; + } + hVBox = crHndlAcquireVBox(hNative); + CRASSERT(hVBox); + return hVBox; +} + +static void SPU_APIENTRY renderspu_SystemGetInfoLogARB( VBoxGLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog ) +{ + GLhandleARB hNative = crHndlSearchNative(obj); + if (!hNative) + { + crWarning("invalid handle!"); + return; + } + + render_spu.pfnGetInfoLog(hNative, maxLength, length, infoLog); +} + +static void SPU_APIENTRY renderspu_SystemGetObjectParameterfvARB( VBoxGLhandleARB obj, GLenum pname, GLfloat * params ) +{ + GLhandleARB hNative = crHndlSearchNative(obj); + if (!hNative) + { + crWarning("invalid handle!"); + return; + } + + render_spu.pfnGetObjectParameterfv(hNative, pname, params); +} + +static void SPU_APIENTRY renderspu_SystemGetObjectParameterivARB( VBoxGLhandleARB obj, GLenum pname, GLint * params ) +{ + GLhandleARB hNative = crHndlSearchNative(obj); + if (!hNative) + { + crWarning("invalid handle!"); + return; + } + + render_spu.pfnGetObjectParameteriv(hNative, pname, params); +} + +uint32_t renderspu_SystemPostprocessFunctions(SPUNamedFunctionTable *aFunctions, uint32_t cFunctions, uint32_t cTable) +{ + SPUNamedFunctionTable * pEntry; + + pEntry = renderspuFindEntry(aFunctions, "DeleteObjectARB"); + if (pEntry) + { + render_spu.pfnDeleteObject = (PFNDELETE_OBJECT)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemDeleteObjectARB; + } + + pEntry = renderspuFindEntry(aFunctions, "GetAttachedObjectsARB"); + if (pEntry) + { + render_spu.pfnGetAttachedObjects = (PFNGET_ATTACHED_OBJECTS)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemGetAttachedObjectsARB; + } + + pEntry = renderspuFindEntry(aFunctions, "GetHandleARB"); + if (pEntry) + { + render_spu.pfnGetHandle = (PFNGET_HANDLE)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemGetHandleARB; + } + + pEntry = renderspuFindEntry(aFunctions, "GetInfoLogARB"); + if (pEntry) + { + render_spu.pfnGetInfoLog = (PFNGET_INFO_LOG)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemGetInfoLogARB; + } + + pEntry = renderspuFindEntry(aFunctions, "GetObjectParameterfvARB"); + if (pEntry) + { + render_spu.pfnGetObjectParameterfv = (PFNGET_OBJECT_PARAMETERFV)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemGetObjectParameterfvARB; + } + + pEntry = renderspuFindEntry(aFunctions, "GetObjectParameterivARB"); + if (pEntry) + { + render_spu.pfnGetObjectParameteriv = (PFNGET_OBJECT_PARAMETERIV)pEntry->fn; + pEntry->fn = (SPUGenericFunction)renderspu_SystemGetObjectParameterivARB; + } + + return cFunctions; +} |