VirtualBox

source: vbox/trunk/src/VBox/Main/src-helper-apps/OpenGLTest/OpenGLTestDarwin.cpp@ 95865

Last change on this file since 95865 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.8 KB
Line 
1/* $Id: OpenGLTestDarwin.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBox host opengl support test
4 */
5
6/*
7 * Copyright (C) 2009-2022 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/VBoxOGL.h>
23
24#include <IOKit/IOKitLib.h>
25#include <OpenGL/OpenGL.h>
26#include <ApplicationServices/ApplicationServices.h>
27#include <OpenGL/gl.h>
28#include <OpenGL/glu.h>
29
30#include <iprt/env.h>
31#include <iprt/log.h>
32#include <iprt/once.h>
33
34
35
36/**
37 * @callback_method_impl{FNRTONCE,
38 * For determining the cached VBoxOglIsOfflineRenderingAppropriate result.}
39 */
40static DECLCALLBACK(int32_t) vboxOglIsOfflineRenderingAppropriateOnce(void *pvUser)
41{
42 bool *pfAppropriate = (bool *)pvUser;
43
44 /* It is assumed that it is makes sense to enable offline rendering
45 only in case if host has more than one GPU installed. This routine
46 counts all the PCI devices in IORegistry which have IOName property
47 set to "display". If the number of such devices is greater than one,
48 it sets pfAppropriate to TRUE, otherwise to FALSE. */
49
50 CFStringRef apKeyStrings[] = { CFSTR(kIOProviderClassKey), CFSTR(kIONameMatchKey) };
51 CFStringRef apValueStrings[] = { CFSTR("IOPCIDevice"), CFSTR("display") };
52 Assert(RT_ELEMENTS(apKeyStrings) == RT_ELEMENTS(apValueStrings));
53
54 CFDictionaryRef pMatchingDictionary = CFDictionaryCreate(kCFAllocatorDefault,
55 (const void **)apKeyStrings,
56 (const void **)apValueStrings,
57 RT_ELEMENTS(apKeyStrings),
58 &kCFTypeDictionaryKeyCallBacks,
59 &kCFTypeDictionaryValueCallBacks);
60 if (pMatchingDictionary)
61 {
62 /* The reference to pMatchingDictionary is consumed by the function below => no IORelease(pMatchingDictionary)! */
63 io_iterator_t matchingServices;
64 kern_return_t krc = IOServiceGetMatchingServices(kIOMasterPortDefault, pMatchingDictionary, &matchingServices);
65 if (krc == kIOReturnSuccess)
66 {
67 io_object_t matchingService;
68 int cMatchingServices = 0;
69
70 while ((matchingService = IOIteratorNext(matchingServices)) != 0)
71 {
72 cMatchingServices++;
73 IOObjectRelease(matchingService);
74 }
75
76 *pfAppropriate = cMatchingServices > 1;
77
78 IOObjectRelease(matchingServices);
79 }
80 }
81
82 LogRel(("OpenGL: Offline rendering support is %s (pid=%d)\n", *pfAppropriate ? "ON" : "OFF", (int)getpid()));
83 return VINF_SUCCESS;
84}
85
86
87bool RTCALL VBoxOglIsOfflineRenderingAppropriate(void)
88{
89 /* In order to do not slowdown 3D engine which can ask about offline rendering several times,
90 let's cache the result and assume that renderers amount value is constant. Use the IPRT
91 execute once construct to make sure there aren't any threading issues. */
92 static RTONCE s_Once = RTONCE_INITIALIZER;
93 static bool s_fCached = false;
94 int rc = RTOnce(&s_Once, vboxOglIsOfflineRenderingAppropriateOnce, &s_fCached);
95 AssertRC(rc);
96 return s_fCached;
97}
98
99
100bool RTCALL VBoxOglIs3DAccelerationSupported(void)
101{
102 if (RTEnvExist("VBOX_3D_FORCE_SUPPORTED"))
103 {
104 LogRel(("VBOX_3D_FORCE_SUPPORTED is specified, skipping 3D test, and treating as supported\n"));
105 return true;
106 }
107
108 CGOpenGLDisplayMask cglDisplayMask = CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID());
109 CGLPixelFormatAttribute aAttribs[] =
110 {
111 kCGLPFADisplayMask,
112 (CGLPixelFormatAttribute)cglDisplayMask,
113 kCGLPFAAccelerated,
114 kCGLPFADoubleBuffer,
115 VBoxOglIsOfflineRenderingAppropriate() ? kCGLPFAAllowOfflineRenderers : (CGLPixelFormatAttribute)NULL,
116 (CGLPixelFormatAttribute)NULL
117 };
118 CGLPixelFormatObj pPixelFormat = NULL;
119 GLint cPixelFormatsIgnored = 0;
120 CGLError rcCgl = CGLChoosePixelFormat(aAttribs, &pPixelFormat, &cPixelFormatsIgnored);
121 if (rcCgl != kCGLNoError)
122 {
123 LogRel(("OpenGL Info: 3D test unable to choose pixel format (rcCgl=0x%X)\n", rcCgl));
124 return false;
125 }
126
127 if (pPixelFormat)
128 {
129 CGLContextObj pCglContext = 0;
130 rcCgl = CGLCreateContext(pPixelFormat, NULL, &pCglContext);
131 CGLDestroyPixelFormat(pPixelFormat);
132
133 if (rcCgl != kCGLNoError)
134 {
135 LogRel(("OpenGL Info: 3D test unable to create context (rcCgl=0x%X)\n", rcCgl));
136 return false;
137 }
138
139 if (pCglContext)
140 {
141 GLboolean isSupported = GL_TRUE;
142
143 /*
144 * In the Cocoa port we depend on the GL_EXT_framebuffer_object &
145 * the GL_EXT_texture_rectangle extension. If they are not
146 * available, disable 3D support.
147 */
148#pragma clang diagnostic ignored "-Wdeprecated-declarations" /* gluCheckExtension deprecated since 10.10 - use MetalKit. */
149 CGLSetCurrentContext(pCglContext);
150 const GLubyte *pszExts = glGetString(GL_EXTENSIONS);
151 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_framebuffer_object", pszExts);
152 if (isSupported)
153 {
154 isSupported = gluCheckExtension((const GLubyte *)"GL_EXT_texture_rectangle", pszExts);
155 if (!isSupported)
156 LogRel(("OpenGL Info: 3D test found that GL_EXT_texture_rectangle extension not supported.\n"));
157 }
158 else
159 LogRel(("OpenGL Info: 3D test found that GL_EXT_framebuffer_object extension not supported.\n"));
160
161 CGLDestroyContext(pCglContext);
162 LogRel(("OpenGL Info: 3D test %spassed\n", isSupported == GL_TRUE ? "" : "not "));
163 return isSupported == GL_TRUE;
164 }
165
166 LogRel(("OpenGL Info: 3D test unable to create context (internal error).\n"));
167 }
168 else
169 LogRel(("OpenGL Info: 3D test unable to choose pixel format (internal error).\n"));
170
171 return false;
172}
173
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