VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-glLdr.cpp@ 76255

Last change on this file since 76255 was 76255, checked in by vboxsync, 6 years ago

DevVGA-SVGA3d: Use PDMDevHlpVMSetError and VERR_VGA_GL_SYMBOL_NOT_FOUND to report errors loading open gl symbol resolving errors. Tested on windows. Left todo (mainly to myself) about better libGL.so/opengl32.dll/OpenGL.dylib loading error reporting, since that'll show up as failure to resolve 'glAlphaFunc' now.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1/* $Id: DevVGA-SVGA3d-glLdr.cpp 76255 2018-12-16 18:47:05Z vboxsync $ */
2/** @file
3 * DevVGA - VMWare SVGA device - 3D part, dynamic loading of GL function.
4 */
5
6/*
7 * Copyright (C) 2018 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#define VMSVGA3D_GL_DEFINE_PFN
19#include "DevVGA-SVGA3d-glLdr.h"
20
21#include <VBox/vmm/pdmdev.h>
22#include <VBox/err.h>
23#include <iprt/assert.h>
24#include <iprt/cdefs.h>
25#include <iprt/ldr.h>
26#include <iprt/log.h>
27
28#ifdef RT_OS_WINDOWS
29# define OGLGETPROCADDRESS MyWinGetProcAddress
30DECLINLINE(PFNRT) MyWinGetProcAddress(const char *pszSymbol)
31{
32 int rc;
33
34 static RTLDRMOD s_hOpenGL32 = NULL;
35 if (s_hOpenGL32 == NULL)
36 {
37 rc = RTLdrLoadSystem("opengl32", /* fNoUnload = */ true, &s_hOpenGL32);
38 if (RT_FAILURE(rc))
39 s_hOpenGL32 = NULL;
40 }
41
42 typedef PROC (WINAPI *PFNWGLGETPROCADDRESS)(LPCSTR);
43 static PFNWGLGETPROCADDRESS s_wglGetProcAddress = NULL;
44 if (s_wglGetProcAddress == NULL)
45 {
46 if (s_hOpenGL32 != NULL)
47 {
48 rc = RTLdrGetSymbol(s_hOpenGL32, "wglGetProcAddress", (void **)&s_wglGetProcAddress);
49 if (RT_FAILURE(rc))
50 s_wglGetProcAddress = NULL;
51 }
52 }
53
54 if (s_wglGetProcAddress)
55 {
56 /* Khronos: [on failure] "some implementations will return other values. 1, 2, and 3 are used, as well as -1". */
57 PFNRT p = (PFNRT)s_wglGetProcAddress(pszSymbol);
58 if (RT_VALID_PTR(p))
59 return p;
60
61 /* Might be an exported symbol. */
62 rc = RTLdrGetSymbol(s_hOpenGL32, pszSymbol, (void **)&p);
63 if (RT_SUCCESS(rc))
64 return p;
65 }
66
67 return 0;
68}
69
70#elif defined(RT_OS_DARWIN)
71# include <dlfcn.h>
72# define OGLGETPROCADDRESS MyNSGLGetProcAddress
73/** Resolves an OpenGL symbol. */
74static void *MyNSGLGetProcAddress(const char *pszSymbol)
75{
76 /* Another copy in shaderapi.c. */
77 static void *s_pvImage = NULL;
78 if (s_pvImage == NULL)
79 s_pvImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
80 return s_pvImage ? dlsym(s_pvImage, pszSymbol) : NULL;
81}
82
83#else
84# define OGLGETPROCADDRESS MyGLXGetProcAddress
85static PFNRT MyGLXGetProcAddress(const char *pszSymbol)
86{
87 int rc;
88
89 static RTLDRMOD s_hGL = NULL;
90 if (s_hGL == NULL)
91 {
92 static const char s_szLibGL[] = "libGL.so.1";
93 rc = RTLdrLoadEx(s_szLibGL, &s_hGL, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD, NULL);
94 if (RT_FAILURE(rc))
95 {
96 LogRel(("VMSVGA3d: failed to load %s: %Rrc\n", s_szLibGL, rc));
97 s_hGL = NULL;
98 return NULL;
99 }
100 }
101
102 typedef PFNRT (* PFNGLXGETPROCADDRESS)(const GLubyte * procName);
103 static PFNGLXGETPROCADDRESS s_glXGetProcAddress = NULL;
104 if (s_glXGetProcAddress == NULL)
105 {
106 rc = RTLdrGetSymbol(s_hGL, "glXGetProcAddress", (void **)&s_glXGetProcAddress);
107 if (RT_FAILURE(rc))
108 {
109 LogRel(("VMSVGA3d: failed to get glXGetProcAddress: %Rrc\n", rc));
110 s_glXGetProcAddress = NULL;
111 return NULL;
112 }
113 }
114
115 PFNRT p = s_glXGetProcAddress((const GLubyte *)pszSymbol);
116 if (RT_VALID_PTR(p))
117 return p;
118
119 /* Might be an exported symbol. */
120 rc = RTLdrGetSymbol(s_hGL, pszSymbol, (void **)&p);
121 if (RT_SUCCESS(rc))
122 return p;
123
124 return NULL;
125}
126#endif
127
128#define GLGETPROC_(ProcName, NameSuffix) do { \
129 *(PFNRT *)&pfn_##ProcName = pfnRet = OGLGETPROCADDRESS(#ProcName NameSuffix); \
130 if (pfnRet) { /* likely */ } \
131 else \
132 { \
133 AssertLogRelMsg(pfnRet, ("%s missing\n", #ProcName NameSuffix)); \
134 return PDMDevHlpVMSetError(pDevIns, VERR_VGA_GL_SYMBOL_NOT_FOUND, RT_SRC_POS, \
135 "Missing OpenGL symbol '%s'\n", #ProcName NameSuffix); \
136 } \
137} while(0)
138
139int glLdrInit(PPDMDEVINS pDevIns)
140{
141 /** @todo r=bird: Perhaps make this template include file driven? See
142 * include/VBox/dbus.h, include/VBox/dbus-calls.h and iprt/runtime-loader.h for
143 * instance. Regardless, it would be would be nice if we could move up the
144 * RTLdrLoadSystem/dlopen bits and have separate error reporting for those,
145 * making use of VERR_VGA_GL_LOAD_FAILURE. I can look into that, but
146 * probably only after the release is out... */
147
148 pfn_glAlphaFunc = 0;
149 pfn_glBindTexture = 0;
150 pfn_glBlendColor = 0;
151 pfn_glBlendEquation = 0;
152 pfn_glBlendFunc = 0;
153 pfn_glClear = 0;
154 pfn_glClearColor = 0;
155 pfn_glClearDepth = 0;
156 pfn_glClearStencil = 0;
157 pfn_glClientActiveTexture = 0;
158 pfn_glClipPlane = 0;
159 pfn_glColorMask = 0;
160 pfn_glColorPointer = 0;
161 pfn_glCullFace = 0;
162 pfn_glDeleteTextures = 0;
163 pfn_glDepthFunc = 0;
164 pfn_glDepthMask = 0;
165 pfn_glDepthRange = 0;
166 pfn_glDisable = 0;
167 pfn_glDisableClientState = 0;
168 pfn_glDrawArrays = 0;
169 pfn_glDrawElements = 0;
170 pfn_glEnable = 0;
171 pfn_glEnableClientState = 0;
172 pfn_glFogf = 0;
173 pfn_glFogfv = 0;
174 pfn_glFogi = 0;
175 pfn_glFrontFace = 0;
176 pfn_glGenTextures = 0;
177 pfn_glGetBooleanv = 0;
178 pfn_glGetError = 0;
179 pfn_glGetFloatv = 0;
180 pfn_glGetIntegerv = 0;
181 pfn_glGetString = 0;
182 pfn_glGetTexImage = 0;
183 pfn_glLightModelfv = 0;
184 pfn_glLightf = 0;
185 pfn_glLightfv = 0;
186 pfn_glLineWidth = 0;
187 pfn_glLoadIdentity = 0;
188 pfn_glLoadMatrixf = 0;
189 pfn_glMaterialfv = 0;
190 pfn_glMatrixMode = 0;
191 pfn_glMultMatrixf = 0;
192 pfn_glNormalPointer = 0;
193 pfn_glPixelStorei = 0;
194 pfn_glPointSize = 0;
195 pfn_glPolygonMode = 0;
196 pfn_glPolygonOffset = 0;
197 pfn_glPopAttrib = 0;
198 pfn_glPopMatrix = 0;
199 pfn_glPushAttrib = 0;
200 pfn_glPushMatrix = 0;
201 pfn_glScissor = 0;
202 pfn_glShadeModel = 0;
203 pfn_glStencilFunc = 0;
204 pfn_glStencilMask = 0;
205 pfn_glStencilOp = 0;
206 pfn_glTexCoordPointer = 0;
207 pfn_glTexImage2D = 0;
208 pfn_glTexParameterf = 0;
209 pfn_glTexParameterfv = 0;
210 pfn_glTexParameteri = 0;
211 pfn_glTexSubImage2D = 0;
212 pfn_glVertexPointer = 0;
213 pfn_glViewport = 0;
214#ifdef RT_OS_WINDOWS
215 pfn_wglCreateContext = 0;
216 pfn_wglDeleteContext = 0;
217 pfn_wglMakeCurrent = 0;
218 pfn_wglShareLists = 0;
219#elif defined(RT_OS_LINUX)
220 pfn_glXQueryVersion = 0;
221 pfn_glXChooseVisual = 0;
222 pfn_glXCreateContext = 0;
223 pfn_glXMakeCurrent = 0;
224 pfn_glXDestroyContext = 0;
225#endif
226
227 PFNRT pfnRet;
228 GLGETPROC_(glAlphaFunc, "");
229 GLGETPROC_(glBindTexture, "");
230 GLGETPROC_(glBlendFunc, "");
231 GLGETPROC_(glClear, "");
232 GLGETPROC_(glClearColor, "");
233 GLGETPROC_(glClearDepth, "");
234 GLGETPROC_(glClearStencil, "");
235 GLGETPROC_(glClipPlane, "");
236 GLGETPROC_(glColorMask, "");
237 GLGETPROC_(glColorPointer, "");
238 GLGETPROC_(glCullFace, "");
239 GLGETPROC_(glDeleteTextures, "");
240 GLGETPROC_(glDepthFunc, "");
241 GLGETPROC_(glDepthMask, "");
242 GLGETPROC_(glDepthRange, "");
243 GLGETPROC_(glDisable, "");
244 GLGETPROC_(glDisableClientState, "");
245 GLGETPROC_(glDrawArrays, "");
246 GLGETPROC_(glDrawElements, "");
247 GLGETPROC_(glEnable, "");
248 GLGETPROC_(glEnableClientState, "");
249 GLGETPROC_(glFogf, "");
250 GLGETPROC_(glFogfv, "");
251 GLGETPROC_(glFogi, "");
252 GLGETPROC_(glFrontFace, "");
253 GLGETPROC_(glGenTextures, "");
254 GLGETPROC_(glGetBooleanv, "");
255 GLGETPROC_(glGetError, "");
256 GLGETPROC_(glGetFloatv, "");
257 GLGETPROC_(glGetIntegerv, "");
258 GLGETPROC_(glGetString, "");
259 GLGETPROC_(glGetTexImage, "");
260 GLGETPROC_(glLightModelfv, "");
261 GLGETPROC_(glLightf, "");
262 GLGETPROC_(glLightfv, "");
263 GLGETPROC_(glLineWidth, "");
264 GLGETPROC_(glLoadIdentity, "");
265 GLGETPROC_(glLoadMatrixf, "");
266 GLGETPROC_(glMaterialfv, "");
267 GLGETPROC_(glMatrixMode, "");
268 GLGETPROC_(glMultMatrixf, "");
269 GLGETPROC_(glNormalPointer, "");
270 GLGETPROC_(glPixelStorei, "");
271 GLGETPROC_(glPointSize, "");
272 GLGETPROC_(glPolygonMode, "");
273 GLGETPROC_(glPolygonOffset, "");
274 GLGETPROC_(glPopAttrib, "");
275 GLGETPROC_(glPopMatrix, "");
276 GLGETPROC_(glPushAttrib, "");
277 GLGETPROC_(glPushMatrix, "");
278 GLGETPROC_(glScissor, "");
279 GLGETPROC_(glShadeModel, "");
280 GLGETPROC_(glStencilFunc, "");
281 GLGETPROC_(glStencilMask, "");
282 GLGETPROC_(glStencilOp, "");
283 GLGETPROC_(glTexCoordPointer, "");
284 GLGETPROC_(glTexImage2D, "");
285 GLGETPROC_(glTexParameterf, "");
286 GLGETPROC_(glTexParameterfv, "");
287 GLGETPROC_(glTexParameteri, "");
288 GLGETPROC_(glTexSubImage2D, "");
289 GLGETPROC_(glVertexPointer, "");
290 GLGETPROC_(glViewport, "");
291#ifdef RT_OS_WINDOWS
292 GLGETPROC_(wglCreateContext, "");
293 GLGETPROC_(wglDeleteContext, "");
294 GLGETPROC_(wglMakeCurrent, "");
295 GLGETPROC_(wglShareLists, "");
296#elif defined(RT_OS_LINUX)
297 GLGETPROC_(glXQueryVersion, "");
298 GLGETPROC_(glXChooseVisual, "");
299 GLGETPROC_(glXCreateContext, "");
300 GLGETPROC_(glXMakeCurrent, "");
301 GLGETPROC_(glXDestroyContext, "");
302#endif
303 return VINF_SUCCESS;
304}
305
306PFNRT glLdrGetProcAddress(const char *pszSymbol)
307{
308 return OGLGETPROCADDRESS(pszSymbol);
309}
310
311int glLdrGetExtFunctions(PPDMDEVINS pDevIns)
312{
313 PFNRT pfnRet;
314 GLGETPROC_(glBlendColor, "");
315 GLGETPROC_(glBlendEquation, "");
316 GLGETPROC_(glClientActiveTexture, "");
317 return VINF_SUCCESS;
318}
Note: See TracBrowser for help on using the repository browser.

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