VirtualBox

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

Last change on this file since 97405 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/* $Id: DevVGA-SVGA3d-glLdr.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * DevVGA - VMWare SVGA device - 3D part, dynamic loading of GL function.
4 */
5
6/*
7 * Copyright (C) 2018-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define VMSVGA3D_GL_DEFINE_PFN
29#include "DevVGA-SVGA3d-glLdr.h"
30
31#include <VBox/vmm/pdmdev.h>
32#include <VBox/err.h>
33#include <iprt/assert.h>
34#include <iprt/cdefs.h>
35#include <iprt/ldr.h>
36#include <iprt/log.h>
37
38#ifdef RT_OS_WINDOWS
39# define OGLGETPROCADDRESS MyWinGetProcAddress
40DECLINLINE(PFNRT) MyWinGetProcAddress(const char *pszSymbol)
41{
42 int rc;
43
44 static RTLDRMOD s_hOpenGL32 = NULL;
45 if (s_hOpenGL32 == NULL)
46 {
47 rc = RTLdrLoadSystem("opengl32", /* fNoUnload = */ true, &s_hOpenGL32);
48 if (RT_FAILURE(rc))
49 s_hOpenGL32 = NULL;
50 }
51
52 typedef PROC (WINAPI *PFNWGLGETPROCADDRESS)(LPCSTR);
53 static PFNWGLGETPROCADDRESS s_wglGetProcAddress = NULL;
54 if (s_wglGetProcAddress == NULL)
55 {
56 if (s_hOpenGL32 != NULL)
57 {
58 rc = RTLdrGetSymbol(s_hOpenGL32, "wglGetProcAddress", (void **)&s_wglGetProcAddress);
59 if (RT_FAILURE(rc))
60 s_wglGetProcAddress = NULL;
61 }
62 }
63
64 if (s_wglGetProcAddress)
65 {
66 /* Khronos: [on failure] "some implementations will return other values. 1, 2, and 3 are used, as well as -1". */
67 PFNRT p = (PFNRT)s_wglGetProcAddress(pszSymbol);
68 if (RT_VALID_PTR(p))
69 return p;
70
71 /* Might be an exported symbol. */
72 rc = RTLdrGetSymbol(s_hOpenGL32, pszSymbol, (void **)&p);
73 if (RT_SUCCESS(rc))
74 return p;
75 }
76
77 return 0;
78}
79
80#elif defined(RT_OS_DARWIN)
81# include <dlfcn.h>
82# define OGLGETPROCADDRESS MyNSGLGetProcAddress
83/** Resolves an OpenGL symbol. */
84static void *MyNSGLGetProcAddress(const char *pszSymbol)
85{
86 /* Another copy in shaderapi.c. */
87 static void *s_pvImage = NULL;
88 if (s_pvImage == NULL)
89 s_pvImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
90 return s_pvImage ? dlsym(s_pvImage, pszSymbol) : NULL;
91}
92
93#else
94# define OGLGETPROCADDRESS MyGLXGetProcAddress
95static PFNRT MyGLXGetProcAddress(const char *pszSymbol)
96{
97 int rc;
98
99 static RTLDRMOD s_hGL = NULL;
100 if (s_hGL == NULL)
101 {
102 static const char s_szLibGL[] = "libGL.so.1";
103 rc = RTLdrLoadEx(s_szLibGL, &s_hGL, RTLDRLOAD_FLAGS_GLOBAL | RTLDRLOAD_FLAGS_NO_UNLOAD, NULL);
104 if (RT_FAILURE(rc))
105 {
106 LogRel(("VMSVGA3d: failed to load %s: %Rrc\n", s_szLibGL, rc));
107 s_hGL = NULL;
108 return NULL;
109 }
110 }
111
112 typedef PFNRT (* PFNGLXGETPROCADDRESS)(const GLubyte * procName);
113 static PFNGLXGETPROCADDRESS s_glXGetProcAddress = NULL;
114 if (s_glXGetProcAddress == NULL)
115 {
116 rc = RTLdrGetSymbol(s_hGL, "glXGetProcAddress", (void **)&s_glXGetProcAddress);
117 if (RT_FAILURE(rc))
118 {
119 LogRel(("VMSVGA3d: failed to get glXGetProcAddress: %Rrc\n", rc));
120 s_glXGetProcAddress = NULL;
121 return NULL;
122 }
123 }
124
125 PFNRT p = s_glXGetProcAddress((const GLubyte *)pszSymbol);
126 if (RT_VALID_PTR(p))
127 return p;
128
129 /* Might be an exported symbol. */
130 rc = RTLdrGetSymbol(s_hGL, pszSymbol, (void **)&p);
131 if (RT_SUCCESS(rc))
132 return p;
133
134 return NULL;
135}
136
137static PFNRT MyX11GetProcAddress(const char *pszSymbol)
138{
139 int rc;
140
141 static RTLDRMOD s_hX11 = NULL;
142 if (s_hX11 == NULL)
143 {
144 static const char s_szLibX11[] = "libX11.so.6";
145 rc = RTLdrLoadEx(s_szLibX11, &s_hX11, RTLDRLOAD_FLAGS_LOCAL | RTLDRLOAD_FLAGS_NO_UNLOAD, NULL);
146 if (RT_FAILURE(rc))
147 {
148 LogRel(("VMSVGA3d: failed to load %s: %Rrc\n", s_szLibX11, rc));
149 s_hX11 = NULL;
150 return NULL;
151 }
152 }
153
154 PFNRT p = NULL;
155 rc = RTLdrGetSymbol(s_hX11, pszSymbol, (void **)&p);
156 if (RT_SUCCESS(rc))
157 return p;
158
159 return NULL;
160}
161
162#define X11GETPROC_(ProcName) do { \
163 *(PFNRT *)&pfn_##ProcName = pfnRet = MyX11GetProcAddress(#ProcName); \
164 if (pfnRet) { /* likely */ } \
165 else \
166 { \
167 AssertLogRelMsg(pfnRet, ("%s missing\n", #ProcName)); \
168 return PDMDevHlpVMSetError(pDevIns, VERR_VGA_GL_SYMBOL_NOT_FOUND, RT_SRC_POS, \
169 "Missing libX11 symbol '%s'\n", #ProcName); \
170 } \
171} while(0)
172#endif
173
174#define GLGETPROC_(ProcName, NameSuffix) do { \
175 *(PFNRT *)&pfn_##ProcName = pfnRet = OGLGETPROCADDRESS(#ProcName NameSuffix); \
176 if (pfnRet) { /* likely */ } \
177 else \
178 { \
179 AssertLogRelMsg(pfnRet, ("%s missing\n", #ProcName NameSuffix)); \
180 return PDMDevHlpVMSetError(pDevIns, VERR_VGA_GL_SYMBOL_NOT_FOUND, RT_SRC_POS, \
181 "Missing OpenGL symbol '%s'\n", #ProcName NameSuffix); \
182 } \
183} while(0)
184
185int glLdrInit(PPDMDEVINS pDevIns)
186{
187 /** @todo r=bird: Perhaps make this template include file driven? See
188 * include/VBox/dbus.h, include/VBox/dbus-calls.h and iprt/runtime-loader.h for
189 * instance. Regardless, it would be would be nice if we could move up the
190 * RTLdrLoadSystem/dlopen bits and have separate error reporting for those,
191 * making use of VERR_VGA_GL_LOAD_FAILURE. I can look into that, but
192 * probably only after the release is out... */
193
194#ifdef RT_OS_WINDOWS
195 pfn_wglCreateContext = 0;
196 pfn_wglDeleteContext = 0;
197 pfn_wglMakeCurrent = 0;
198 pfn_wglShareLists = 0;
199#elif defined(RT_OS_LINUX)
200 pfn_XConfigureWindow = 0;
201 pfn_XCloseDisplay = 0;
202 pfn_XCreateColormap = 0;
203 pfn_XCreatePixmap = 0;
204 pfn_XCreateWindow = 0;
205 pfn_XDefaultRootWindow = 0;
206 pfn_XDestroyWindow = 0;
207 pfn_XFree = 0;
208 pfn_XFreePixmap = 0;
209 pfn_XInitThreads = 0;
210 pfn_XNextEvent = 0;
211 pfn_XOpenDisplay = 0;
212 pfn_XPending = 0;
213 pfn_XSetErrorHandler = 0;
214 pfn_XSync = 0;
215 pfn_XScreenNumberOfScreen = 0;
216 pfn_XMapWindow = 0;
217 pfn_XGetWindowAttributes = 0;
218 pfn_glXGetFBConfigAttrib = 0;
219 pfn_glXGetVisualFromFBConfig = 0;
220 pfn_glXQueryVersion = 0;
221 pfn_glXChooseFBConfig = 0;
222 pfn_glXChooseVisual = 0;
223 pfn_glXCreateContext = 0;
224 pfn_glXCreatePixmap = 0;
225 pfn_glXMakeCurrent = 0;
226 pfn_glXDestroyContext = 0;
227 pfn_glXDestroyPixmap = 0;
228#endif
229 pfn_glAlphaFunc = 0;
230 pfn_glBegin = 0;
231 pfn_glBindTexture = 0;
232 pfn_glBlendColor = 0;
233 pfn_glBlendEquation = 0;
234 pfn_glBlendFunc = 0;
235 pfn_glClear = 0;
236 pfn_glClearColor = 0;
237 pfn_glClearDepth = 0;
238 pfn_glClearStencil = 0;
239 pfn_glClientActiveTexture = 0;
240 pfn_glClipPlane = 0;
241 pfn_glColorMask = 0;
242 pfn_glColorPointer = 0;
243 pfn_glCullFace = 0;
244 pfn_glDeleteTextures = 0;
245 pfn_glDepthFunc = 0;
246 pfn_glDepthMask = 0;
247 pfn_glDepthRange = 0;
248 pfn_glDisable = 0;
249 pfn_glDisableClientState = 0;
250 pfn_glDrawArrays = 0;
251 pfn_glDrawElements = 0;
252 pfn_glEnable = 0;
253 pfn_glEnableClientState = 0;
254 pfn_glEnd = 0;
255 pfn_glFinish = 0;
256 pfn_glFlush = 0;
257 pfn_glFogf = 0;
258 pfn_glFogfv = 0;
259 pfn_glFogi = 0;
260 pfn_glFrontFace = 0;
261 pfn_glGenTextures = 0;
262 pfn_glGetBooleanv = 0;
263 pfn_glGetError = 0;
264 pfn_glGetFloatv = 0;
265 pfn_glGetIntegerv = 0;
266 pfn_glGetString = 0;
267 pfn_glGetTexImage = 0;
268 pfn_glLightModelfv = 0;
269 pfn_glLightf = 0;
270 pfn_glLightfv = 0;
271 pfn_glLineWidth = 0;
272 pfn_glLoadIdentity = 0;
273 pfn_glLoadMatrixf = 0;
274 pfn_glMaterialfv = 0;
275 pfn_glMatrixMode = 0;
276 pfn_glMultMatrixf = 0;
277 pfn_glNormalPointer = 0;
278 pfn_glOrtho = 0;
279 pfn_glPixelStorei = 0;
280 pfn_glPointSize = 0;
281 pfn_glPolygonMode = 0;
282 pfn_glPolygonOffset = 0;
283 pfn_glPopAttrib = 0;
284 pfn_glPopMatrix = 0;
285 pfn_glPushAttrib = 0;
286 pfn_glPushMatrix = 0;
287 pfn_glScissor = 0;
288 pfn_glShadeModel = 0;
289 pfn_glStencilFunc = 0;
290 pfn_glStencilMask = 0;
291 pfn_glStencilOp = 0;
292 pfn_glTexCoord2f = 0;
293 pfn_glTexCoordPointer = 0;
294 pfn_glTexImage2D = 0;
295 pfn_glTexParameterf = 0;
296 pfn_glTexParameterfv = 0;
297 pfn_glTexParameteri = 0;
298 pfn_glTexSubImage2D = 0;
299 pfn_glVertex2i = 0;
300 pfn_glVertexPointer = 0;
301 pfn_glViewport = 0;
302
303 PFNRT pfnRet;
304#ifdef RT_OS_WINDOWS
305 GLGETPROC_(wglCreateContext, "");
306 GLGETPROC_(wglDeleteContext, "");
307 GLGETPROC_(wglMakeCurrent, "");
308 GLGETPROC_(wglShareLists, "");
309#elif defined(RT_OS_LINUX)
310 X11GETPROC_(XConfigureWindow);
311 X11GETPROC_(XCloseDisplay);
312 X11GETPROC_(XCreateColormap);
313 X11GETPROC_(XCreatePixmap);
314 X11GETPROC_(XCreateWindow);
315 X11GETPROC_(XDefaultRootWindow);
316 X11GETPROC_(XDestroyWindow);
317 X11GETPROC_(XFree);
318 X11GETPROC_(XFreePixmap);
319 X11GETPROC_(XInitThreads);
320 X11GETPROC_(XNextEvent);
321 X11GETPROC_(XOpenDisplay);
322 X11GETPROC_(XPending);
323 X11GETPROC_(XSetErrorHandler);
324 X11GETPROC_(XSync);
325 X11GETPROC_(XScreenNumberOfScreen);
326 X11GETPROC_(XMapWindow);
327 X11GETPROC_(XGetWindowAttributes);
328 GLGETPROC_(glXGetFBConfigAttrib, "");
329 GLGETPROC_(glXGetVisualFromFBConfig, "");
330 GLGETPROC_(glXQueryVersion, "");
331 GLGETPROC_(glXChooseFBConfig, "");
332 GLGETPROC_(glXChooseVisual, "");
333 GLGETPROC_(glXCreateContext, "");
334 GLGETPROC_(glXCreatePixmap, "");
335 GLGETPROC_(glXMakeCurrent, "");
336 GLGETPROC_(glXDestroyContext, "");
337 GLGETPROC_(glXDestroyPixmap, "");
338#endif
339 GLGETPROC_(glAlphaFunc, "");
340 GLGETPROC_(glBegin, "");
341 GLGETPROC_(glBindTexture, "");
342 GLGETPROC_(glBlendFunc, "");
343 GLGETPROC_(glClear, "");
344 GLGETPROC_(glClearColor, "");
345 GLGETPROC_(glClearDepth, "");
346 GLGETPROC_(glClearStencil, "");
347 GLGETPROC_(glClipPlane, "");
348 GLGETPROC_(glColorMask, "");
349 GLGETPROC_(glColorPointer, "");
350 GLGETPROC_(glCullFace, "");
351 GLGETPROC_(glDeleteTextures, "");
352 GLGETPROC_(glDepthFunc, "");
353 GLGETPROC_(glDepthMask, "");
354 GLGETPROC_(glDepthRange, "");
355 GLGETPROC_(glDisable, "");
356 GLGETPROC_(glDisableClientState, "");
357 GLGETPROC_(glDrawArrays, "");
358 GLGETPROC_(glDrawElements, "");
359 GLGETPROC_(glEnable, "");
360 GLGETPROC_(glEnableClientState, "");
361 GLGETPROC_(glEnd, "");
362 GLGETPROC_(glFinish, "");
363 GLGETPROC_(glFlush, "");
364 GLGETPROC_(glFogf, "");
365 GLGETPROC_(glFogfv, "");
366 GLGETPROC_(glFogi, "");
367 GLGETPROC_(glFrontFace, "");
368 GLGETPROC_(glGenTextures, "");
369 GLGETPROC_(glGetBooleanv, "");
370 GLGETPROC_(glGetError, "");
371 GLGETPROC_(glGetFloatv, "");
372 GLGETPROC_(glGetIntegerv, "");
373 GLGETPROC_(glGetString, "");
374 GLGETPROC_(glGetTexImage, "");
375 GLGETPROC_(glLightModelfv, "");
376 GLGETPROC_(glLightf, "");
377 GLGETPROC_(glLightfv, "");
378 GLGETPROC_(glLineWidth, "");
379 GLGETPROC_(glLoadIdentity, "");
380 GLGETPROC_(glLoadMatrixf, "");
381 GLGETPROC_(glMaterialfv, "");
382 GLGETPROC_(glMatrixMode, "");
383 GLGETPROC_(glMultMatrixf, "");
384 GLGETPROC_(glNormalPointer, "");
385 GLGETPROC_(glOrtho, "");
386 GLGETPROC_(glPixelStorei, "");
387 GLGETPROC_(glPointSize, "");
388 GLGETPROC_(glPolygonMode, "");
389 GLGETPROC_(glPolygonOffset, "");
390 GLGETPROC_(glPopAttrib, "");
391 GLGETPROC_(glPopMatrix, "");
392 GLGETPROC_(glPushAttrib, "");
393 GLGETPROC_(glPushMatrix, "");
394 GLGETPROC_(glScissor, "");
395 GLGETPROC_(glShadeModel, "");
396 GLGETPROC_(glStencilFunc, "");
397 GLGETPROC_(glStencilMask, "");
398 GLGETPROC_(glStencilOp, "");
399 GLGETPROC_(glTexCoord2f, "");
400 GLGETPROC_(glTexCoordPointer, "");
401 GLGETPROC_(glTexImage2D, "");
402 GLGETPROC_(glTexParameterf, "");
403 GLGETPROC_(glTexParameterfv, "");
404 GLGETPROC_(glTexParameteri, "");
405 GLGETPROC_(glTexSubImage2D, "");
406 GLGETPROC_(glVertex2i, "");
407 GLGETPROC_(glVertexPointer, "");
408 GLGETPROC_(glViewport, "");
409
410#ifdef RT_OS_LINUX
411 XInitThreads();
412#endif
413 return VINF_SUCCESS;
414}
415
416PFNRT glLdrGetProcAddress(const char *pszSymbol)
417{
418 return OGLGETPROCADDRESS(pszSymbol);
419}
420
421int glLdrGetExtFunctions(PPDMDEVINS pDevIns)
422{
423 PFNRT pfnRet;
424 GLGETPROC_(glBlendColor, "");
425 GLGETPROC_(glBlendEquation, "");
426 GLGETPROC_(glClientActiveTexture, "");
427 return VINF_SUCCESS;
428}
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