VirtualBox

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

Last change on this file since 88904 was 85368, checked in by vboxsync, 4 years ago

Devices/Graphics,Main,include: Experimental graphics output. bugref:9695

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
Line 
1/* $Id: DevVGA-SVGA3d-glLdr.cpp 85368 2020-07-17 09:55:56Z vboxsync $ */
2/** @file
3 * DevVGA - VMWare SVGA device - 3D part, dynamic loading of GL function.
4 */
5
6/*
7 * Copyright (C) 2018-2020 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_XCreatePixmap = 0;
194 pfn_XCreateWindow = 0;
195 pfn_XDefaultRootWindow = 0;
196 pfn_XDestroyWindow = 0;
197 pfn_XFree = 0;
198 pfn_XFreePixmap = 0;
199 pfn_XInitThreads = 0;
200 pfn_XNextEvent = 0;
201 pfn_XOpenDisplay = 0;
202 pfn_XPending = 0;
203 pfn_XSetErrorHandler = 0;
204 pfn_XSync = 0;
205 pfn_XScreenNumberOfScreen = 0;
206 pfn_XMapWindow = 0;
207 pfn_XGetWindowAttributes = 0;
208 pfn_glXGetFBConfigAttrib = 0;
209 pfn_glXGetVisualFromFBConfig = 0;
210 pfn_glXQueryVersion = 0;
211 pfn_glXChooseFBConfig = 0;
212 pfn_glXChooseVisual = 0;
213 pfn_glXCreateContext = 0;
214 pfn_glXCreatePixmap = 0;
215 pfn_glXMakeCurrent = 0;
216 pfn_glXDestroyContext = 0;
217 pfn_glXDestroyPixmap = 0;
218#endif
219 pfn_glAlphaFunc = 0;
220 pfn_glBegin = 0;
221 pfn_glBindTexture = 0;
222 pfn_glBlendColor = 0;
223 pfn_glBlendEquation = 0;
224 pfn_glBlendFunc = 0;
225 pfn_glClear = 0;
226 pfn_glClearColor = 0;
227 pfn_glClearDepth = 0;
228 pfn_glClearStencil = 0;
229 pfn_glClientActiveTexture = 0;
230 pfn_glClipPlane = 0;
231 pfn_glColorMask = 0;
232 pfn_glColorPointer = 0;
233 pfn_glCullFace = 0;
234 pfn_glDeleteTextures = 0;
235 pfn_glDepthFunc = 0;
236 pfn_glDepthMask = 0;
237 pfn_glDepthRange = 0;
238 pfn_glDisable = 0;
239 pfn_glDisableClientState = 0;
240 pfn_glDrawArrays = 0;
241 pfn_glDrawElements = 0;
242 pfn_glEnable = 0;
243 pfn_glEnableClientState = 0;
244 pfn_glEnd = 0;
245 pfn_glFinish = 0;
246 pfn_glFlush = 0;
247 pfn_glFogf = 0;
248 pfn_glFogfv = 0;
249 pfn_glFogi = 0;
250 pfn_glFrontFace = 0;
251 pfn_glGenTextures = 0;
252 pfn_glGetBooleanv = 0;
253 pfn_glGetError = 0;
254 pfn_glGetFloatv = 0;
255 pfn_glGetIntegerv = 0;
256 pfn_glGetString = 0;
257 pfn_glGetTexImage = 0;
258 pfn_glLightModelfv = 0;
259 pfn_glLightf = 0;
260 pfn_glLightfv = 0;
261 pfn_glLineWidth = 0;
262 pfn_glLoadIdentity = 0;
263 pfn_glLoadMatrixf = 0;
264 pfn_glMaterialfv = 0;
265 pfn_glMatrixMode = 0;
266 pfn_glMultMatrixf = 0;
267 pfn_glNormalPointer = 0;
268 pfn_glOrtho = 0;
269 pfn_glPixelStorei = 0;
270 pfn_glPointSize = 0;
271 pfn_glPolygonMode = 0;
272 pfn_glPolygonOffset = 0;
273 pfn_glPopAttrib = 0;
274 pfn_glPopMatrix = 0;
275 pfn_glPushAttrib = 0;
276 pfn_glPushMatrix = 0;
277 pfn_glScissor = 0;
278 pfn_glShadeModel = 0;
279 pfn_glStencilFunc = 0;
280 pfn_glStencilMask = 0;
281 pfn_glStencilOp = 0;
282 pfn_glTexCoord2f = 0;
283 pfn_glTexCoordPointer = 0;
284 pfn_glTexImage2D = 0;
285 pfn_glTexParameterf = 0;
286 pfn_glTexParameterfv = 0;
287 pfn_glTexParameteri = 0;
288 pfn_glTexSubImage2D = 0;
289 pfn_glVertex2i = 0;
290 pfn_glVertexPointer = 0;
291 pfn_glViewport = 0;
292
293 PFNRT pfnRet;
294#ifdef RT_OS_WINDOWS
295 GLGETPROC_(wglCreateContext, "");
296 GLGETPROC_(wglDeleteContext, "");
297 GLGETPROC_(wglMakeCurrent, "");
298 GLGETPROC_(wglShareLists, "");
299#elif defined(RT_OS_LINUX)
300 X11GETPROC_(XConfigureWindow);
301 X11GETPROC_(XCloseDisplay);
302 X11GETPROC_(XCreateColormap);
303 X11GETPROC_(XCreatePixmap);
304 X11GETPROC_(XCreateWindow);
305 X11GETPROC_(XDefaultRootWindow);
306 X11GETPROC_(XDestroyWindow);
307 X11GETPROC_(XFree);
308 X11GETPROC_(XFreePixmap);
309 X11GETPROC_(XInitThreads);
310 X11GETPROC_(XNextEvent);
311 X11GETPROC_(XOpenDisplay);
312 X11GETPROC_(XPending);
313 X11GETPROC_(XSetErrorHandler);
314 X11GETPROC_(XSync);
315 X11GETPROC_(XScreenNumberOfScreen);
316 X11GETPROC_(XMapWindow);
317 X11GETPROC_(XGetWindowAttributes);
318 GLGETPROC_(glXGetFBConfigAttrib, "");
319 GLGETPROC_(glXGetVisualFromFBConfig, "");
320 GLGETPROC_(glXQueryVersion, "");
321 GLGETPROC_(glXChooseFBConfig, "");
322 GLGETPROC_(glXChooseVisual, "");
323 GLGETPROC_(glXCreateContext, "");
324 GLGETPROC_(glXCreatePixmap, "");
325 GLGETPROC_(glXMakeCurrent, "");
326 GLGETPROC_(glXDestroyContext, "");
327 GLGETPROC_(glXDestroyPixmap, "");
328#endif
329 GLGETPROC_(glAlphaFunc, "");
330 GLGETPROC_(glBegin, "");
331 GLGETPROC_(glBindTexture, "");
332 GLGETPROC_(glBlendFunc, "");
333 GLGETPROC_(glClear, "");
334 GLGETPROC_(glClearColor, "");
335 GLGETPROC_(glClearDepth, "");
336 GLGETPROC_(glClearStencil, "");
337 GLGETPROC_(glClipPlane, "");
338 GLGETPROC_(glColorMask, "");
339 GLGETPROC_(glColorPointer, "");
340 GLGETPROC_(glCullFace, "");
341 GLGETPROC_(glDeleteTextures, "");
342 GLGETPROC_(glDepthFunc, "");
343 GLGETPROC_(glDepthMask, "");
344 GLGETPROC_(glDepthRange, "");
345 GLGETPROC_(glDisable, "");
346 GLGETPROC_(glDisableClientState, "");
347 GLGETPROC_(glDrawArrays, "");
348 GLGETPROC_(glDrawElements, "");
349 GLGETPROC_(glEnable, "");
350 GLGETPROC_(glEnableClientState, "");
351 GLGETPROC_(glEnd, "");
352 GLGETPROC_(glFinish, "");
353 GLGETPROC_(glFlush, "");
354 GLGETPROC_(glFogf, "");
355 GLGETPROC_(glFogfv, "");
356 GLGETPROC_(glFogi, "");
357 GLGETPROC_(glFrontFace, "");
358 GLGETPROC_(glGenTextures, "");
359 GLGETPROC_(glGetBooleanv, "");
360 GLGETPROC_(glGetError, "");
361 GLGETPROC_(glGetFloatv, "");
362 GLGETPROC_(glGetIntegerv, "");
363 GLGETPROC_(glGetString, "");
364 GLGETPROC_(glGetTexImage, "");
365 GLGETPROC_(glLightModelfv, "");
366 GLGETPROC_(glLightf, "");
367 GLGETPROC_(glLightfv, "");
368 GLGETPROC_(glLineWidth, "");
369 GLGETPROC_(glLoadIdentity, "");
370 GLGETPROC_(glLoadMatrixf, "");
371 GLGETPROC_(glMaterialfv, "");
372 GLGETPROC_(glMatrixMode, "");
373 GLGETPROC_(glMultMatrixf, "");
374 GLGETPROC_(glNormalPointer, "");
375 GLGETPROC_(glOrtho, "");
376 GLGETPROC_(glPixelStorei, "");
377 GLGETPROC_(glPointSize, "");
378 GLGETPROC_(glPolygonMode, "");
379 GLGETPROC_(glPolygonOffset, "");
380 GLGETPROC_(glPopAttrib, "");
381 GLGETPROC_(glPopMatrix, "");
382 GLGETPROC_(glPushAttrib, "");
383 GLGETPROC_(glPushMatrix, "");
384 GLGETPROC_(glScissor, "");
385 GLGETPROC_(glShadeModel, "");
386 GLGETPROC_(glStencilFunc, "");
387 GLGETPROC_(glStencilMask, "");
388 GLGETPROC_(glStencilOp, "");
389 GLGETPROC_(glTexCoord2f, "");
390 GLGETPROC_(glTexCoordPointer, "");
391 GLGETPROC_(glTexImage2D, "");
392 GLGETPROC_(glTexParameterf, "");
393 GLGETPROC_(glTexParameterfv, "");
394 GLGETPROC_(glTexParameteri, "");
395 GLGETPROC_(glTexSubImage2D, "");
396 GLGETPROC_(glVertex2i, "");
397 GLGETPROC_(glVertexPointer, "");
398 GLGETPROC_(glViewport, "");
399
400#ifdef RT_OS_LINUX
401 XInitThreads();
402#endif
403 return VINF_SUCCESS;
404}
405
406PFNRT glLdrGetProcAddress(const char *pszSymbol)
407{
408 return OGLGETPROCADDRESS(pszSymbol);
409}
410
411int glLdrGetExtFunctions(PPDMDEVINS pDevIns)
412{
413 PFNRT pfnRet;
414 GLGETPROC_(glBlendColor, "");
415 GLGETPROC_(glBlendEquation, "");
416 GLGETPROC_(glClientActiveTexture, "");
417 return VINF_SUCCESS;
418}
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