VirtualBox

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

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

OpenGLTestDarwin.cpp: Replaced the home-cooked execute-once with RTONCE from IPRT. Cleaned up the code a little, dropping some duplicated code in VBoxOglIs3DAccelerationSupported among other things.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 6.7 KB
Line 
1/* $Id: OpenGLTestDarwin.cpp 53582 2014-12-20 20:01:45Z vboxsync $ */
2/** @file
3 * VBox host opengl support test
4 */
5
6/*
7 * Copyright (C) 2009-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/VBoxOGLTest.h>
23
24#include <IOKit/IOKitLib.h>
25#include <OpenGL/OpenGL.h>
26#include <ApplicationServices/ApplicationServices.h>
27#include <OpenGL/gl.h>
28#ifdef VBOX_WITH_COCOA_QT
29# include <OpenGL/glu.h>
30#endif
31
32#include <iprt/env.h>
33#include <iprt/log.h>
34#include <iprt/once.h>
35
36
37
38/**
39 * @callback_method_impl{FNRTONCE,
40 * For determining the cached VBoxOglIsOfflineRenderingAppropriate result.}
41 */
42static DECLCALLBACK(int32_t) vboxOglIsOfflineRenderingAppropriateOnce(void *pvUser)
43{
44 bool *pfAppropriate = (bool *)pvUser;
45
46 /* It is assumed that it is makes sense to enable offline rendering
47 only in case if host has more than one GPU installed. This routine
48 counts all the PCI devices in IORegistry which have IOName property
49 set to "display". If the number of such devices is greater than one,
50 it sets pfAppropriate to TRUE, otherwise to FALSE. */
51
52 CFStringRef ppDictionaryKeys[] = { CFSTR(kIOProviderClassKey), CFSTR(kIONameMatchKey) };
53 CFStringRef ppDictionaryVals[] = { CFSTR("IOPCIDevice"), CFSTR("display") };
54 Assert(RT_ELEMENTS(ppDictionaryKeys) == RT_ELEMENTS(ppDictionaryVals));
55
56 CFDictionaryRef pMatchingDictionary = CFDictionaryCreate(kCFAllocatorDefault,
57 (const void **)ppDictionaryKeys,
58 (const void **)ppDictionaryVals,
59 RT_ELEMENTS(ppDictionaryKeys),
60 &kCFTypeDictionaryKeyCallBacks,
61 &kCFTypeDictionaryValueCallBacks);
62 if (pMatchingDictionary)
63 {
64 /* The reference to pMatchingDictionary is consumed by the function below => no IORelease(pMatchingDictionary)! */
65 io_iterator_t matchingServices;
66 kern_return_t krc = IOServiceGetMatchingServices(kIOMasterPortDefault, pMatchingDictionary, &matchingServices);
67 if (krc == kIOReturnSuccess)
68 {
69 io_object_t matchingService;
70 int cMatchingServices = 0;
71
72 while ((matchingService = IOIteratorNext(matchingServices)) != 0)
73 {
74 cMatchingServices++;
75 IOObjectRelease(matchingService);
76 }
77
78 *pfAppropriate = cMatchingServices > 1;
79
80 IOObjectRelease(matchingServices);
81 }
82 }
83
84 LogRel(("OpenGL: Offline rendering support is %s (pid=%d)\n", *pfAppropriate ? "ON" : "OFF", (int)getpid()));
85 return VINF_SUCCESS;
86}
87
88
89bool 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;
99}
100
101
102bool RTCALL VBoxOglIs3DAccelerationSupported(void)
103{
104 if (RTEnvExist("VBOX_CROGL_FORCE_SUPPORTED"))
105 {
106 LogRel(("VBOX_CROGL_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n"));
107 return true;
108 }
109
110 CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID());
111 CGLPixelFormatAttribute aAttribs[] =
112 {
113 kCGLPFADisplayMask,
114 (CGLPixelFormatAttribute)cglDisplayMask,
115 kCGLPFAAccelerated,
116 kCGLPFADoubleBuffer,
117 kCGLPFAWindow,
118 VBoxOglIsOfflineRenderingAppropriate() ? kCGLPFAAllowOfflineRenderers : (CGLPixelFormatAttribute)NULL,
119 (CGLPixelFormatAttribute)NULL
120 };
121 CGLPixelFormatObj pPixelFormat = NULL;
122 GLint cPixelFormatsIgnored = 0;
123 CGLError rcCgl = CGLChoosePixelFormat(aAttribs, &pPixelFormat, &cPixelFormatsIgnored);
124 if (rcCgl != kCGLNoError)
125 {
126 LogRel(("OpenGL Info: 3D test unable to choose pixel format (rcCgl=0x%X)\n", rcCgl));
127 return false;
128 }
129
130 if (pPixelFormat)
131 {
132 CGLContextObj pCglContext = 0;
133 rcCgl = CGLCreateContext(pPixelFormat, NULL, &pCglContext);
134 CGLDestroyPixelFormat(pPixelFormat);
135
136 if (rcCgl != kCGLNoError)
137 {
138 LogRel(("OpenGL Info: 3D test unable to create context (rcCgl=0x%X)\n", rcCgl));
139 return false;
140 }
141
142 if (pCglContext)
143 {
144 GLboolean isSupported = GL_TRUE;
145
146#ifdef VBOX_WITH_COCOA_QT
147 /*
148 * In the Cocoa port we depend on the GL_EXT_framebuffer_object &
149 * the GL_EXT_texture_rectangle extension. If they are not
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);
155 if (isSupported)
156 {
157 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_texture_rectangle", pszExts);
158 if (!isSupported)
159 LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported.\n"));
160 }
161 else
162 LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported.\n"));
163#endif /* VBOX_WITH_COCOA_QT */
164
165 CGLDestroyContext(pCglContext);
166 LogRel(("OpenGL Info: 3D test %spassed\n", isSupported == GL_TRUE ? "" : "not "));
167 return isSupported == GL_TRUE;
168 }
169
170 LogRel(("OpenGL Info: 3D test unable to create context (internal error).\n"));
171 }
172 else
173 LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error).\n"));
174
175 return false;
176}
177
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