Changeset 53582 in vbox for trunk/src/VBox/HostServices/SharedOpenGL
- Timestamp:
- Dec 20, 2014 8:01:45 PM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 97344
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/OpenGLTest/OpenGLTestDarwin.cpp
r53554 r53582 1 1 /* $Id$ */ 2 3 2 /** @file 4 3 * VBox host opengl support test … … 18 17 19 18 19 /******************************************************************************* 20 * Header Files * 21 *******************************************************************************/ 22 #include <VBox/VBoxOGLTest.h> 23 20 24 #include <IOKit/IOKitLib.h> 21 25 #include <OpenGL/OpenGL.h> … … 24 28 #ifdef VBOX_WITH_COCOA_QT 25 29 # include <OpenGL/glu.h> 26 # include <iprt/log.h>27 #endif /* VBOX_WITH_COCOA_QT */ 30 #endif 31 28 32 #include <iprt/env.h> 29 33 #include <iprt/log.h> 34 #include <iprt/once.h> 30 35 31 #include <iprt/asm.h>32 #include <iprt/thread.h>33 36 34 #include <VBox/VBoxOGLTest.h>35 37 36 bool RTCALL VBoxOglIsOfflineRenderingAppropriate(void) 38 /** 39 * @callback_method_impl{FNRTONCE, 40 * For determining the cached VBoxOglIsOfflineRenderingAppropriate result.} 41 */ 42 static DECLCALLBACK(int32_t) vboxOglIsOfflineRenderingAppropriateOnce(void *pvUser) 37 43 { 44 bool *pfAppropriate = (bool *)pvUser; 45 38 46 /* It is assumed that it is makes sense to enable offline rendering 39 47 only in case if host has more than one GPU installed. This routine 40 48 counts all the PCI devices in IORegistry which have IOName property 41 set to "display". If the amount of such devices ifgreater than one,42 it returns TRUE or FALSE otherwise. */49 set to "display". If the number of such devices is greater than one, 50 it sets pfAppropriate to TRUE, otherwise to FALSE. */ 43 51 44 kern_return_t krc; 45 io_iterator_t matchingServices; 46 CFDictionaryRef pMatchingDictionary; 47 static bool fAppropriate = false; 52 CFStringRef ppDictionaryKeys[] = { CFSTR(kIOProviderClassKey), CFSTR(kIONameMatchKey) }; 53 CFStringRef ppDictionaryVals[] = { CFSTR("IOPCIDevice"), CFSTR("display") }; 54 Assert(RT_ELEMENTS(ppDictionaryKeys) == RT_ELEMENTS(ppDictionaryVals)); 48 55 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 #define VBOX_OGL_CHECK_UNINITIALIZED (0) 54 #define VBOX_OGL_CHECK_INITIALIZING (1) 55 #define VBOX_OGL_CHECK_INITIALIZED (2) 56 57 /* Transition VBOX_OGL_CHECK_UNINITIALIZED -> VBOX_OGL_CHECK_INITIALIZING means the current thread 58 is the first one who entered the routine. In this case, it should detect number of GPUs, cache result 59 and return it. If it's not TRUE, then fInitialized is VBOX_OGL_CHECK_INITIALIZING (another thread is performing 60 the check; current thread should wait till result will be cached and return it) or VBOX_OGL_CHECK_INITIALIZED 61 (result is already cached; just return it.) */ 62 63 static uint32_t volatile fInitialized = VBOX_OGL_CHECK_UNINITIALIZED; 64 if (!ASMAtomicCmpXchgU32(&fInitialized, VBOX_OGL_CHECK_INITIALIZING, VBOX_OGL_CHECK_UNINITIALIZED)) 65 { 66 while (ASMAtomicReadU32(&fInitialized) != VBOX_OGL_CHECK_INITIALIZED) 67 RTThreadSleep(5); 68 69 return fAppropriate; 70 } 71 72 #define VBOX_OGL_RENDERER_MATCH_KEYS_NUM (2) 73 74 CFStringRef ppDictionaryKeys[VBOX_OGL_RENDERER_MATCH_KEYS_NUM] = { CFSTR(kIOProviderClassKey), CFSTR(kIONameMatchKey) }; 75 CFStringRef ppDictionaryVals[VBOX_OGL_RENDERER_MATCH_KEYS_NUM] = { CFSTR("IOPCIDevice"), CFSTR("display") }; 76 77 pMatchingDictionary = CFDictionaryCreate(kCFAllocatorDefault, 78 (const void **)ppDictionaryKeys, 79 (const void **)ppDictionaryVals, 80 VBOX_OGL_RENDERER_MATCH_KEYS_NUM, 81 &kCFTypeDictionaryKeyCallBacks, 82 &kCFTypeDictionaryValueCallBacks); 56 CFDictionaryRef pMatchingDictionary = CFDictionaryCreate(kCFAllocatorDefault, 57 (const void **)ppDictionaryKeys, 58 (const void **)ppDictionaryVals, 59 RT_ELEMENTS(ppDictionaryKeys), 60 &kCFTypeDictionaryKeyCallBacks, 61 &kCFTypeDictionaryValueCallBacks); 83 62 if (pMatchingDictionary) 84 63 { 85 64 /* The reference to pMatchingDictionary is consumed by the function below => no IORelease(pMatchingDictionary)! */ 86 krc = IOServiceGetMatchingServices(kIOMasterPortDefault, pMatchingDictionary, &matchingServices); 65 io_iterator_t matchingServices; 66 kern_return_t krc = IOServiceGetMatchingServices(kIOMasterPortDefault, pMatchingDictionary, &matchingServices); 87 67 if (krc == kIOReturnSuccess) 88 68 { … … 96 76 } 97 77 98 fAppropriate = (cMatchingServices > 1);78 *pfAppropriate = cMatchingServices > 1; 99 79 100 80 IOObjectRelease(matchingServices); 101 81 } 102 103 82 } 104 83 105 LogRel(("OpenGL: Offline rendering support is %s (PID=%d)\n", fAppropriate ? "ON" : "OFF", (int)getpid())); 84 LogRel(("OpenGL: Offline rendering support is %s (pid=%d)\n", *pfAppropriate ? "ON" : "OFF", (int)getpid())); 85 return VINF_SUCCESS; 86 } 106 87 107 ASMAtomicWriteU32(&fInitialized, VBOX_OGL_CHECK_INITIALIZED);108 88 109 return fAppropriate; 89 bool RTCALL VBoxOglIsOfflineRenderingAppropriate(void) 90 { 91 /* In order to do not slowdown 3D engine which can ask about offline rendering several times, 92 let's cache the result and assume that renderers amount value is constant. Use the IPRT 93 execute once construct to make sure there aren't any threading issues. */ 94 static RTONCE s_Once = RTONCE_INITIALIZER; 95 static bool s_fCached = false; 96 int rc = RTOnce(&s_Once, vboxOglIsOfflineRenderingAppropriateOnce, &s_fCached); 97 AssertRC(rc); 98 return s_fCached; 110 99 } 100 111 101 112 102 bool RTCALL VBoxOglIs3DAccelerationSupported(void) … … 118 108 } 119 109 120 CGDirectDisplayID display = CGMainDisplayID (); 121 CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask (display); 122 CGLPixelFormatObj pixelFormat = NULL; 123 GLint numPixelFormats = 0; 124 CGLError rcCgl; 125 126 CGLPixelFormatAttribute attribs[] = { 110 CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()); 111 CGLPixelFormatAttribute aAttribs[] = 112 { 127 113 kCGLPFADisplayMask, 128 114 (CGLPixelFormatAttribute)cglDisplayMask, … … 133 119 (CGLPixelFormatAttribute)NULL 134 120 }; 135 136 display = CGMainDisplayID(); 137 cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(display); 138 rcCgl = CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats); 121 CGLPixelFormatObj pPixelFormat = NULL; 122 GLint cPixelFormatsIgnored = 0; 123 CGLError rcCgl = CGLChoosePixelFormat(aAttribs, &pPixelFormat, &cPixelFormatsIgnored); 139 124 if (rcCgl != kCGLNoError) 140 125 { … … 143 128 } 144 129 145 if (p ixelFormat)130 if (pPixelFormat) 146 131 { 147 CGLContextObj cglContext = 0;148 rcCgl = CGLCreateContext(p ixelFormat, NULL, &cglContext);149 CGLDestroyPixelFormat(p ixelFormat);132 CGLContextObj pCglContext = 0; 133 rcCgl = CGLCreateContext(pPixelFormat, NULL, &pCglContext); 134 CGLDestroyPixelFormat(pPixelFormat); 150 135 151 136 if (rcCgl != kCGLNoError) … … 155 140 } 156 141 157 if ( cglContext)142 if (pCglContext) 158 143 { 159 144 GLboolean isSupported = GL_TRUE; 145 160 146 #ifdef VBOX_WITH_COCOA_QT 161 /* On the Cocoa port we depend on the GL_EXT_framebuffer_object & 147 /* 148 * In the Cocoa port we depend on the GL_EXT_framebuffer_object & 162 149 * the GL_EXT_texture_rectangle extension. If they are not 163 * available, disable 3D support. */164 CGLSetCurrentContext(cglContext);165 const GLubyte* strExt;166 strExt= glGetString(GL_EXTENSIONS);167 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_framebuffer_object", strExt);150 * available, disable 3D support. 151 */ 152 CGLSetCurrentContext(pCglContext); 153 const GLubyte *pszExts = glGetString(GL_EXTENSIONS); 154 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_framebuffer_object", pszExts); 168 155 if (isSupported) 169 156 { 170 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_texture_rectangle", strExt);157 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_texture_rectangle", pszExts); 171 158 if (!isSupported) 172 LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported \n"));159 LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported.\n")); 173 160 } 174 161 else 175 LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported \n"));162 LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported.\n")); 176 163 #endif /* VBOX_WITH_COCOA_QT */ 177 CGLDestroyContext(cglContext); 164 165 CGLDestroyContext(pCglContext); 178 166 LogRel(("OpenGL Info: 3D test %spassed\n", isSupported == GL_TRUE ? "" : "not ")); 179 return isSupported == GL_TRUE ? true : false;167 return isSupported == GL_TRUE; 180 168 } 181 else 182 LogRel(("OpenGL Info: 3D test unable to create context (internal error)\n"));169 170 LogRel(("OpenGL Info: 3D test unable to create context (internal error).\n")); 183 171 } 184 172 else 185 LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error) \n"));173 LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error).\n")); 186 174 187 175 return false;
Note:
See TracChangeset
for help on using the changeset viewer.