VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp@ 52622

Last change on this file since 52622 was 52622, checked in by vboxsync, 10 years ago

3D: Mac OS X host: enable support for offline rendering.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.7 KB
Line 
1/* $Id: OpenGLTestDarwin.cpp 52622 2014-09-05 18:25:38Z vboxsync $ */
2
3/** @file
4 * VBox host opengl support test
5 */
6
7/*
8 * Copyright (C) 2009-2014 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19
20#include <IOKit/IOKitLib.h>
21#include <OpenGL/OpenGL.h>
22#include <ApplicationServices/ApplicationServices.h>
23#include <OpenGL/gl.h>
24#ifdef VBOX_WITH_COCOA_QT
25# include <OpenGL/glu.h>
26# include <iprt/log.h>
27#endif /* VBOX_WITH_COCOA_QT */
28#include <iprt/env.h>
29#include <iprt/log.h>
30
31#include <iprt/asm.h>
32#include <iprt/thread.h>
33
34#include <VBox/VBoxOGLTest.h>
35
36bool RTCALL VBoxOglIsOfflineRenderingAppropriate()
37{
38 /* It is assumed that it is makes sense to enable offline rendering
39 only in case if host has more than one GPU installed. This routine
40 counts all the PCI devices in IORegistry which have IOName property
41 set to "display". If the amount of such devices if greater than one,
42 it returns TRUE or FALSE otherwise. */
43
44 kern_return_t krc;
45 io_iterator_t matchingServices;
46 CFDictionaryRef pMatchingDictionary;
47 static bool fAppropriate = false;
48
49 /* In order to do not slowdown 3D engine which can ask about offline rendering several times,
50 let's cache the result and assume that renderers amount value is constant. Also prevent threads race
51 on startup. */
52
53 static bool volatile fState = false;
54 if (!ASMAtomicCmpXchgBool(&fState, true, false))
55 {
56 while (ASMAtomicReadBool(&fState) != true)
57 RTThreadSleep(5);
58
59 return fAppropriate;
60 }
61
62#define VBOX_OGL_RENDERER_MATCH_KEYS_NUM (2)
63
64 CFStringRef ppDictionaryKeys[VBOX_OGL_RENDERER_MATCH_KEYS_NUM] = { CFSTR(kIOProviderClassKey), CFSTR(kIONameMatchKey) };
65 CFStringRef ppDictionaryVals[VBOX_OGL_RENDERER_MATCH_KEYS_NUM] = { CFSTR("IOPCIDevice"), CFSTR("display") };
66
67 pMatchingDictionary = CFDictionaryCreate(kCFAllocatorDefault,
68 (const void **)ppDictionaryKeys,
69 (const void **)ppDictionaryVals,
70 VBOX_OGL_RENDERER_MATCH_KEYS_NUM,
71 &kCFTypeDictionaryKeyCallBacks,
72 &kCFTypeDictionaryValueCallBacks);
73 if (pMatchingDictionary)
74 {
75 /* The reference to pMatchingDictionary is consumed by the function below => no IORelease(pMatchingDictionary)! */
76 krc = IOServiceGetMatchingServices(kIOMasterPortDefault, pMatchingDictionary, &matchingServices);
77 if (krc == kIOReturnSuccess)
78 {
79 io_object_t matchingService;
80 int cMatchingServices = 0;
81
82 while ((matchingService = IOIteratorNext(matchingServices)) != 0)
83 {
84 cMatchingServices++;
85 IOObjectRelease(matchingService);
86 }
87
88 fAppropriate = (cMatchingServices > 1);
89
90 IOObjectRelease(matchingServices);
91 }
92
93 }
94
95 LogRel(("OpenGL: Offline rendering support is %s (PID=%d)\n", fAppropriate ? "ON" : "OFF", (int)getpid()));
96
97 return fAppropriate;
98}
99
100bool RTCALL VBoxOglIs3DAccelerationSupported()
101{
102 if (RTEnvExist("VBOX_CROGL_FORCE_SUPPORTED"))
103 {
104 LogRel(("VBOX_CROGL_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n"));
105 return true;
106 }
107
108 CGDirectDisplayID display = CGMainDisplayID ();
109 CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask (display);
110 CGLPixelFormatObj pixelFormat = NULL;
111 GLint numPixelFormats = 0;
112
113 CGLPixelFormatAttribute attribs[] = {
114 kCGLPFADisplayMask,
115 (CGLPixelFormatAttribute)cglDisplayMask,
116 kCGLPFAAccelerated,
117 kCGLPFADoubleBuffer,
118 kCGLPFAWindow,
119 VBoxOglIsOfflineRenderingAppropriate() ? kCGLPFAAllowOfflineRenderers : (CGLPixelFormatAttribute)NULL,
120 (CGLPixelFormatAttribute)NULL
121 };
122
123 display = CGMainDisplayID();
124 cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(display);
125 CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats);
126
127 if (pixelFormat)
128 {
129 CGLContextObj cglContext = 0;
130 CGLCreateContext(pixelFormat, NULL, &cglContext);
131 CGLDestroyPixelFormat(pixelFormat);
132 if (cglContext)
133 {
134 GLboolean isSupported = GL_TRUE;
135#ifdef VBOX_WITH_COCOA_QT
136 /* On the Cocoa port we depend on the GL_EXT_framebuffer_object &
137 * the GL_EXT_texture_rectangle extension. If they are not
138 * available, disable 3D support. */
139 CGLSetCurrentContext(cglContext);
140 const GLubyte* strExt;
141 strExt = glGetString(GL_EXTENSIONS);
142 isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_framebuffer_object", strExt);
143 if (isSupported)
144 {
145 isSupported = gluCheckExtension((const GLubyte*)"GL_EXT_texture_rectangle", strExt);
146 if (!isSupported)
147 LogRel(("OpenGL Info: GL_EXT_texture_rectangle extension not supported\n"));
148 }
149 else
150 LogRel(("OpenGL Info: GL_EXT_framebuffer_object extension not supported\n"));
151#endif /* VBOX_WITH_COCOA_QT */
152 CGLDestroyContext(cglContext);
153 return isSupported == GL_TRUE ? true : false;
154 }
155 }
156
157 return false;
158}
159
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