VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/render/renderspu_cocoa.c@ 53582

Last change on this file since 53582 was 51442, checked in by vboxsync, 11 years ago

crOpenGL: fix flickering on osx

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1/** @file
2 * VirtualBox OpenGL Cocoa Window System implementation
3 */
4
5/*
6 * Copyright (C) 2009-2012 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <OpenGL/OpenGL.h>
18
19#include "renderspu.h"
20#include <iprt/process.h>
21#include <iprt/string.h>
22#include <iprt/path.h>
23
24#include <cr_string.h>
25#include <cr_mem.h>
26
27GLboolean renderspu_SystemInitVisual(VisualInfo *pVisInfo)
28{
29 CRASSERT(pVisInfo);
30
31/* cocoaGLVisualCreate(&pCtxInfo->context);*/
32
33 return GL_TRUE;
34}
35
36GLboolean renderspu_SystemCreateContext(VisualInfo *pVisInfo, ContextInfo *pCtxInfo, ContextInfo *pSharedCtxInfo)
37{
38 CRASSERT(pVisInfo);
39 CRASSERT(pCtxInfo);
40
41 pCtxInfo->currentWindow = NULL;
42
43 cocoaGLCtxCreate(&pCtxInfo->context, pVisInfo->visAttribs, pSharedCtxInfo ? pSharedCtxInfo->context : NULL);
44
45 return GL_TRUE;
46}
47
48void renderspu_SystemDestroyContext(ContextInfo *pCtxInfo)
49{
50 if(!pCtxInfo)
51 return;
52
53 if(pCtxInfo->context)
54 {
55 cocoaGLCtxDestroy(pCtxInfo->context);
56 pCtxInfo->context = NULL;
57 }
58}
59
60void renderspuFullscreen(WindowInfo *pWinInfo, GLboolean fFullscreen)
61{
62 /* Real fullscreen isn't supported by VirtualBox */
63}
64
65GLboolean renderspu_SystemVBoxCreateWindow(VisualInfo *pVisInfo, GLboolean fShowIt, WindowInfo *pWinInfo)
66{
67 CRASSERT(pVisInfo);
68 CRASSERT(pWinInfo);
69
70 /* VirtualBox is the only frontend which support 3D right now. */
71 char pszName[256];
72 if (RTProcGetExecutablePath(pszName, sizeof(pszName)))
73 /* Check for VirtualBox and VirtualBoxVM */
74 if (RTStrNICmp(RTPathFilename(pszName), "VirtualBox", 10) != 0)
75 return GL_FALSE;
76
77 pWinInfo->visual = pVisInfo;
78 pWinInfo->window = NULL;
79 pWinInfo->nativeWindow = NULL;
80 pWinInfo->currentCtx = NULL;
81
82#ifdef __LP64__
83 NativeNSViewRef pParentWin = (NativeNSViewRef)render_spu_parent_window_id;
84#else /* __LP64__ */
85 NativeNSViewRef pParentWin = (NativeNSViewRef)(uint32_t)render_spu_parent_window_id;
86#endif /* __LP64__ */
87
88 cocoaViewCreate(&pWinInfo->window, pWinInfo, pParentWin, pVisInfo->visAttribs);
89
90 if (fShowIt)
91 renderspu_SystemShowWindow(pWinInfo, fShowIt);
92
93 return GL_TRUE;
94}
95
96void renderspu_SystemReparentWindow(WindowInfo *pWinInfo)
97{
98#ifdef __LP64__
99 NativeNSViewRef pParentWin = (NativeNSViewRef)render_spu_parent_window_id;
100#else /* __LP64__ */
101 NativeNSViewRef pParentWin = (NativeNSViewRef)(uint32_t)render_spu_parent_window_id;
102#endif /* __LP64__ */
103 cocoaViewReparent(pWinInfo->window, pParentWin);
104}
105
106void renderspu_SystemDestroyWindow(WindowInfo *pWinInfo)
107{
108 CRASSERT(pWinInfo);
109
110 cocoaViewDestroy(pWinInfo->window);
111}
112
113void renderspu_SystemWindowPosition(WindowInfo *pWinInfo, GLint x, GLint y)
114{
115 CRASSERT(pWinInfo);
116
117#ifdef __LP64__
118 NativeNSViewRef pParentWin = (NativeNSViewRef)render_spu_parent_window_id;
119#else /* __LP64__ */
120 NativeNSViewRef pParentWin = (NativeNSViewRef)(uint32_t)render_spu_parent_window_id;
121#endif /* __LP64__ */
122
123 /*pParentWin is unused in the call, otherwise it might hold incorrect value if for ex. last reparent call was for
124 a different screen*/
125 cocoaViewSetPosition(pWinInfo->window, pParentWin, x, y);
126}
127
128void renderspu_SystemWindowSize(WindowInfo *pWinInfo, GLint w, GLint h)
129{
130 CRASSERT(pWinInfo);
131
132 cocoaViewSetSize(pWinInfo->window, w, h);
133}
134
135void renderspu_SystemGetWindowGeometry(WindowInfo *pWinInfo, GLint *pX, GLint *pY, GLint *pW, GLint *pH)
136{
137 CRASSERT(pWinInfo);
138
139 cocoaViewGetGeometry(pWinInfo->window, pX, pY, pW, pH);
140}
141
142void renderspu_SystemGetMaxWindowSize(WindowInfo *pWinInfo, GLint *pW, GLint *pH)
143{
144 CRASSERT(pWinInfo);
145
146 *pW = 10000;
147 *pH = 10000;
148}
149
150void renderspu_SystemShowWindow(WindowInfo *pWinInfo, GLboolean fShowIt)
151{
152 CRASSERT(pWinInfo);
153
154 cocoaViewShow(pWinInfo->window, fShowIt);
155}
156
157void renderspu_SystemVBoxPresentComposition( WindowInfo *window, const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry )
158{
159 cocoaViewPresentComposition(window->window, pChangedEntry);
160}
161
162void renderspu_SystemMakeCurrent(WindowInfo *pWinInfo, GLint nativeWindow, ContextInfo *pCtxInfo)
163{
164/* if(pWinInfo->visual != pCtxInfo->visual)*/
165/* printf ("visual mismatch .....................\n");*/
166
167 nativeWindow = 0;
168
169 if (pWinInfo && pCtxInfo)
170 cocoaViewMakeCurrentContext(pWinInfo->window, pCtxInfo->context);
171 else
172 cocoaViewMakeCurrentContext(NULL, NULL);
173}
174
175void renderspu_SystemSwapBuffers(WindowInfo *pWinInfo, GLint flags)
176{
177 CRASSERT(pWinInfo);
178
179 cocoaViewDisplay(pWinInfo->window);
180}
181
182GLboolean renderspu_SystemWindowNeedEmptyPresent(WindowInfo *pWinInfo)
183{
184 return cocoaViewNeedsEmptyPresent(pWinInfo->window);
185}
186
187void renderspu_SystemWindowVisibleRegion(WindowInfo *pWinInfo, GLint cRects, const GLint* paRects)
188{
189 CRASSERT(pWinInfo);
190
191 cocoaViewSetVisibleRegion(pWinInfo->window, cRects, paRects);
192}
193
194void renderspu_SystemWindowApplyVisibleRegion(WindowInfo *pWinInfo)
195{
196}
197
198int renderspu_SystemInit()
199{
200 return VINF_SUCCESS;
201}
202
203int renderspu_SystemTerm()
204{
205 CrGlslTerm(&render_spu.GlobalShaders);
206 return VINF_SUCCESS;
207}
208
209static SPUNamedFunctionTable * renderspuFindEntry(SPUNamedFunctionTable *aFunctions, const char *pcszName)
210{
211 SPUNamedFunctionTable *pCur;
212
213 for (pCur = aFunctions ; pCur->name != NULL ; pCur++)
214 {
215 if (!crStrcmp( pcszName, pCur->name ) )
216 {
217 return pCur;
218 }
219 }
220
221 AssertFailed();
222
223 return NULL;
224}
225
226typedef struct CR_RENDER_CTX_INFO
227{
228 ContextInfo * pContext;
229 WindowInfo * pWindow;
230} CR_RENDER_CTX_INFO;
231
232void renderspuCtxInfoInitCurrent(CR_RENDER_CTX_INFO *pInfo)
233{
234 GET_CONTEXT(pCurCtx);
235 pInfo->pContext = pCurCtx;
236 pInfo->pWindow = pCurCtx ? pCurCtx->currentWindow : NULL;
237}
238
239void renderspuCtxInfoRestoreCurrent(CR_RENDER_CTX_INFO *pInfo)
240{
241 GET_CONTEXT(pCurCtx);
242 if (pCurCtx == pInfo->pContext && (!pCurCtx || pCurCtx->currentWindow == pInfo->pWindow))
243 return;
244 renderspuPerformMakeCurrent(pInfo->pWindow, 0, pInfo->pContext);
245}
246
247GLboolean renderspuCtxSetCurrentWithAnyWindow(ContextInfo * pContext, CR_RENDER_CTX_INFO *pInfo)
248{
249 WindowInfo * window;
250 renderspuCtxInfoInitCurrent(pInfo);
251
252 if (pInfo->pContext == pContext)
253 return GL_TRUE;
254
255 window = pContext->currentWindow;
256 if (!window)
257 {
258 window = renderspuGetDummyWindow(pContext->BltInfo.Base.visualBits);
259 if (!window)
260 {
261 WARN(("renderspuGetDummyWindow failed"));
262 return GL_FALSE;
263 }
264 }
265
266 Assert(window);
267
268 renderspuPerformMakeCurrent(window, 0, pContext);
269 return GL_TRUE;
270}
271
272void renderspu_SystemDefaultSharedContextChanged(ContextInfo *fromContext, ContextInfo *toContext)
273{
274 CRASSERT(fromContext != toContext);
275
276 if (!CrGlslIsInited(&render_spu.GlobalShaders))
277 {
278 CrGlslInit(&render_spu.GlobalShaders, &render_spu.blitterDispatch);
279 }
280
281 if (fromContext)
282 {
283 if (CrGlslNeedsCleanup(&render_spu.GlobalShaders))
284 {
285 CR_RENDER_CTX_INFO Info;
286 if (renderspuCtxSetCurrentWithAnyWindow(fromContext, &Info))
287 {
288 CrGlslCleanup(&render_spu.GlobalShaders);
289 renderspuCtxInfoRestoreCurrent(&Info);
290 }
291 else
292 WARN(("renderspuCtxSetCurrentWithAnyWindow failed!"));
293 }
294 }
295 else
296 {
297 CRASSERT(!CrGlslNeedsCleanup(&render_spu.GlobalShaders));
298 }
299
300 CRASSERT(!CrGlslNeedsCleanup(&render_spu.GlobalShaders));
301
302 if (toContext)
303 {
304 CR_RENDER_CTX_INFO Info;
305 if (renderspuCtxSetCurrentWithAnyWindow(toContext, &Info))
306 {
307 int rc = CrGlslProgGenAllNoAlpha(&render_spu.GlobalShaders);
308 if (!RT_SUCCESS(rc))
309 WARN(("CrGlslProgGenAllNoAlpha failed, rc %d", rc));
310
311 renderspuCtxInfoRestoreCurrent(&Info);
312 }
313 else
314 crWarning("renderspuCtxSetCurrentWithAnyWindow failed!");
315 }
316}
317
318AssertCompile(sizeof (GLhandleARB) == sizeof (void*));
319
320static VBoxGLhandleARB crHndlSearchVBox(GLhandleARB hNative)
321{
322 CRASSERT(!(((uintptr_t)hNative) >> 32));
323 return (VBoxGLhandleARB)((uintptr_t)hNative);
324}
325
326static GLhandleARB crHndlSearchNative(VBoxGLhandleARB hVBox)
327{
328 return (GLhandleARB)((uintptr_t)hVBox);
329}
330
331static VBoxGLhandleARB crHndlAcquireVBox(GLhandleARB hNative)
332{
333 CRASSERT(!(((uintptr_t)hNative) >> 32));
334 return (VBoxGLhandleARB)((uintptr_t)hNative);
335}
336
337static GLhandleARB crHndlReleaseVBox(VBoxGLhandleARB hVBox)
338{
339 return (GLhandleARB)((uintptr_t)hVBox);
340}
341
342static void SPU_APIENTRY renderspu_SystemDeleteObjectARB(VBoxGLhandleARB obj)
343{
344 GLhandleARB hNative = crHndlReleaseVBox(obj);
345 if (!hNative)
346 {
347 crWarning("no native for %d", obj);
348 return;
349 }
350
351 render_spu.pfnDeleteObject(hNative);
352}
353
354static void SPU_APIENTRY renderspu_SystemGetAttachedObjectsARB( VBoxGLhandleARB containerObj, GLsizei maxCount, GLsizei * pCount, VBoxGLhandleARB * obj )
355{
356 GLhandleARB *paAttachments;
357 GLhandleARB hNative = crHndlSearchNative(containerObj);
358 GLsizei count, i;
359
360 if (pCount)
361 *pCount = 0;
362
363 if (!hNative)
364 {
365 crWarning("no native for %d", obj);
366 return;
367 }
368
369 paAttachments = crCalloc(maxCount * sizeof (*paAttachments));
370 if (!paAttachments)
371 {
372 crWarning("crCalloc failed");
373 return;
374 }
375
376 render_spu.pfnGetAttachedObjects(hNative, maxCount, &count, paAttachments);
377 if (pCount)
378 *pCount = count;
379 if (count > maxCount)
380 {
381 crWarning("count too big");
382 count = maxCount;
383 }
384
385 for (i = 0; i < count; ++i)
386 {
387 obj[i] = crHndlSearchVBox(paAttachments[i]);
388 CRASSERT(obj[i]);
389 }
390
391 crFree(paAttachments);
392}
393
394static VBoxGLhandleARB SPU_APIENTRY renderspu_SystemGetHandleARB(GLenum pname)
395{
396 GLhandleARB hNative = render_spu.pfnGetHandle(pname);
397 VBoxGLhandleARB hVBox;
398 if (!hNative)
399 {
400 crWarning("pfnGetHandle failed");
401 return 0;
402 }
403 hVBox = crHndlAcquireVBox(hNative);
404 CRASSERT(hVBox);
405 return hVBox;
406}
407
408static void SPU_APIENTRY renderspu_SystemGetInfoLogARB( VBoxGLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog )
409{
410 GLhandleARB hNative = crHndlSearchNative(obj);
411 if (!hNative)
412 {
413 crWarning("invalid handle!");
414 return;
415 }
416
417 render_spu.pfnGetInfoLog(hNative, maxLength, length, infoLog);
418}
419
420static void SPU_APIENTRY renderspu_SystemGetObjectParameterfvARB( VBoxGLhandleARB obj, GLenum pname, GLfloat * params )
421{
422 GLhandleARB hNative = crHndlSearchNative(obj);
423 if (!hNative)
424 {
425 crWarning("invalid handle!");
426 return;
427 }
428
429 render_spu.pfnGetObjectParameterfv(hNative, pname, params);
430}
431
432static void SPU_APIENTRY renderspu_SystemGetObjectParameterivARB( VBoxGLhandleARB obj, GLenum pname, GLint * params )
433{
434 GLhandleARB hNative = crHndlSearchNative(obj);
435 if (!hNative)
436 {
437 crWarning("invalid handle!");
438 return;
439 }
440
441 render_spu.pfnGetObjectParameteriv(hNative, pname, params);
442}
443
444uint32_t renderspu_SystemPostprocessFunctions(SPUNamedFunctionTable *aFunctions, uint32_t cFunctions, uint32_t cTable)
445{
446 SPUNamedFunctionTable * pEntry;
447
448 pEntry = renderspuFindEntry(aFunctions, "DeleteObjectARB");
449 if (pEntry)
450 {
451 render_spu.pfnDeleteObject = (PFNDELETE_OBJECT)pEntry->fn;
452 pEntry->fn = (SPUGenericFunction)renderspu_SystemDeleteObjectARB;
453 }
454
455 pEntry = renderspuFindEntry(aFunctions, "GetAttachedObjectsARB");
456 if (pEntry)
457 {
458 render_spu.pfnGetAttachedObjects = (PFNGET_ATTACHED_OBJECTS)pEntry->fn;
459 pEntry->fn = (SPUGenericFunction)renderspu_SystemGetAttachedObjectsARB;
460 }
461
462 pEntry = renderspuFindEntry(aFunctions, "GetHandleARB");
463 if (pEntry)
464 {
465 render_spu.pfnGetHandle = (PFNGET_HANDLE)pEntry->fn;
466 pEntry->fn = (SPUGenericFunction)renderspu_SystemGetHandleARB;
467 }
468
469 pEntry = renderspuFindEntry(aFunctions, "GetInfoLogARB");
470 if (pEntry)
471 {
472 render_spu.pfnGetInfoLog = (PFNGET_INFO_LOG)pEntry->fn;
473 pEntry->fn = (SPUGenericFunction)renderspu_SystemGetInfoLogARB;
474 }
475
476 pEntry = renderspuFindEntry(aFunctions, "GetObjectParameterfvARB");
477 if (pEntry)
478 {
479 render_spu.pfnGetObjectParameterfv = (PFNGET_OBJECT_PARAMETERFV)pEntry->fn;
480 pEntry->fn = (SPUGenericFunction)renderspu_SystemGetObjectParameterfvARB;
481 }
482
483 pEntry = renderspuFindEntry(aFunctions, "GetObjectParameterivARB");
484 if (pEntry)
485 {
486 render_spu.pfnGetObjectParameteriv = (PFNGET_OBJECT_PARAMETERIV)pEntry->fn;
487 pEntry->fn = (SPUGenericFunction)renderspu_SystemGetObjectParameterivARB;
488 }
489
490 return cFunctions;
491}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette