VirtualBox

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

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

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-glLdr.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * DevVGA - VMWare SVGA device - 3D part, dynamic loading of GL function.
4 */
5
6/*
7 * Copyright (C) 2018-2019 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
127static PFNRT MyX11GetProcAddress(const char *pszSymbol)
128{
129 int rc;
130
131 static RTLDRMOD s_hX11 = NULL;
132 if (s_hX11 == NULL)
133 {
134 static const char s_szLibX11[] = "libX11.so.6";
135 rc = RTLdrLoadEx(s_szLibX11, &s_hX11, RTLDRLOAD_FLAGS_LOCAL | RTLDRLOAD_FLAGS_NO_UNLOAD, NULL);
136 if (RT_FAILURE(rc))
137 {
138 LogRel(("VMSVGA3d: failed to load %s: %Rrc\n", s_szLibX11, rc));
139 s_hX11 = NULL;
140 return NULL;
141 }
142 }
143
144 PFNRT p = NULL;
145 rc = RTLdrGetSymbol(s_hX11, pszSymbol, (void **)&p);
146 if (RT_SUCCESS(rc))
147 return p;
148
149 return NULL;
150}
151
152#define X11GETPROC_(ProcName) do { \
153 *(PFNRT *)&pfn_##ProcName = pfnRet = MyX11GetProcAddress(#ProcName); \
154 if (pfnRet) { /* likely */ } \
155 else \
156 { \
157 AssertLogRelMsg(pfnRet, ("%s missing\n", #ProcName)); \
158 return PDMDevHlpVMSetError(pDevIns, VERR_VGA_GL_SYMBOL_NOT_FOUND, RT_SRC_POS, \
159 "Missing libX11 symbol '%s'\n", #ProcName); \
160 } \
161} while(0)
162#endif
163
164#define GLGETPROC_(ProcName, NameSuffix) do { \
165 *(PFNRT *)&pfn_##ProcName = pfnRet = OGLGETPROCADDRESS(#ProcName NameSuffix); \
166 if (pfnRet) { /* likely */ } \
167 else \
168 { \
169 AssertLogRelMsg(pfnRet, ("%s missing\n", #ProcName NameSuffix)); \
170 return PDMDevHlpVMSetError(pDevIns, VERR_VGA_GL_SYMBOL_NOT_FOUND, RT_SRC_POS, \
171 "Missing OpenGL symbol '%s'\n", #ProcName NameSuffix); \
172 } \
173} while(0)
174
175int glLdrInit(PPDMDEVINS pDevIns)
176{
177 /** @todo r=bird: Perhaps make this template include file driven? See
178 * include/VBox/dbus.h, include/VBox/dbus-calls.h and iprt/runtime-loader.h for
179 * instance. Regardless, it would be would be nice if we could move up the
180 * RTLdrLoadSystem/dlopen bits and have separate error reporting for those,
181 * making use of VERR_VGA_GL_LOAD_FAILURE. I can look into that, but
182 * probably only after the release is out... */
183
184#ifdef RT_OS_WINDOWS
185 pfn_wglCreateContext = 0;
186 pfn_wglDeleteContext = 0;
187 pfn_wglMakeCurrent = 0;
188 pfn_wglShareLists = 0;
189#elif defined(RT_OS_LINUX)
190 pfn_XConfigureWindow = 0;
191 pfn_XCloseDisplay = 0;
192 pfn_XCreateColormap = 0;
193 pfn_XCreateWindow = 0;
194 pfn_XDefaultRootWindow = 0;
195 pfn_XDestroyWindow = 0;
196 pfn_XInitThreads = 0;
197 pfn_XNextEvent = 0;
198 pfn_XOpenDisplay = 0;
199 pfn_XPending = 0;
200 pfn_glXQueryVersion = 0;
201 pfn_glXChooseVisual = 0;
202 pfn_glXCreateContext = 0;
203 pfn_glXMakeCurrent = 0;
204 pfn_glXDestroyContext = 0;
205#endif
206 pfn_glAlphaFunc = 0;
207 pfn_glBindTexture = 0;
208 pfn_glBlendColor = 0;
209 pfn_glBlendEquation = 0;
210 pfn_glBlendFunc = 0;
211 pfn_glClear = 0;
212 pfn_glClearColor = 0;
213 pfn_glClearDepth = 0;
214 pfn_glClearStencil = 0;
215 pfn_glClientActiveTexture = 0;
216 pfn_glClipPlane = 0;
217 pfn_glColorMask = 0;
218 pfn_glColorPointer = 0;
219 pfn_glCullFace = 0;
220 pfn_glDeleteTextures = 0;
221 pfn_glDepthFunc = 0;
222 pfn_glDepthMask = 0;
223 pfn_glDepthRange = 0;
224 pfn_glDisable = 0;
225 pfn_glDisableClientState = 0;
226 pfn_glDrawArrays = 0;
227 pfn_glDrawElements = 0;
228 pfn_glEnable = 0;
229 pfn_glEnableClientState = 0;
230 pfn_glFogf = 0;
231 pfn_glFogfv = 0;
232 pfn_glFogi = 0;
233 pfn_glFrontFace = 0;
234 pfn_glGenTextures = 0;
235 pfn_glGetBooleanv = 0;
236 pfn_glGetError = 0;
237 pfn_glGetFloatv = 0;
238 pfn_glGetIntegerv = 0;
239 pfn_glGetString = 0;
240 pfn_glGetTexImage = 0;
241 pfn_glLightModelfv = 0;
242 pfn_glLightf = 0;
243 pfn_glLightfv = 0;
244 pfn_glLineWidth = 0;
245 pfn_glLoadIdentity = 0;
246 pfn_glLoadMatrixf = 0;
247 pfn_glMaterialfv = 0;
248 pfn_glMatrixMode = 0;
249 pfn_glMultMatrixf = 0;
250 pfn_glNormalPointer = 0;
251 pfn_glPixelStorei = 0;
252 pfn_glPointSize = 0;
253 pfn_glPolygonMode = 0;
254 pfn_glPolygonOffset = 0;
255 pfn_glPopAttrib = 0;
256 pfn_glPopMatrix = 0;
257 pfn_glPushAttrib = 0;
258 pfn_glPushMatrix = 0;
259 pfn_glScissor = 0;
260 pfn_glShadeModel = 0;
261 pfn_glStencilFunc = 0;
262 pfn_glStencilMask = 0;
263 pfn_glStencilOp = 0;
264 pfn_glTexCoordPointer = 0;
265 pfn_glTexImage2D = 0;
266 pfn_glTexParameterf = 0;
267 pfn_glTexParameterfv = 0;
268 pfn_glTexParameteri = 0;
269 pfn_glTexSubImage2D = 0;
270 pfn_glVertexPointer = 0;
271 pfn_glViewport = 0;
272
273 PFNRT pfnRet;
274#ifdef RT_OS_WINDOWS
275 GLGETPROC_(wglCreateContext, "");
276 GLGETPROC_(wglDeleteContext, "");
277 GLGETPROC_(wglMakeCurrent, "");
278 GLGETPROC_(wglShareLists, "");
279#elif defined(RT_OS_LINUX)
280 X11GETPROC_(XConfigureWindow);
281 X11GETPROC_(XCloseDisplay);
282 X11GETPROC_(XCreateColormap);
283 X11GETPROC_(XCreateWindow);
284 X11GETPROC_(XDefaultRootWindow);
285 X11GETPROC_(XDestroyWindow);
286 X11GETPROC_(XInitThreads);
287 X11GETPROC_(XNextEvent);
288 X11GETPROC_(XOpenDisplay);
289 X11GETPROC_(XPending);
290 GLGETPROC_(glXQueryVersion, "");
291 GLGETPROC_(glXChooseVisual, "");
292 GLGETPROC_(glXCreateContext, "");
293 GLGETPROC_(glXMakeCurrent, "");
294 GLGETPROC_(glXDestroyContext, "");
295#endif
296 GLGETPROC_(glAlphaFunc, "");
297 GLGETPROC_(glBindTexture, "");
298 GLGETPROC_(glBlendFunc, "");
299 GLGETPROC_(glClear, "");
300 GLGETPROC_(glClearColor, "");
301 GLGETPROC_(glClearDepth, "");
302 GLGETPROC_(glClearStencil, "");
303 GLGETPROC_(glClipPlane, "");
304 GLGETPROC_(glColorMask, "");
305 GLGETPROC_(glColorPointer, "");
306 GLGETPROC_(glCullFace, "");
307 GLGETPROC_(glDeleteTextures, "");
308 GLGETPROC_(glDepthFunc, "");
309 GLGETPROC_(glDepthMask, "");
310 GLGETPROC_(glDepthRange, "");
311 GLGETPROC_(glDisable, "");
312 GLGETPROC_(glDisableClientState, "");
313 GLGETPROC_(glDrawArrays, "");
314 GLGETPROC_(glDrawElements, "");
315 GLGETPROC_(glEnable, "");
316 GLGETPROC_(glEnableClientState, "");
317 GLGETPROC_(glFogf, "");
318 GLGETPROC_(glFogfv, "");
319 GLGETPROC_(glFogi, "");
320 GLGETPROC_(glFrontFace, "");
321 GLGETPROC_(glGenTextures, "");
322 GLGETPROC_(glGetBooleanv, "");
323 GLGETPROC_(glGetError, "");
324 GLGETPROC_(glGetFloatv, "");
325 GLGETPROC_(glGetIntegerv, "");
326 GLGETPROC_(glGetString, "");
327 GLGETPROC_(glGetTexImage, "");
328 GLGETPROC_(glLightModelfv, "");
329 GLGETPROC_(glLightf, "");
330 GLGETPROC_(glLightfv, "");
331 GLGETPROC_(glLineWidth, "");
332 GLGETPROC_(glLoadIdentity, "");
333 GLGETPROC_(glLoadMatrixf, "");
334 GLGETPROC_(glMaterialfv, "");
335 GLGETPROC_(glMatrixMode, "");
336 GLGETPROC_(glMultMatrixf, "");
337 GLGETPROC_(glNormalPointer, "");
338 GLGETPROC_(glPixelStorei, "");
339 GLGETPROC_(glPointSize, "");
340 GLGETPROC_(glPolygonMode, "");
341 GLGETPROC_(glPolygonOffset, "");
342 GLGETPROC_(glPopAttrib, "");
343 GLGETPROC_(glPopMatrix, "");
344 GLGETPROC_(glPushAttrib, "");
345 GLGETPROC_(glPushMatrix, "");
346 GLGETPROC_(glScissor, "");
347 GLGETPROC_(glShadeModel, "");
348 GLGETPROC_(glStencilFunc, "");
349 GLGETPROC_(glStencilMask, "");
350 GLGETPROC_(glStencilOp, "");
351 GLGETPROC_(glTexCoordPointer, "");
352 GLGETPROC_(glTexImage2D, "");
353 GLGETPROC_(glTexParameterf, "");
354 GLGETPROC_(glTexParameterfv, "");
355 GLGETPROC_(glTexParameteri, "");
356 GLGETPROC_(glTexSubImage2D, "");
357 GLGETPROC_(glVertexPointer, "");
358 GLGETPROC_(glViewport, "");
359
360#ifdef RT_OS_LINUX
361 XInitThreads();
362#endif
363 return VINF_SUCCESS;
364}
365
366PFNRT glLdrGetProcAddress(const char *pszSymbol)
367{
368 return OGLGETPROCADDRESS(pszSymbol);
369}
370
371int glLdrGetExtFunctions(PPDMDEVINS pDevIns)
372{
373 PFNRT pfnRet;
374 GLGETPROC_(glBlendColor, "");
375 GLGETPROC_(glBlendEquation, "");
376 GLGETPROC_(glClientActiveTexture, "");
377 return VINF_SUCCESS;
378}
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